Changelog
Fix the texture operations to resolve glitches shown in UT2003 when get
quad damage.
checkGLcall must not supply a \n as that is supplied by its expansion
Performance fixes to save applying the same states 6 times and to reduce
function calls when accessing front/back buffers
Make traces more readable by more constants -> english descriptions
Jason
Note: This applies to cvs + dx53try2 + dx54 patches
diff -u3 dlls/d3d8/cvsplus54b/d3d8_private.h dlls/d3d8/d3d8_private.h
--- dlls/d3d8/cvsplus54b/d3d8_private.h 2003-06-11 20:35:55.000000000 +0100
+++ dlls/d3d8/d3d8_private.h 2003-06-11 20:26:57.000000000 +0100
@@ -1283,6 +1283,8 @@
const char* debug_d3dressourcetype(D3DRESOURCETYPE res);
const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType);
const char* debug_d3dpool(D3DPOOL Pool);
+const char *debug_d3drenderstate(DWORD State);
+const char *debug_d3dtexturestate(DWORD State);
/* Some #defines for additional diagnostics */
#if 0 /* NOTE: Must be 0 in cvs */
diff -u3 dlls/d3d8/cvsplus54b/device.c dlls/d3d8/device.c
--- dlls/d3d8/cvsplus54b/device.c 2003-06-11 20:35:55.000000000 +0100
+++ dlls/d3d8/device.c 2003-06-08 20:53:41.000000000 +0100
@@ -83,7 +83,20 @@
TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
- IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
+
+ /* Performance: For texture states where multiples effect the outcome, only bother
+ applying the last one as it will pick up all the other values */
+ switch (i) {
+ case D3DTSS_COLORARG0: /* Will be picked up when setting color op */
+ case D3DTSS_COLORARG1: /* Will be picked up when setting color op */
+ case D3DTSS_COLORARG2: /* Will be picked up when setting color op */
+ case D3DTSS_ALPHAARG0: /* Will be picked up when setting alpha op */
+ case D3DTSS_ALPHAARG1: /* Will be picked up when setting alpha op */
+ case D3DTSS_ALPHAARG2: /* Will be picked up when setting alpha op */
+ break;
+ default:
+ IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
+ }
}
/* Note the D3DRS value applies to all textures, but GL has one
@@ -1883,7 +1896,7 @@
ICOM_THIS(IDirect3DDevice8Impl,iface);
DWORD OldValue = This->StateBlock->renderstate[State];
- TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
+ TRACE("(%p)->state = %s(%d), value = %ld\n", This, debug_d3drenderstate(State), State, Value);
This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
This->UpdateStateBlock->Set.renderstate[State] = TRUE;
This->UpdateStateBlock->renderstate[State] = Value;
@@ -2237,7 +2250,7 @@
} else {
TRACE("Specular colors cannot be enabled in this version of opengl\n");
}
- checkGLcall("glEnable(GL_COLOR_SUM)\n");
+ checkGLcall("glEnable(GL_COLOR_SUM)");
} else {
float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -2251,7 +2264,7 @@
} else {
TRACE("Specular colors cannot be disabled in this version of opengl\n");
}
- checkGLcall("glDisable(GL_COLOR_SUM)\n");
+ checkGLcall("glDisable(GL_COLOR_SUM)");
}
}
break;
@@ -2380,10 +2393,10 @@
{
if (Value && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
glEnable(GL_FOG);
- checkGLcall("glEnable GL_FOG\n");
+ checkGLcall("glEnable GL_FOG");
} else {
glDisable(GL_FOG);
- checkGLcall("glDisable GL_FOG\n");
+ checkGLcall("glDisable GL_FOG");
}
}
break;
@@ -2467,7 +2480,7 @@
if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
glEnable(GL_COLOR_MATERIAL);
- checkGLcall("glEnable GL_GL_COLOR_MATERIAL\n");
+ checkGLcall("glEnable GL_COLOR_MATERIAL");
TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
@@ -2493,16 +2506,16 @@
if (Parm == -1) {
glDisable(GL_COLOR_MATERIAL);
- checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
+ checkGLcall("glDisable GL_COLOR_MATERIAL");
} else {
TRACE("glColorMaterial Parm=%d\n", Parm);
glColorMaterial(GL_FRONT_AND_BACK, Parm);
- checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)\n");
+ checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
}
} else {
glDisable(GL_COLOR_MATERIAL);
- checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
+ checkGLcall("glDisable GL_COLOR_MATERIAL");
}
}
break;
@@ -2514,12 +2527,12 @@
if (pattern->wRepeatFactor) {
glLineStipple(pattern->wRepeatFactor, pattern->wLinePattern);
- checkGLcall("glLineStipple(repeat, linepattern)\n");
+ checkGLcall("glLineStipple(repeat, linepattern)");
glEnable(GL_LINE_STIPPLE);
- checkGLcall("glEnable(GL_LINE_STIPPLE);\n");
+ checkGLcall("glEnable(GL_LINE_STIPPLE);");
} else {
glDisable(GL_LINE_STIPPLE);
- checkGLcall("glDisable(GL_LINE_STIPPLE);\n");
+ checkGLcall("glDisable(GL_LINE_STIPPLE);");
}
}
break;
@@ -2560,13 +2573,13 @@
case D3DRS_POINTSIZE :
TRACE("Set point size to %f\n", *((float*)&Value));
glPointSize(*((float*)&Value));
- checkGLcall("glPointSize(...);\n");
+ checkGLcall("glPointSize(...);");
break;
case D3DRS_POINTSIZE_MIN :
if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, *((float*)&Value));
- checkGLcall("glPointParameterfEXT(...);\n");
+ checkGLcall("glPointParameterfEXT(...);");
} else {
FIXME("D3DRS_POINTSIZE_MIN not supported on this opengl\n");
}
@@ -2575,7 +2588,7 @@
case D3DRS_POINTSIZE_MAX :
if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, *((float*)&Value));
- checkGLcall("glPointParameterfEXT(...);\n");
+ checkGLcall("glPointParameterfEXT(...);");
} else {
FIXME("D3DRS_POINTSIZE_MAX not supported on this opengl\n");
}
@@ -2595,7 +2608,7 @@
if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
- checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);\n");
+ checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
} else {
TRACE("D3DRS_POINTSCALEENABLE not supported on this opengl\n");
}
@@ -2603,7 +2616,7 @@
GLfloat att[3] = {1.0f, 0.0f, 0.0f};
if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
- checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);\n");
+ checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
} else {
TRACE("D3DRS_POINTSCALEENABLE not supported, but not on either\n");
}
@@ -2621,7 +2634,7 @@
Value & D3DCOLORWRITEENABLE_GREEN,
Value & D3DCOLORWRITEENABLE_BLUE,
Value & D3DCOLORWRITEENABLE_ALPHA);
- checkGLcall("glColorMask(...)\n");
+ checkGLcall("glColorMask(...)");
break;
/* Unhandled yet...! */
@@ -2853,7 +2866,7 @@
/* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
- TRACE("(%p) : stub, Stage=%ld, Type=%d, Value=%ld\n", This, Stage, Type, Value);
+ TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
/* Reject invalid texture units */
if (Stage >= GL_LIMITS(textures)) {
diff -u3 dlls/d3d8/cvsplus54b/surface.c dlls/d3d8/surface.c
--- dlls/d3d8/cvsplus54b/surface.c 2003-06-11 20:35:55.000000000 +0100
+++ dlls/d3d8/surface.c 2003-06-08 20:20:12.000000000 +0100
@@ -193,13 +193,15 @@
{
long j;
+ GLenum format = D3DFmt2GLFmt(This->Device, This->myDesc.Format);
+ GLenum type = D3DFmt2GLType(This->Device, This->myDesc.Format);
for (j = This->lockedRect.top; j < This->lockedRect.bottom - This->lockedRect.top; ++j) {
glReadPixels(This->lockedRect.left,
This->lockedRect.bottom - j - 1,
This->lockedRect.right - This->lockedRect.left,
1,
- D3DFmt2GLFmt(This->Device, This->myDesc.Format),
- D3DFmt2GLType(This->Device, This->myDesc.Format),
+ format,
+ type,
(char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-This->lockedRect.top)));
vcheckGLcall("glReadPixels");
}
diff -u3 dlls/d3d8/cvsplus54b/utils.c dlls/d3d8/utils.c
--- dlls/d3d8/cvsplus54b/utils.c 2003-06-11 20:35:55.000000000 +0100
+++ dlls/d3d8/utils.c 2003-06-11 19:40:43.000000000 +0100
@@ -165,6 +165,133 @@
}
}
+const char* debug_d3drenderstate(DWORD state) {
+ switch (state) {
+#define D3DSTATE_TO_STR(u) case u: return #u
+ D3DSTATE_TO_STR(D3DRS_ZENABLE );
+ D3DSTATE_TO_STR(D3DRS_FILLMODE );
+ D3DSTATE_TO_STR(D3DRS_SHADEMODE );
+ D3DSTATE_TO_STR(D3DRS_LINEPATTERN );
+ D3DSTATE_TO_STR(D3DRS_ZWRITEENABLE );
+ D3DSTATE_TO_STR(D3DRS_ALPHATESTENABLE );
+ D3DSTATE_TO_STR(D3DRS_LASTPIXEL );
+ D3DSTATE_TO_STR(D3DRS_SRCBLEND );
+ D3DSTATE_TO_STR(D3DRS_DESTBLEND );
+ D3DSTATE_TO_STR(D3DRS_CULLMODE );
+ D3DSTATE_TO_STR(D3DRS_ZFUNC );
+ D3DSTATE_TO_STR(D3DRS_ALPHAREF );
+ D3DSTATE_TO_STR(D3DRS_ALPHAFUNC );
+ D3DSTATE_TO_STR(D3DRS_DITHERENABLE );
+ D3DSTATE_TO_STR(D3DRS_ALPHABLENDENABLE );
+ D3DSTATE_TO_STR(D3DRS_FOGENABLE );
+ D3DSTATE_TO_STR(D3DRS_SPECULARENABLE );
+ D3DSTATE_TO_STR(D3DRS_ZVISIBLE );
+ D3DSTATE_TO_STR(D3DRS_FOGCOLOR );
+ D3DSTATE_TO_STR(D3DRS_FOGTABLEMODE );
+ D3DSTATE_TO_STR(D3DRS_FOGSTART );
+ D3DSTATE_TO_STR(D3DRS_FOGEND );
+ D3DSTATE_TO_STR(D3DRS_FOGDENSITY );
+ D3DSTATE_TO_STR(D3DRS_EDGEANTIALIAS );
+ D3DSTATE_TO_STR(D3DRS_ZBIAS );
+ D3DSTATE_TO_STR(D3DRS_RANGEFOGENABLE );
+ D3DSTATE_TO_STR(D3DRS_STENCILENABLE );
+ D3DSTATE_TO_STR(D3DRS_STENCILFAIL );
+ D3DSTATE_TO_STR(D3DRS_STENCILZFAIL );
+ D3DSTATE_TO_STR(D3DRS_STENCILPASS );
+ D3DSTATE_TO_STR(D3DRS_STENCILFUNC );
+ D3DSTATE_TO_STR(D3DRS_STENCILREF );
+ D3DSTATE_TO_STR(D3DRS_STENCILMASK );
+ D3DSTATE_TO_STR(D3DRS_STENCILWRITEMASK );
+ D3DSTATE_TO_STR(D3DRS_TEXTUREFACTOR );
+ D3DSTATE_TO_STR(D3DRS_WRAP0 );
+ D3DSTATE_TO_STR(D3DRS_WRAP1 );
+ D3DSTATE_TO_STR(D3DRS_WRAP2 );
+ D3DSTATE_TO_STR(D3DRS_WRAP3 );
+ D3DSTATE_TO_STR(D3DRS_WRAP4 );
+ D3DSTATE_TO_STR(D3DRS_WRAP5 );
+ D3DSTATE_TO_STR(D3DRS_WRAP6 );
+ D3DSTATE_TO_STR(D3DRS_WRAP7 );
+ D3DSTATE_TO_STR(D3DRS_CLIPPING );
+ D3DSTATE_TO_STR(D3DRS_LIGHTING );
+ D3DSTATE_TO_STR(D3DRS_AMBIENT );
+ D3DSTATE_TO_STR(D3DRS_FOGVERTEXMODE );
+ D3DSTATE_TO_STR(D3DRS_COLORVERTEX );
+ D3DSTATE_TO_STR(D3DRS_LOCALVIEWER );
+ D3DSTATE_TO_STR(D3DRS_NORMALIZENORMALS );
+ D3DSTATE_TO_STR(D3DRS_DIFFUSEMATERIALSOURCE );
+ D3DSTATE_TO_STR(D3DRS_SPECULARMATERIALSOURCE );
+ D3DSTATE_TO_STR(D3DRS_AMBIENTMATERIALSOURCE );
+ D3DSTATE_TO_STR(D3DRS_EMISSIVEMATERIALSOURCE );
+ D3DSTATE_TO_STR(D3DRS_VERTEXBLEND );
+ D3DSTATE_TO_STR(D3DRS_CLIPPLANEENABLE );
+ D3DSTATE_TO_STR(D3DRS_SOFTWAREVERTEXPROCESSING );
+ D3DSTATE_TO_STR(D3DRS_POINTSIZE );
+ D3DSTATE_TO_STR(D3DRS_POINTSIZE_MIN );
+ D3DSTATE_TO_STR(D3DRS_POINTSPRITEENABLE );
+ D3DSTATE_TO_STR(D3DRS_POINTSCALEENABLE );
+ D3DSTATE_TO_STR(D3DRS_POINTSCALE_A );
+ D3DSTATE_TO_STR(D3DRS_POINTSCALE_B );
+ D3DSTATE_TO_STR(D3DRS_POINTSCALE_C );
+ D3DSTATE_TO_STR(D3DRS_MULTISAMPLEANTIALIAS );
+ D3DSTATE_TO_STR(D3DRS_MULTISAMPLEMASK );
+ D3DSTATE_TO_STR(D3DRS_PATCHEDGESTYLE );
+ D3DSTATE_TO_STR(D3DRS_PATCHSEGMENTS );
+ D3DSTATE_TO_STR(D3DRS_DEBUGMONITORTOKEN );
+ D3DSTATE_TO_STR(D3DRS_POINTSIZE_MAX );
+ D3DSTATE_TO_STR(D3DRS_INDEXEDVERTEXBLENDENABLE );
+ D3DSTATE_TO_STR(D3DRS_COLORWRITEENABLE );
+ D3DSTATE_TO_STR(D3DRS_TWEENFACTOR );
+ D3DSTATE_TO_STR(D3DRS_BLENDOP );
+ D3DSTATE_TO_STR(D3DRS_POSITIONORDER );
+ D3DSTATE_TO_STR(D3DRS_NORMALORDER );
+#undef D3DSTATE_TO_STR
+ default:
+ FIXME("Unrecognized %lu render state!\n", state);
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3dtexturestate(DWORD state) {
+ switch (state) {
+#define D3DSTATE_TO_STR(u) case u: return #u
+ D3DSTATE_TO_STR(D3DTSS_COLOROP );
+ D3DSTATE_TO_STR(D3DTSS_COLORARG1 );
+ D3DSTATE_TO_STR(D3DTSS_COLORARG2 );
+ D3DSTATE_TO_STR(D3DTSS_ALPHAOP );
+ D3DSTATE_TO_STR(D3DTSS_ALPHAARG1 );
+ D3DSTATE_TO_STR(D3DTSS_ALPHAARG2 );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT00 );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT01 );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT10 );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT11 );
+ D3DSTATE_TO_STR(D3DTSS_TEXCOORDINDEX );
+ D3DSTATE_TO_STR(D3DTSS_ADDRESSU );
+ D3DSTATE_TO_STR(D3DTSS_ADDRESSV );
+ D3DSTATE_TO_STR(D3DTSS_BORDERCOLOR );
+ D3DSTATE_TO_STR(D3DTSS_MAGFILTER );
+ D3DSTATE_TO_STR(D3DTSS_MINFILTER );
+ D3DSTATE_TO_STR(D3DTSS_MIPFILTER );
+ D3DSTATE_TO_STR(D3DTSS_MIPMAPLODBIAS );
+ D3DSTATE_TO_STR(D3DTSS_MAXMIPLEVEL );
+ D3DSTATE_TO_STR(D3DTSS_MAXANISOTROPY );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVLSCALE );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVLOFFSET );
+ D3DSTATE_TO_STR(D3DTSS_TEXTURETRANSFORMFLAGS );
+ D3DSTATE_TO_STR(D3DTSS_ADDRESSW );
+ D3DSTATE_TO_STR(D3DTSS_COLORARG0 );
+ D3DSTATE_TO_STR(D3DTSS_ALPHAARG0 );
+ D3DSTATE_TO_STR(D3DTSS_RESULTARG );
+#undef D3DSTATE_TO_STR
+ case 12:
+ /* Note D3DTSS are not consecutive, so skip these */
+ return "unused";
+ break;
+ default:
+ FIXME("Unrecognized %lu texture state!\n", state);
+ return "unrecognized";
+ }
+}
+
/*
* Simple utility routines used for dx -> gl mapping of byte formats
*/
@@ -564,6 +691,17 @@
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;
+ /* Note: Operations usually involve two ars, src0 and src1 and are operations of
+ the form (a1 <operation> a2). However, some of the more complex operations
+ take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
+ in a third parameter called a0. Therefore these are operations of the form
+ a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
+
+ However, below we treat the new (a0) parameter as src2/opr2, so in the actual
+ functions below, expect their syntax to differ slightly to those listed in the
+ manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
+ This affects D3DTOP_MULTIPLYADD and D3DTOP_LERP */
+
if (isAlpha) {
comb_target = useext(GL_COMBINE_ALPHA);
src0_target = useext(GL_SOURCE0_ALPHA);
@@ -589,7 +727,7 @@
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) {
+ if (isAlpha && This->StateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) {
GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1);
} else {
GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1);
@@ -817,17 +955,17 @@
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);
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
- glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
- glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
- glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
- glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
- glTexEnvi(GL_TEXTURE_ENV, opr2_target, src1);
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, src3);
checkGLcall("GL_TEXTURE_ENV, opr2_target, src1");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
@@ -835,43 +973,95 @@
default:
Handled = FALSE;
}
+
if (Handled) {
+ BOOL combineOK = TRUE;
#if defined(GL_NV_texture_env_combine4)
+ DWORD op2;
+
+ if (isAlpha) {
+ op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP];
+ } else {
+ op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_ALPHAOP];
+ }
+
/* 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);
+ switch (op2)
+ {
+ 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:
+ /* Ignore those implemented in both cases */
+ switch (op) {
+ case D3DTOP_SELECTARG1:
+ case D3DTOP_SELECTARG2:
+ combineOK = FALSE;
+ Handled = FALSE;
+ break;
+ default:
+ FIXME("Cant have COMBINE4 and COMBINE in efferct together, thisop=%d, otherop=%ld, isAlpha(%d)\n",
+ op, op2, isAlpha);
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;
+
+ if (combineOK == TRUE) {
+ 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) {
+ opr = GL_SRC_ALPHA;
invopr = GL_ONE_MINUS_SRC_ALPHA;
src3_target = GL_SOURCE3_ALPHA_NV;
opr3_target = GL_OPERAND3_ALPHA_NV;
}
else {
+ opr = GL_SRC_COLOR;
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_SELECTARG1: /* = a1 * 1 + 0 * 0 */
+ case D3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ if (op == D3DTOP_SELECTARG1) {
+ 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");
+ } else {
+ 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, 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, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ break;
+
case D3DTOP_ADDSMOOTH:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
@@ -1037,21 +1227,21 @@
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);
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
- glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
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);
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
- glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
- glTexEnvi(GL_TEXTURE_ENV, src3_target, src3);
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
- glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr3);
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");