|
@@ -129,16 +129,23 @@ null_glActiveTexture(GLenum gl_texture_stage) {
|
|
|
|
|
|
|
|
#ifdef OPENGLES_2
|
|
#ifdef OPENGLES_2
|
|
|
#define _glBlendEquation glBlendEquation
|
|
#define _glBlendEquation glBlendEquation
|
|
|
|
|
+#define _glBlendEquationSeparate glBlendEquationSeparate
|
|
|
|
|
+#define _glBlendFuncSeparate glBlendFuncSeparate
|
|
|
#define _glBlendColor glBlendColor
|
|
#define _glBlendColor glBlendColor
|
|
|
#else
|
|
#else
|
|
|
static void APIENTRY
|
|
static void APIENTRY
|
|
|
null_glBlendEquation(GLenum) {
|
|
null_glBlendEquation(GLenum) {
|
|
|
}
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
|
+
|
|
|
|
|
+static void APIENTRY
|
|
|
|
|
+null_glBlendFuncSeparate(GLenum src, GLenum dest, GLenum, GLenum) {
|
|
|
|
|
+ glBlendFunc(src, dest);
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
static void APIENTRY
|
|
static void APIENTRY
|
|
|
null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
|
|
null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
|
|
|
}
|
|
}
|
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
#ifndef OPENGLES_1
|
|
#ifndef OPENGLES_1
|
|
|
// We have a default shader that will be applied when there isn't any shader
|
|
// We have a default shader that will be applied when there isn't any shader
|
|
@@ -2284,29 +2291,115 @@ reset() {
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
- // In OpenGL ES 2.x, this is supported in the core.
|
|
|
|
|
-#ifndef OPENGLES_2
|
|
|
|
|
- _glBlendEquation = NULL;
|
|
|
|
|
- bool supports_blend_equation = false;
|
|
|
|
|
|
|
+#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)) {
|
|
if (is_at_least_gl_version(1, 2)) {
|
|
|
- supports_blend_equation = true;
|
|
|
|
|
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
|
|
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
|
|
|
get_extension_func("glBlendEquation");
|
|
get_extension_func("glBlendEquation");
|
|
|
- } else if (has_extension("GL_OES_blend_subtract")) {
|
|
|
|
|
- supports_blend_equation = true;
|
|
|
|
|
- _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
|
|
|
|
|
- get_extension_func("glBlendEquationOES");
|
|
|
|
|
|
|
+
|
|
|
} else if (has_extension("GL_EXT_blend_minmax")) {
|
|
} else if (has_extension("GL_EXT_blend_minmax")) {
|
|
|
- supports_blend_equation = true;
|
|
|
|
|
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
|
|
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
|
|
|
get_extension_func("glBlendEquationEXT");
|
|
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) {
|
|
if (_glBlendEquation == NULL) {
|
|
|
_glBlendEquation = null_glBlendEquation;
|
|
_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
|
|
#endif
|
|
|
|
|
|
|
@@ -2332,6 +2425,15 @@ reset() {
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#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
|
|
#ifdef OPENGLES
|
|
|
_edge_clamp = GL_CLAMP_TO_EDGE;
|
|
_edge_clamp = GL_CLAMP_TO_EDGE;
|
|
|
#else
|
|
#else
|
|
@@ -6902,6 +7004,7 @@ do_issue_blending() {
|
|
|
_target_rs->get_attrib_def(target_color_blend);
|
|
_target_rs->get_attrib_def(target_color_blend);
|
|
|
CPT(ColorBlendAttrib) color_blend = target_color_blend;
|
|
CPT(ColorBlendAttrib) color_blend = target_color_blend;
|
|
|
ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
|
|
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;
|
|
const TransparencyAttrib *target_transparency;
|
|
|
_target_rs->get_attrib_def(target_transparency);
|
|
_target_rs->get_attrib_def(target_transparency);
|
|
@@ -6914,9 +7017,17 @@ do_issue_blending() {
|
|
|
enable_multisample_alpha_one(false);
|
|
enable_multisample_alpha_one(false);
|
|
|
enable_multisample_alpha_mask(false);
|
|
enable_multisample_alpha_mask(false);
|
|
|
enable_blend(true);
|
|
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
|
|
#ifndef OPENGLES_1
|
|
|
LColor c;
|
|
LColor c;
|
|
@@ -6931,9 +7042,17 @@ do_issue_blending() {
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
if (GLCAT.is_spam()) {
|
|
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
|
|
#ifndef OPENGLES_1
|
|
|
GLCAT.spam() << "glBlendColor(" << c << ")\n";
|
|
GLCAT.spam() << "glBlendColor(" << c << ")\n";
|
|
|
#endif
|
|
#endif
|
|
@@ -9304,6 +9423,13 @@ get_blend_func(ColorBlendAttrib::Operand operand) {
|
|
|
case ColorBlendAttrib::O_one_minus_constant_alpha:
|
|
case ColorBlendAttrib::O_one_minus_constant_alpha:
|
|
|
case ColorBlendAttrib::O_one_minus_alpha_scale:
|
|
case ColorBlendAttrib::O_one_minus_alpha_scale:
|
|
|
break;
|
|
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
|
|
#else
|
|
|
case ColorBlendAttrib::O_constant_color:
|
|
case ColorBlendAttrib::O_constant_color:
|
|
|
case ColorBlendAttrib::O_color_scale:
|
|
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_constant_alpha:
|
|
|
case ColorBlendAttrib::O_one_minus_alpha_scale:
|
|
case ColorBlendAttrib::O_one_minus_alpha_scale:
|
|
|
return GL_ONE_MINUS_CONSTANT_ALPHA;
|
|
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
|
|
#endif
|
|
|
|
|
|
|
|
case ColorBlendAttrib::O_incoming_color_saturate:
|
|
case ColorBlendAttrib::O_incoming_color_saturate:
|