ColorBlendAttrib: support separate alpha mode and dual-src blend. bam 6.42

This commit is contained in:
rdb 2016-04-08 13:41:13 +02:00
parent e73a89705b
commit f0cd1ce315
13 changed files with 382 additions and 79 deletions

View File

@ -684,6 +684,15 @@ get_max_color_targets() const {
return _max_color_targets;
}
/**
* Returns true if dual source (incoming1_color and incoming1_alpha) blend
* operands are supported by this GSG.
*/
INLINE bool GraphicsStateGuardian::
get_supports_dual_source_blending() const {
return _supports_dual_source_blending;
}
/**
* Deprecated. Use get_max_color_targets() instead, which returns the exact
* same value.

View File

@ -246,6 +246,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
// Assume a maximum of 1 render target in absence of MRT.
_max_color_targets = 1;
_supports_dual_source_blending = false;
_supported_geom_rendering = 0;

View File

@ -172,6 +172,7 @@ PUBLISHED:
INLINE int get_max_color_targets() const;
INLINE int get_maximum_simultaneous_render_targets() const;
INLINE bool get_supports_dual_source_blending() const;
MAKE_PROPERTY(max_vertices_per_array, get_max_vertices_per_array);
MAKE_PROPERTY(max_vertices_per_primitive, get_max_vertices_per_primitive);
@ -217,6 +218,7 @@ PUBLISHED:
MAKE_PROPERTY(supports_timer_query, get_supports_timer_query);
MAKE_PROPERTY(timer_queries_active, get_timer_queries_active);
MAKE_PROPERTY(max_color_targets, get_max_color_targets);
MAKE_PROPERTY(supports_dual_source_blending, get_supports_dual_source_blending);
INLINE ShaderModel get_shader_model() const;
INLINE void set_shader_model(ShaderModel shader_model);
@ -609,6 +611,7 @@ protected:
bool _supports_indirect_draw;
int _max_color_targets;
bool _supports_dual_source_blending;
int _supported_geom_rendering;
bool _color_scale_via_lighting;

View File

@ -3766,43 +3766,24 @@ do_issue_blending() {
}
}
const ColorBlendAttrib *target_color_blend = DCAST(ColorBlendAttrib, _target_rs->get_attrib_def(ColorBlendAttrib::get_class_slot()));
CPT(ColorBlendAttrib) color_blend = target_color_blend;
ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
const ColorBlendAttrib *color_blend;
_target_rs->get_attrib_def(color_blend);
ColorBlendAttrib::Mode color_blend_mode = color_blend->get_mode();
const TransparencyAttrib *target_transparency = DCAST(TransparencyAttrib, _target_rs->get_attrib_def(TransparencyAttrib::get_class_slot()));
const TransparencyAttrib *target_transparency;
_target_rs->get_attrib_def(target_transparency);
TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode();
// Is there a color blend set?
if (color_blend_mode != ColorBlendAttrib::M_none) {
set_render_state(D3DRS_ALPHABLENDENABLE, TRUE);
switch (color_blend_mode) {
case ColorBlendAttrib::M_add:
set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
break;
case ColorBlendAttrib::M_subtract:
set_render_state(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
break;
case ColorBlendAttrib::M_inv_subtract:
set_render_state(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT);
break;
case ColorBlendAttrib::M_min:
set_render_state(D3DRS_BLENDOP, D3DBLENDOP_MIN);
break;
case ColorBlendAttrib::M_max:
set_render_state(D3DRS_BLENDOP, D3DBLENDOP_MAX);
break;
}
set_render_state(D3DRS_SRCBLEND,
get_blend_func(color_blend->get_operand_a()));
set_render_state(D3DRS_DESTBLEND,
get_blend_func(color_blend->get_operand_b()));
set_render_state(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
set_render_state(D3DRS_BLENDOP, get_blend_mode(color_blend_mode));
set_render_state(D3DRS_BLENDOPALPHA, get_blend_mode(color_blend->get_alpha_mode()));
set_render_state(D3DRS_SRCBLEND, get_blend_func(color_blend->get_operand_a()));
set_render_state(D3DRS_DESTBLEND, get_blend_func(color_blend->get_operand_b()));
set_render_state(D3DRS_SRCBLENDALPHA, get_blend_func(color_blend->get_alpha_operand_a()));
set_render_state(D3DRS_DESTBLENDALPHA, get_blend_func(color_blend->get_alpha_operand_b()));
return;
}
@ -3817,6 +3798,7 @@ do_issue_blending() {
case TransparencyAttrib::M_multisample_mask:
case TransparencyAttrib::M_dual:
set_render_state(D3DRS_ALPHABLENDENABLE, TRUE);
set_render_state(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
set_render_state(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
set_render_state(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
@ -3824,6 +3806,7 @@ do_issue_blending() {
case TransparencyAttrib::M_premultiplied_alpha:
set_render_state(D3DRS_ALPHABLENDENABLE, TRUE);
set_render_state(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
set_render_state(D3DRS_SRCBLEND, D3DBLEND_ONE);
set_render_state(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
@ -4052,6 +4035,33 @@ get_light_color(Light *light) const {
return *(D3DCOLORVALUE *)cf.get_data();
}
/**
* Maps from ColorBlendAttrib::Mode to D3DBLENDOP vaule.
*/
D3DBLENDOP DXGraphicsStateGuardian9::
get_blend_mode(ColorBlendAttrib::Mode mode) {
switch (mode) {
case ColorBlendAttrib::M_add:
return D3DBLENDOP_ADD;
case ColorBlendAttrib::M_subtract:
return D3DBLENDOP_SUBTRACT;
case ColorBlendAttrib::M_inv_subtract:
return D3DBLENDOP_REVSUBTRACT;
case ColorBlendAttrib::M_min:
return D3DBLENDOP_MIN;
case ColorBlendAttrib::M_max:
return D3DBLENDOP_MAX;
}
dxgsg9_cat.error()
<< "Unknown color blend mode " << (int)mode << endl;
return D3DBLENDOP_ADD;
}
/**
* Maps from ColorBlendAttrib::Operand to D3DBLEND value.
*/
@ -4106,6 +4116,21 @@ get_blend_func(ColorBlendAttrib::Operand operand) {
case ColorBlendAttrib::O_incoming_color_saturate:
return D3DBLEND_SRCALPHASAT;
case ColorBlendAttrib::O_incoming1_color:
return D3DBLEND_SRCCOLOR2;
case ColorBlendAttrib::O_one_minus_incoming1_color:
return D3DBLEND_INVSRCCOLOR2;
case ColorBlendAttrib::O_incoming1_alpha:
// Not supported by DX.
return D3DBLEND_SRCCOLOR2;
case ColorBlendAttrib::O_one_minus_incoming1_alpha:
// Not supported by DX.
return D3DBLEND_INVSRCCOLOR2;
}
dxgsg9_cat.error()

