Add support for a lot of the remaining texture ops, move code into the
utils module, and clean up the main code path.
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index c1c8cec..b18b584 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -985,71 +985,6 @@
TRACE("glEnd\n");
}
-/**
- * @nodoc: todo
- */
-void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand)
-{
- BOOL isAlphaReplicate = FALSE;
- BOOL isComplement = FALSE;
-
- *operand = GL_SRC_COLOR;
- *source = GL_TEXTURE;
-
- /* Catch alpha replicate */
- if (iValue & D3DTA_ALPHAREPLICATE) {
- iValue = iValue & ~D3DTA_ALPHAREPLICATE;
- isAlphaReplicate = TRUE;
- }
-
- /* Catch Complement */
- if (iValue & D3DTA_COMPLEMENT) {
- iValue = iValue & ~D3DTA_COMPLEMENT;
- isComplement = TRUE;
- }
-
- /* Calculate the operand */
- if (isAlphaReplicate && !isComplement) {
- *operand = GL_SRC_ALPHA;
- } else if (isAlphaReplicate && isComplement) {
- *operand = GL_ONE_MINUS_SRC_ALPHA;
- } else if (isComplement) {
- if (isAlphaArg) {
- *operand = GL_ONE_MINUS_SRC_ALPHA;
- } else {
- *operand = GL_ONE_MINUS_SRC_COLOR;
- }
- } else {
- if (isAlphaArg) {
- *operand = GL_SRC_ALPHA;
- } else {
- *operand = GL_SRC_COLOR;
- }
- }
-
- /* Calculate the source */
- switch (iValue & D3DTA_SELECTMASK) {
- case D3DTA_CURRENT: *source = GL_PREVIOUS_EXT;
- break;
- case D3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT;
- break;
- case D3DTA_TEXTURE: *source = GL_TEXTURE;
- break;
- case D3DTA_TFACTOR: *source = GL_CONSTANT_EXT;
- break;
- case D3DTA_SPECULAR:
- /**
- * According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
- * isnt supported until base GL supports it
- * There is no concept of temp registers as far as I can tell
- */
-
- default:
- FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
- *source = GL_TEXTURE;
- }
-}
-
/* Apply the current values to the specified texture stage */
void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
@@ -3848,63 +3783,22 @@
}
break;
- case D3DTSS_COLORARG0 :
- case D3DTSS_ALPHAARG0 :
- /* FIXME: Mesa seems to struggle setting these at the moment */
- /*FIXME("COLORARG0/ALPHAARG0 support still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);*/
- /*break;*/
-
- case D3DTSS_COLORARG1 :
- case D3DTSS_COLORARG2 :
- case D3DTSS_ALPHAARG1 :
- case D3DTSS_ALPHAARG2 :
- {
- BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
- int operand = GL_SRC_COLOR;
- int source = GL_TEXTURE;
-
- GetSrcAndOpFromValue(Value, isAlphaArg, &source, &operand);
- if (isAlphaArg) {
-
- /* From MSDN (D3DTSS_ALPHAARG1) :
- The default argument is D3DTA_TEXTURE. If no texture is set for this stage,
- then the default argument is D3DTA_DIFFUSE.
- FIXME? If texture added/removed, may need to reset back as well? */
- if (Type == D3DTSS_ALPHAARG1 && This->StateBlock->textures[Stage] == NULL && Value == D3DTA_TEXTURE) {
- GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlphaArg, &source, &operand);
- }
- TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
- glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
- vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
- glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
- vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
- } else {
- TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
- glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
- vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
- glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
- vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
- }
- }
- break;
-
case D3DTSS_ALPHAOP :
case D3DTSS_COLOROP :
{
- int Scale = 1;
- int Parm = (Type == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
-
- if (Type == D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
+ if (Value == D3DTOP_DISABLE) {
/* TODO: Disable by making this and all later levels disabled */
- glDisable(GL_TEXTURE_1D);
- checkGLcall("Disable GL_TEXTURE_1D");
- glDisable(GL_TEXTURE_2D);
- checkGLcall("Disable GL_TEXTURE_2D");
- glDisable(GL_TEXTURE_3D);
- checkGLcall("Disable GL_TEXTURE_3D");
+ if (Type == D3DTSS_COLOROP) {
+ glDisable(GL_TEXTURE_1D);
+ checkGLcall("Disable GL_TEXTURE_1D");
+ glDisable(GL_TEXTURE_2D);
+ checkGLcall("Disable GL_TEXTURE_2D");
+ glDisable(GL_TEXTURE_3D);
+ checkGLcall("Disable GL_TEXTURE_3D");
+ }
+ break; /* Dont bother setting the texture operations */
} else {
-
/* Enable only the appropriate texture dimension */
if (Type == D3DTSS_COLOROP) {
if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
@@ -3936,139 +3830,27 @@
checkGLcall("Disable GL_TEXTURE_CUBE_MAP");
}
}
-
- /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
- if (Value != D3DTOP_DISABLE) {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
- }
-
- /* Now set up the operand correctly */
- switch (Value) {
- case D3DTOP_DISABLE :
- /* Contrary to the docs, alpha can be disabled when colorop is enabled
- and it works, so ignore this op */
- TRACE("Disable ALPHAOP but COLOROP enabled!\n");
- break;
-
- case D3DTOP_SELECTARG1 :
- {
- glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
- }
- break;
-
- case D3DTOP_SELECTARG2 :
- {
- BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP);
- DWORD dwValue = 0;
- GLenum source;
- GLenum operand;
- /*FIXME("see if D3DTOP_SELECTARG2 behavior is correct now!\n");*/
- glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
- /* GL_REPLACE, swap args 0 and 1? */
- dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG2 : D3DTSS_COLORARG2];
- GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
- if (isAlphaOp) {
- TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_ALPHA_EXT, source, GL_OPERAND0_ALPHA_EXT, operand);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, source);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, 'source')");
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, operand);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, 'operand')");
- } else {
- TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_RGB_EXT, source, GL_OPERAND0_RGB_EXT, operand);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, source);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')");
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, operand);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, 'operand')");
- }
- dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG1 : D3DTSS_COLORARG1];
- GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
- if (isAlphaOp) {
- TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_ALPHA_EXT, source, GL_OPERAND1_ALPHA_EXT, operand);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, source);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, 'source')");
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, operand);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, 'operand')");
- } else {
- TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_RGB_EXT, source, GL_OPERAND1_RGB_EXT, operand);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, source);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, 'source')");
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, operand);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, 'operand')");
- }
- }
- break;
-
- case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
- case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
- case D3DTOP_MODULATE :
-
- /* Correct scale */
- if (Type == D3DTSS_ALPHAOP) {
- glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
- vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
- } else {
- glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
- vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
- }
- glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
- break;
-
- case D3DTOP_ADD :
- glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
- vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
- break;
-
- case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
- case D3DTOP_ADDSIGNED :
- glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
- vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
- break;
-
- case D3DTOP_DOTPRODUCT3 :
-#if defined(GL_VERSION_1_3)
- if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
- glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
- break;
- }
-#endif
- FIXME("DotProduct3 extension requested but not supported via this version of opengl\n");
- break;
-
-
- case D3DTOP_SUBTRACT :
-#if defined(GL_VERSION_1_3)
- glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT);
- checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT)");
- break;
-#else
- /**
- * @TODO: to check:
- * if ARB_texture_env_combine is supported
- * we can use GL_SUBTRACT_ARB here
- */
-#endif
-
- case D3DTOP_ADDSMOOTH :
- case D3DTOP_BLENDDIFFUSEALPHA :
- case D3DTOP_BLENDTEXTUREALPHA :
- case D3DTOP_BLENDFACTORALPHA :
- case D3DTOP_BLENDTEXTUREALPHAPM :
- case D3DTOP_BLENDCURRENTALPHA :
- case D3DTOP_PREMODULATE :
- case D3DTOP_MODULATEALPHA_ADDCOLOR :
- case D3DTOP_MODULATECOLOR_ADDALPHA :
- case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
- case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
- case D3DTOP_BUMPENVMAP :
- case D3DTOP_BUMPENVMAPLUMINANCE :
- case D3DTOP_MULTIPLYADD :
- case D3DTOP_LERP :
- default:
- FIXME("Unhandled texture operation %ld\n", Value);
+ }
+ /* Drop through... (Except disable case) */
+ case D3DTSS_COLORARG0 :
+ case D3DTSS_COLORARG1 :
+ case D3DTSS_COLORARG2 :
+ case D3DTSS_ALPHAARG0 :
+ case D3DTSS_ALPHAARG1 :
+ case D3DTSS_ALPHAARG2 :
+ {
+ BOOL isAlphaArg = (Type == D3DTSS_ALPHAOP || Type == D3DTSS_ALPHAARG1 ||
+ Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
+ if (isAlphaArg) {
+ set_tex_op(iface, TRUE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_ALPHAOP],
+ This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1],
+ This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG2],
+ This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG0]);
+ } else {
+ set_tex_op(iface, FALSE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_COLOROP],
+ This->StateBlock->texture_state[Stage][D3DTSS_COLORARG1],
+ This->StateBlock->texture_state[Stage][D3DTSS_COLORARG2],
+ This->StateBlock->texture_state[Stage][D3DTSS_COLORARG0]);
}
}
break;
diff --git a/dlls/d3d8/utils.c b/dlls/d3d8/utils.c
index 75ac1a5..0d0433f 100644
--- a/dlls/d3d8/utils.c
+++ b/dlls/d3d8/utils.c
@@ -468,3 +468,618 @@
return GL_ALWAYS;
}
}
+
+/**
+ * @nodoc: todo
+ */
+void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand)
+{
+ BOOL isAlphaReplicate = FALSE;
+ BOOL isComplement = FALSE;
+
+ *operand = GL_SRC_COLOR;
+ *source = GL_TEXTURE;
+
+ /* Catch alpha replicate */
+ if (iValue & D3DTA_ALPHAREPLICATE) {
+ iValue = iValue & ~D3DTA_ALPHAREPLICATE;
+ isAlphaReplicate = TRUE;
+ }
+
+ /* Catch Complement */
+ if (iValue & D3DTA_COMPLEMENT) {
+ iValue = iValue & ~D3DTA_COMPLEMENT;
+ isComplement = TRUE;
+ }
+
+ /* Calculate the operand */
+ if (isAlphaReplicate && !isComplement) {
+ *operand = GL_SRC_ALPHA;
+ } else if (isAlphaReplicate && isComplement) {
+ *operand = GL_ONE_MINUS_SRC_ALPHA;
+ } else if (isComplement) {
+ if (isAlphaArg) {
+ *operand = GL_ONE_MINUS_SRC_ALPHA;
+ } else {
+ *operand = GL_ONE_MINUS_SRC_COLOR;
+ }
+ } else {
+ if (isAlphaArg) {
+ *operand = GL_SRC_ALPHA;
+ } else {
+ *operand = GL_SRC_COLOR;
+ }
+ }
+
+ /* Calculate the source */
+ switch (iValue & D3DTA_SELECTMASK) {
+ case D3DTA_CURRENT: *source = GL_PREVIOUS_EXT;
+ break;
+ case D3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT;
+ break;
+ case D3DTA_TEXTURE: *source = GL_TEXTURE;
+ break;
+ case D3DTA_TFACTOR: *source = GL_CONSTANT_EXT;
+ break;
+ case D3DTA_SPECULAR:
+ /**
+ * According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
+ * isnt supported until base GL supports it
+ * There is no concept of temp registers as far as I can tell
+ */
+
+ default:
+ FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
+ *source = GL_TEXTURE;
+ }
+}
+
+/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
+#if defined (GL_VERSION_1_3)
+ #define useext(A) A
+ #define combine_ext 1
+#elif defined (GL_EXT_texture_env_combine)
+ #define useext(A) A##_EXT
+ #define combine_ext 1
+#elif defined (GL_ARB_texture_env_combine)
+ #define useext(A) A##_ARB
+ #define combine_ext 1
+#else
+ #undef combine_ext
+#endif
+
+#if !defined(combine_ext)
+void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
+{
+ FIXME("Requires opengl combine extensions to work\n");
+ return;
+}
+#else
+/* Setup the texture operations texture stage states */
+void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
+{
+ GLenum src1, src2, src3;
+ GLenum opr1, opr2, opr3;
+ GLenum comb_target;
+ GLenum src0_target, src1_target, src2_target;
+ GLenum opr0_target, opr1_target, opr2_target;
+ GLenum scal_target;
+ GLenum opr=0, invopr, src3_target, opr3_target;
+ BOOL Handled = FALSE;
+ ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+ TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3);
+ if (op == D3DTOP_DISABLE) return;
+
+ if (isAlpha) {
+ comb_target = useext(GL_COMBINE_ALPHA);
+ src0_target = useext(GL_SOURCE0_ALPHA);
+ src1_target = useext(GL_SOURCE1_ALPHA);
+ src2_target = useext(GL_SOURCE2_ALPHA);
+ opr0_target = useext(GL_OPERAND0_ALPHA);
+ opr1_target = useext(GL_OPERAND1_ALPHA);
+ opr2_target = useext(GL_OPERAND2_ALPHA);
+ scal_target = useext(GL_ALPHA_SCALE);
+ }
+ else {
+ comb_target = useext(GL_COMBINE_RGB);
+ src0_target = useext(GL_SOURCE0_RGB);
+ src1_target = useext(GL_SOURCE1_RGB);
+ src2_target = useext(GL_SOURCE2_RGB);
+ opr0_target = useext(GL_OPERAND0_RGB);
+ opr1_target = useext(GL_OPERAND1_RGB);
+ opr2_target = useext(GL_OPERAND2_RGB);
+ scal_target = useext(GL_RGB_SCALE);
+ }
+
+ /* From MSDN (D3DTSS_ALPHAARG1) :
+ The default argument is D3DTA_TEXTURE. If no texture is set for this stage,
+ then the default argument is D3DTA_DIFFUSE.
+ FIXME? If texture added/removed, may need to reset back as well? */
+ if (isAlpha && Stage==0 && This->StateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) {
+ GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1);
+ } else {
+ GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1);
+ }
+ GetSrcAndOpFromValue(arg2, isAlpha, &src2, &opr2);
+ GetSrcAndOpFromValue(arg3, isAlpha, &src3, &opr3);
+
+ TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
+
+ Handled = TRUE; /* Assume will be handled */
+ switch (op) {
+ case D3DTOP_SELECTARG1:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_SELECTARG2:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATE:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATE2X:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+ break;
+ case D3DTOP_MODULATE4X:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
+ break;
+ case D3DTOP_ADD:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_ADDSIGNED:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_ADDSIGNED2X:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+ break;
+ case D3DTOP_SUBTRACT:
+#if defined(GL_VERSION_1_3) || defined (GL_ARB_texture_env_combine)
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+#else
+ FIXME("This version of opengl does not support GL_SUBTRACT\n");
+#endif
+ break;
+ case D3DTOP_BLENDDIFFUSEALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_BLENDTEXTUREALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_BLENDFACTORALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_BLENDCURRENTALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_DOTPRODUCT3:
+#if defined(GL_EXT_texture_env_dot3)
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
+#elif defined(GL_ARB_texture_env_dot3)
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
+#elif defined (GL_VERSION_1_3)
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA");
+#else
+ FIXME("This version of opengl does not support GL_DOT3\n");
+#endif
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_LERP:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ default:
+ Handled = FALSE;
+ }
+ if (Handled) {
+#if defined(GL_NV_texture_env_combine4)
+ /* Note: If COMBINE4 in effect cant go back to combine! */
+ if (isAlpha) {
+ switch (This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP])
+ {
+ case D3DTOP_ADDSMOOTH:
+ case D3DTOP_BLENDTEXTUREALPHAPM:
+ case D3DTOP_MODULATEALPHA_ADDCOLOR:
+ case D3DTOP_MODULATECOLOR_ADDALPHA:
+ case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
+ case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
+ case D3DTOP_MULTIPLYADD:
+ FIXME("Cant have COMBINE4 and COMBINE in efferct together, alphaop=%d\n", op);
+ return;
+ }
+ }
+#endif
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
+ checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
+ return;
+ }
+
+ /* Other texture operations require special extensions: */
+#if defined(GL_NV_texture_env_combine4)
+ if (isAlpha) {
+ invopr = GL_ONE_MINUS_SRC_ALPHA;
+ src3_target = GL_SOURCE3_ALPHA_NV;
+ opr3_target = GL_OPERAND3_ALPHA_NV;
+ }
+ else {
+ invopr = GL_ONE_MINUS_SRC_COLOR;
+ src3_target = GL_SOURCE3_RGB_NV;
+ opr3_target = GL_OPERAND3_RGB_NV;
+ }
+ Handled = TRUE; /* Again, assume handled */
+ switch (op) {
+ case D3DTOP_ADDSMOOTH:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_SRC_COLOR; break;
+ case GL_SRC_ALPHA: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr1 = GL_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_BLENDTEXTUREALPHAPM:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATEALPHA_ADDCOLOR:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATECOLOR_ADDALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MULTIPLYADD:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src3);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr3);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+
+ default:
+ Handled = FALSE;
+ }
+ if (Handled) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+ checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
+ return;
+ }
+#endif /* GL_NV_texture_env_combine4 */
+
+ /* After all the extensions, if still unhandled, report fixme */
+ FIXME("Unhandled texture operation %d\n", op);
+}
+#endif