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.
This commit is contained in:
Jason Edmeades 2003-06-13 19:14:34 +00:00 committed by Alexandre Julliard
parent bba49757bb
commit 21a092816a
4 changed files with 256 additions and 49 deletions

View File

@ -1283,6 +1283,8 @@ const char* debug_d3dformat(D3DFORMAT fmt);
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 */

View File

@ -83,7 +83,20 @@ void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
} 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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
} 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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
{
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
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 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
Value & D3DCOLORWRITEENABLE_GREEN,
Value & D3DCOLORWRITEENABLE_BLUE,
Value & D3DCOLORWRITEENABLE_ALPHA);
checkGLcall("glColorMask(...)\n");
checkGLcall("glColorMask(...)");
break;
/* Unhandled yet...! */
@ -2853,7 +2866,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 ifa
/* 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)) {

View File

@ -193,13 +193,15 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
{
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");
}

View File

@ -165,6 +165,133 @@ const char* debug_d3dpool(D3DPOOL Pool) {
}
}
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 @@ void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP o
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 @@ void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP o
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 @@ void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP o
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 @@ void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP o
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 @@ void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP o
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");