View File

@ -217,6 +217,7 @@ protected:
const D3DCOLORVALUE &get_light_color(Light *light) const;
INLINE static D3DTRANSFORMSTATETYPE get_tex_mat_sym(int stage_index);
static D3DBLENDOP get_blend_mode(ColorBlendAttrib::Mode mode);
static D3DBLEND get_blend_func(ColorBlendAttrib::Operand operand);
void report_texmgr_stats();

View File

@ -123,6 +123,10 @@ typedef char GLchar;
#define GL_MAX_DRAW_BUFFERS GL_MAX_DRAW_BUFFERS_NV
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE
#define GL_SRC1_COLOR GL_SRC1_COLOR_EXT
#define GL_ONE_MINUS_SRC1_COLOR GL_ONE_MINUS_SRC1_COLOR_EXT
#define GL_SRC1_ALPHA GL_SRC1_ALPHA_EXT
#define GL_ONE_MINUS_SRC1_ALPHA GL_ONE_MINUS_SRC1_ALPHA_EXT
// For GLES 3 compat - need a better solution for this
#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x1

View File

@ -430,6 +430,17 @@ typedef struct __GLsync *GLsync;
* EXT extension tokens
*------------------------------------------------------------------------*/
#ifndef GL_EXT_blend_func_extended
#define GL_EXT_blend_func_extended 1
#define GL_SRC1_COLOR_EXT 0x88F9
#define GL_SRC1_ALPHA_EXT 0x8589
#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA
#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB
#define GL_SRC_ALPHA_SATURATE_EXT 0x0308
#define GL_LOCATION_INDEX_EXT 0x930F
#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC
#endif
/* GL_EXT_blend_minmax */
#ifndef GL_EXT_blend_minmax
#define GL_MIN_EXT 0x8007

View File

@ -129,16 +129,23 @@ null_glActiveTexture(GLenum gl_texture_stage) {
#ifdef OPENGLES_2
#define _glBlendEquation glBlendEquation
#define _glBlendEquationSeparate glBlendEquationSeparate
#define _glBlendFuncSeparate glBlendFuncSeparate
#define _glBlendColor glBlendColor
#else
static void APIENTRY
null_glBlendEquation(GLenum) {
}
#endif
static void APIENTRY
null_glBlendFuncSeparate(GLenum src, GLenum dest, GLenum, GLenum) {
glBlendFunc(src, dest);
}
static void APIENTRY
null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
}
#endif
#ifndef OPENGLES_1
// We have a default shader that will be applied when there isn't any shader
@ -2284,29 +2291,115 @@ reset() {
}
#endif
// In OpenGL ES 2.x, this is supported in the core.
#ifndef OPENGLES_2
_glBlendEquation = NULL;
bool supports_blend_equation = false;
if (is_at_least_gl_version(1, 2)) {
supports_blend_equation = true;
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
get_extension_func("glBlendEquation");
} else if (has_extension("GL_OES_blend_subtract")) {
supports_blend_equation = true;
#ifdef OPENGLES_1
// In OpenGL ES 1, blending is supported via extensions.
if (has_extension("GL_OES_blend_subtract")) {
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
get_extension_func("glBlendEquationOES");
if (_glBlendEquation == NULL) {
_glBlendEquation = null_glBlendEquation;
GLCAT.warning()
<< "BlendEquationOES advertised as supported by OpenGL ES runtime, but "
"could not get pointer to extension function.\n";
}
} else {
_glBlendEquation = null_glBlendEquation;
}
if (has_extension("GL_OES_blend_equation_separate")) {
_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEOESPROC)
get_extension_func("glBlendEquationSeparateOES");
if (_glBlendEquation == NULL) {
_supports_blend_equation_separate = false;
GLCAT.warning()
<< "BlendEquationSeparateOES advertised as supported by OpenGL ES "
"runtime, but could not get pointer to extension function.\n";
} else {
_supports_blend_equation_separate = true;
}
} else {
_supports_blend_equation_separate = false;
_glBlendEquationSeparate = NULL;
}
if (has_extension("GL_OES_blend_func_separate")) {
_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEOESPROC)
get_extension_func("glBlendFuncSeparateOES");
if (_glBlendFuncSeparate == NULL) {
_glBlendFuncSeparate = null_glBlendFuncSeparate;
GLCAT.warning()
<< "BlendFuncSeparateOES advertised as supported by OpenGL ES runtime, but "
"could not get pointer to extension function.\n";
}
} else {
_glBlendFuncSeparate = null_glBlendFuncSeparate;
}
#elif defined(OPENGLES)
// In OpenGL ES 2.x and above, this is supported in the core.
_supports_blend_equation_separate = false;
#else
if (is_at_least_gl_version(1, 2)) {
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
get_extension_func("glBlendEquation");
} else if (has_extension("GL_EXT_blend_minmax")) {
supports_blend_equation = true;
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
get_extension_func("glBlendEquationEXT");
} else {
_glBlendEquation = null_glBlendEquation;
}
if (supports_blend_equation && _glBlendEquation == NULL) {
GLCAT.warning()
<< "BlendEquation advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
}
if (_glBlendEquation == NULL) {
_glBlendEquation = null_glBlendEquation;
GLCAT.warning()
<< "BlendEquation advertised as supported by OpenGL runtime, but could "
"not get pointer to extension function.\n";
}
if (is_at_least_gl_version(2, 0)) {
_supports_blend_equation_separate = true;
_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)
get_extension_func("glBlendEquationSeparate");
} else if (has_extension("GL_EXT_blend_equation_separate")) {
_supports_blend_equation_separate = true;
_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)
get_extension_func("glBlendEquationSeparateEXT");
} else {
_supports_blend_equation_separate = false;
_glBlendEquationSeparate = NULL;
}
if (_supports_blend_equation_separate && _glBlendEquationSeparate == NULL) {
_supports_blend_equation_separate = false;
GLCAT.warning()
<< "BlendEquationSeparate advertised as supported by OpenGL runtime, "
"but could not get pointer to extension function.\n";
}
if (is_at_least_gl_version(1, 4)) {
_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)
get_extension_func("glBlendFuncSeparate");
} else if (has_extension("GL_EXT_blend_func_separate")) {
_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEEXTPROC)
get_extension_func("glBlendFuncSeparateEXT");
} else {
_glBlendFuncSeparate = null_glBlendFuncSeparate;
}
if (_glBlendFuncSeparate == NULL) {
_glBlendFuncSeparate = null_glBlendFuncSeparate;
GLCAT.warning()
<< "BlendFuncSeparate advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
}
#endif
@ -2332,6 +2425,15 @@ reset() {
}
#endif
#ifdef OPENGLES_1
// OpenGL ES 1 doesn't support dual-source blending.
#elif defined(OPENGLES)
_supports_dual_source_blending = has_extension("GL_EXT_blend_func_extended");
#else
_supports_dual_source_blending =
is_at_least_gl_version(3, 3) || has_extension("GL_ARB_blend_func_extended");
#endif
#ifdef OPENGLES
_edge_clamp = GL_CLAMP_TO_EDGE;
#else
@ -6902,6 +7004,7 @@ do_issue_blending() {
_target_rs->get_attrib_def(target_color_blend);
CPT(ColorBlendAttrib) color_blend = target_color_blend;
ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
ColorBlendAttrib::Mode alpha_blend_mode = target_color_blend->get_alpha_mode();
const TransparencyAttrib *target_transparency;
_target_rs->get_attrib_def(target_transparency);
@ -6914,9 +7017,17 @@ do_issue_blending() {
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(true);
_glBlendEquation(get_blend_equation_type(color_blend_mode));
glBlendFunc(get_blend_func(color_blend->get_operand_a()),
get_blend_func(color_blend->get_operand_b()));
if (_supports_blend_equation_separate) {
_glBlendEquationSeparate(get_blend_equation_type(color_blend_mode),
get_blend_equation_type(alpha_blend_mode));
} else {
_glBlendEquation(get_blend_equation_type(color_blend_mode));
}
_glBlendFuncSeparate(get_blend_func(color_blend->get_operand_a()),
get_blend_func(color_blend->get_operand_b()),
get_blend_func(color_blend->get_alpha_operand_a()),
get_blend_func(color_blend->get_alpha_operand_b()));
#ifndef OPENGLES_1
LColor c;
@ -6931,9 +7042,17 @@ do_issue_blending() {
#endif
if (GLCAT.is_spam()) {
GLCAT.spam() << "glBlendEquation(" << color_blend_mode << ")\n";
GLCAT.spam() << "glBlendFunc(" << color_blend->get_operand_a()
<< color_blend->get_operand_b() << ")\n";
if (_supports_blend_equation_separate) {
GLCAT.spam() << "glBlendEquationSeparate(" << color_blend_mode << ", "
<< alpha_blend_mode << ")\n";
} else {
GLCAT.spam() << "glBlendEquation(" << color_blend_mode << ")\n";
}
GLCAT.spam() << "glBlendFuncSeparate("
<< color_blend->get_operand_a() << ", "
<< color_blend->get_operand_b() << ", "
<< color_blend->get_alpha_operand_a() << ", "
<< color_blend->get_alpha_operand_b() << ")\n";
#ifndef OPENGLES_1
GLCAT.spam() << "glBlendColor(" << c << ")\n";
#endif
@ -9304,6 +9423,13 @@ get_blend_func(ColorBlendAttrib::Operand operand) {
case ColorBlendAttrib::O_one_minus_constant_alpha:
case ColorBlendAttrib::O_one_minus_alpha_scale:
break;
// No dual-source blending, either.
case ColorBlendAttrib::O_incoming1_color:
case ColorBlendAttrib::O_one_minus_incoming1_color:
case ColorBlendAttrib::O_incoming1_alpha:
case ColorBlendAttrib::O_one_minus_incoming1_alpha:
break;
#else
case ColorBlendAttrib::O_constant_color:
case ColorBlendAttrib::O_color_scale:
@ -9320,6 +9446,18 @@ get_blend_func(ColorBlendAttrib::Operand operand) {
case ColorBlendAttrib::O_one_minus_constant_alpha:
case ColorBlendAttrib::O_one_minus_alpha_scale:
return GL_ONE_MINUS_CONSTANT_ALPHA;
case ColorBlendAttrib::O_incoming1_color:
return GL_SRC1_COLOR;
case ColorBlendAttrib::O_one_minus_incoming1_color:
return GL_ONE_MINUS_SRC1_COLOR;
case ColorBlendAttrib::O_incoming1_alpha:
return GL_SRC1_ALPHA;
case ColorBlendAttrib::O_one_minus_incoming1_alpha:
return GL_ONE_MINUS_SRC1_ALPHA;
#endif
case ColorBlendAttrib::O_incoming_color_saturate:

View File

@ -141,6 +141,8 @@ typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, G
typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
#ifndef OPENGLES_1
// GLSL shader functions
@ -817,8 +819,12 @@ public:
PFNGLBUFFERSTORAGEPROC _glBufferStorage;
#endif
bool _supports_blend_equation_separate;
#ifndef OPENGLES_2
// OpenGL ES 2+ has these in the core.
PFNGLBLENDEQUATIONPROC _glBlendEquation;
PFNGLBLENDEQUATIONSEPARATEPROC _glBlendEquationSeparate;
PFNGLBLENDFUNCSEPARATEPROC _glBlendFuncSeparate;
#endif
#ifndef OPENGLES
PFNGLBLENDCOLORPROC _glBlendColor;

View File

@ -19,6 +19,9 @@ ColorBlendAttrib() :
_mode(M_none),
_a(O_one),
_b(O_one),
_alpha_mode(M_none),
_alpha_a(O_one),
_alpha_b(O_one),
_color(LColor::zero()),
_involves_constant_color(false),
_involves_color_scale(false)
@ -31,18 +34,29 @@ ColorBlendAttrib() :
INLINE ColorBlendAttrib::
ColorBlendAttrib(ColorBlendAttrib::Mode mode,
ColorBlendAttrib::Operand a, ColorBlendAttrib::Operand b,
ColorBlendAttrib::Mode alpha_mode,
ColorBlendAttrib::Operand alpha_a, ColorBlendAttrib::Operand alpha_b,
const LColor &color) :
_mode(mode),
_a(a),
_b(b),
_alpha_mode(alpha_mode),
_alpha_a(alpha_a),
_alpha_b(alpha_b),
_color(color),
_involves_constant_color(involves_constant_color(a) || involves_constant_color(b)),
_involves_color_scale(involves_color_scale(a) || involves_color_scale(b))
_involves_constant_color(involves_constant_color(a) ||
involves_constant_color(b) ||
involves_constant_color(alpha_a) ||
involves_constant_color(alpha_b)),
_involves_color_scale(involves_color_scale(a) ||
involves_color_scale(b) ||
involves_color_scale(alpha_a) ||
involves_color_scale(alpha_b))
{
}
/**
* Returns the colorBlend mode.
* Returns the blending mode for the RGB channels.
*/
INLINE ColorBlendAttrib::Mode ColorBlendAttrib::
get_mode() const {
@ -50,7 +64,7 @@ get_mode() const {
}
/**
* Returns the multiplier for the first component.
* Returns the RGB multiplier for the first component.
*/
INLINE ColorBlendAttrib::Operand ColorBlendAttrib::
get_operand_a() const {
@ -58,13 +72,37 @@ get_operand_a() const {
}
/**
* Returns the multiplier for the second component.
* Returns the RGB multiplier for the second component.
*/
INLINE ColorBlendAttrib::Operand ColorBlendAttrib::
get_operand_b() const {
return _b;
}
/**
* Returns the blending mode for the alpha channel.
*/
INLINE ColorBlendAttrib::Mode ColorBlendAttrib::
get_alpha_mode() const {
return _alpha_mode;
}
/**
* Returns the alpha multiplier for the first component.
*/
INLINE ColorBlendAttrib::Operand ColorBlendAttrib::
get_alpha_operand_a() const {
return _alpha_a;
}
/**
* Returns the alpha multiplier for the second component.
*/
INLINE ColorBlendAttrib::Operand ColorBlendAttrib::
get_alpha_operand_b() const {
return _alpha_b;
}
/**
* Returns the constant color associated with the attrib.
*/
@ -114,14 +152,5 @@ involves_constant_color(ColorBlendAttrib::Operand operand) {
*/
INLINE bool ColorBlendAttrib::
involves_color_scale(ColorBlendAttrib::Operand operand) {
switch (operand) {
case O_color_scale:
case O_one_minus_color_scale:
case O_alpha_scale:
case O_one_minus_alpha_scale:
return true;
default:
return false;
}
return (operand >= O_color_scale);
}

View File

@ -39,19 +39,38 @@ make_off() {
CPT(RenderAttrib) ColorBlendAttrib::
make(ColorBlendAttrib::Mode mode) {
ColorBlendAttrib *attrib = new ColorBlendAttrib(mode, O_one, O_one,
mode, O_one, O_one,
LColor::zero());
return return_new(attrib);
}
/**
* Constructs a new ColorBlendAttrib object that enables special-effect
* blending. This supercedes transparency.
* blending. This supercedes transparency. The given mode and operands are
* used for both the RGB and alpha channels.
*/
CPT(RenderAttrib) ColorBlendAttrib::
make(ColorBlendAttrib::Mode mode,
ColorBlendAttrib::Operand a, ColorBlendAttrib::Operand b,
const LColor &color) {
ColorBlendAttrib *attrib = new ColorBlendAttrib(mode, a, b, color);
ColorBlendAttrib *attrib = new ColorBlendAttrib(mode, a, b, mode, a, b, color);
return return_new(attrib);
}
/**
* Constructs a new ColorBlendAttrib object that enables special-effect
* blending. This supercedes transparency. This form is used to specify
* separate blending parameters for the RGB and alpha channels.
*/
CPT(RenderAttrib) ColorBlendAttrib::
make(ColorBlendAttrib::Mode mode,
ColorBlendAttrib::Operand a, ColorBlendAttrib::Operand b,
ColorBlendAttrib::Mode alpha_mode,
ColorBlendAttrib::Operand alpha_a, ColorBlendAttrib::Operand alpha_b,
const LColor &color) {
ColorBlendAttrib *attrib = new ColorBlendAttrib(mode, a, b,
alpha_mode, alpha_a, alpha_b,
color);
return return_new(attrib);
}
@ -187,10 +206,34 @@ fillin(DatagramIterator &scan, BamReader *manager) {
_mode = (Mode)scan.get_uint8();
_a = (Operand)scan.get_uint8();
_b = (Operand)scan.get_uint8();
if (manager->get_file_minor_ver() >= 42) {
_alpha_mode = (Mode)scan.get_uint8();
_alpha_a = (Operand)scan.get_uint8();
_alpha_b = (Operand)scan.get_uint8();
} else {
// Before bam 6.42, these were shifted by four.
if (_a >= O_incoming1_color) {
_a = (Operand)(_a + 4);
}
if (_b >= O_incoming1_color) {
_b = (Operand)(_b + 4);
}
// And there was only one set of blend constants for both RGB and alpha.
_alpha_mode = _mode;
_alpha_a = _a;
_alpha_b = _b;
}
_color.read_datagram(scan);
_involves_constant_color = involves_constant_color(_a) || involves_constant_color(_b);
_involves_color_scale = involves_color_scale(_a) || involves_color_scale(_b);
_involves_constant_color =
involves_constant_color(_a) || involves_constant_color(_alpha_a) ||
involves_constant_color(_b) || involves_constant_color(_alpha_b);
_involves_color_scale =
involves_color_scale(_a) || involves_color_scale(_alpha_a) ||
involves_color_scale(_b) || involves_color_scale(_alpha_b);
}
/**
@ -234,7 +277,7 @@ operator << (ostream &out, ColorBlendAttrib::Operand operand) {
return out << "one";
case ColorBlendAttrib::O_incoming_color:
return out << "incomfing_color";
return out << "incoming_color";
case ColorBlendAttrib::O_one_minus_incoming_color:
return out << "one_minus_incoming_color";
@ -283,6 +326,18 @@ operator << (ostream &out, ColorBlendAttrib::Operand operand) {
case ColorBlendAttrib::O_one_minus_alpha_scale:
return out << "one_minus_alpha_scale";
case ColorBlendAttrib::O_incoming1_color:
return out << "incoming1_color";
case ColorBlendAttrib::O_one_minus_incoming1_color:
return out << "one_minus_incoming1_color";
case ColorBlendAttrib::O_incoming1_alpha:
return out << "incoming1_alpha";
case ColorBlendAttrib::O_one_minus_incoming1_alpha:
return out << "one_minus_incoming1_alpha";
}
return out << "**invalid ColorBlendAttrib::Operand(" << (int)operand << ")**";

View File

@ -52,11 +52,20 @@ PUBLISHED:
O_one_minus_constant_alpha,
O_incoming_color_saturate, // valid only for operand a
// If you set either of the operands to any of the below, the blend color
// is taken from the current ColorScaleAttrib. This also inhibits the
// normal behavior of the ColorScaleAttrib; it no longer directly scales
// the vertex colors, on the assumption that you will instead take care of
// the scale here, in the blend mode.
// The following are used for dual-source blending, where the fragment
// shader outputs a second color that will be used for blending.
O_incoming1_color,
O_one_minus_incoming1_color,
O_incoming1_alpha,
O_one_minus_incoming1_alpha,
// If you set any of the operands to any of the below, the blend color is
// taken from the current ColorScaleAttrib. This also inhibits the normal
// behavior of the ColorScaleAttrib; it no longer directly scales the
// vertex colors, on the assumption that you will instead take care of the
// scale here, in the blend mode.
//
// These modes are being considered for deprecation.
O_color_scale,
O_one_minus_color_scale,
O_alpha_scale,
@ -66,6 +75,7 @@ PUBLISHED:
private:
INLINE ColorBlendAttrib();
INLINE ColorBlendAttrib(Mode mode, Operand a, Operand b,
Mode alpha_mode, Operand alpha_a, Operand alpha_b,
const LColor &color);
PUBLISHED:
@ -73,11 +83,19 @@ PUBLISHED:
static CPT(RenderAttrib) make(Mode mode);
static CPT(RenderAttrib) make(Mode mode, Operand a, Operand b,
const LColor &color = LColor::zero());
static CPT(RenderAttrib) make(Mode rgb_mode, Operand rgb_a, Operand rgb_b,
Mode alpha_mode, Operand alpha_a, Operand alpha_b,
const LColor &color = LColor::zero());
static CPT(RenderAttrib) make_default();
INLINE Mode get_mode() const;
INLINE Operand get_operand_a() const;
INLINE Operand get_operand_b() const;
INLINE Mode get_alpha_mode() const;
INLINE Operand get_alpha_operand_a() const;
INLINE Operand get_alpha_operand_b() const;
INLINE LColor get_color() const;
INLINE bool involves_constant_color() const;
@ -97,6 +115,8 @@ protected:
private:
Mode _mode;
Operand _a, _b;
Mode _alpha_mode;
Operand _alpha_a, _alpha_b;
LColor _color;
bool _involves_constant_color;
bool _involves_color_scale;

View File

@ -32,7 +32,7 @@ static const unsigned short _bam_major_ver = 6;
// Bumped to major version 6 on 2006-02-11 to factor out PandaNode::CData.
static const unsigned short _bam_first_minor_ver = 14;
static const unsigned short _bam_minor_ver = 41;
static const unsigned short _bam_minor_ver = 42;
// Bumped to minor version 14 on 2007-12-19 to change default ColorAttrib.
// Bumped to minor version 15 on 2008-04-09 to add TextureAttrib::_implicit_sort.
// Bumped to minor version 16 on 2008-05-13 to add Texture::_quality_level.
@ -61,5 +61,6 @@ static const unsigned short _bam_minor_ver = 41;
// Bumped to minor version 39 on 2016-01-09 to change lights and materials.
// Bumped to minor version 40 on 2016-01-11 to make NodePaths writable.
// Bumped to minor version 41 on 2016-03-02 to change LensNode, Lens, and Camera.
// Bumped to minor version 42 on 2016-04-08 to expand ColorBlendAttrib.
#endif