-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi again, this thime better: with patch attached Changelog - trying to get D3DTOP_SELECTARG_* working. It seems ok here (more textures on war3) but i'm not really sure of that code - code D3DTOP_SUBTRACT: currently only if OpenGL1.3 is used. We have to use GL_SUBTRACT_ARB for other versions - some comments on new Jason code Regards, Raphael -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQE+uEYFp7NA3AmQTU4RAm86AJ4vv/z4vYEpARUn7z9cePIOUvTwYgCfdTbC tHPmYfB5QkKAlIieslcLfP4= =6b/P -----END PGP SIGNATURE-----
Index: device.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/device.c,v retrieving revision 1.45 diff -u -r1.45 device.c --- device.c 6 May 2003 00:19:11 -0000 1.45 +++ device.c 6 May 2003 23:20:51 -0000 @@ -1004,6 +1004,71 @@ } } +/** + * @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); + } +} + + /* Apply the current values to the specified texture stage */ void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) { ICOM_THIS(IDirect3DDevice8Impl,iface); @@ -3399,25 +3463,27 @@ case D3DTSS_ALPHAARG1 : case D3DTSS_ALPHAARG2 : { - BOOL isAlphaReplicate = FALSE; - BOOL isComplement = FALSE; + /*BOOL isAlphaReplicate = FALSE; + BOOL isComplement = FALSE;*/ BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0); - int operand= GL_SRC_COLOR; + int operand = GL_SRC_COLOR; int source = GL_TEXTURE; - /* Catch alpha replicate */ + GetSrcAndOpFromValue(Value, isAlphaArg, &source, &operand); + /* + / * Catch alpha replicate * / if (Value & D3DTA_ALPHAREPLICATE) { Value = Value & ~D3DTA_ALPHAREPLICATE; isAlphaReplicate = TRUE; } - /* Catch Complement */ + / * Catch Complement * / if (Value & D3DTA_COMPLEMENT) { Value = Value & ~D3DTA_COMPLEMENT; isComplement = TRUE; } - /* Calculate the operand */ + / * Calculate the operand * / if (isAlphaReplicate && !isComplement) { operand = GL_SRC_ALPHA; } else if (isAlphaReplicate && isComplement) { @@ -3436,7 +3502,7 @@ } } - /* Calculate the source */ + / * Calculate the source * / switch (Value) { case D3DTA_CURRENT: source = GL_PREVIOUS_EXT; break; @@ -3447,27 +3513,27 @@ case D3DTA_TFACTOR: source = GL_CONSTANT_EXT; break; - /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and + / * 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 */ + There is no concept of temp registers as far as I can tell * / default: FIXME("Unrecognized or unhandled texture arg %ld\n", Value); } - + */ if (isAlphaArg) { 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); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);"); + vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);"); glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, 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); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);"); + vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);"); glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);"); + vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);"); } } break; @@ -3527,11 +3593,41 @@ break; case D3DTOP_SELECTARG1 : - glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)"); + { + BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP); + DWORD dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG1 : D3DTSS_COLORARG1]; + 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)"); + GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand); + glTexEnvi(GL_TEXTURE_ENV, (isAlphaOp) ? GL_SOURCE0_ALPHA_EXT : GL_SOURCE0_RGB_EXT, source); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')"); + glTexEnvi(GL_TEXTURE_ENV, (isAlphaOp) ? GL_OPERAND0_ALPHA_EXT : GL_OPERAND0_RGB_EXT, operand); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'operand')"); + } break; + case D3DTOP_SELECTARG2 : + { + BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP); + DWORD dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG2 : D3DTSS_COLORARG2]; + 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? */ + GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand); + glTexEnvi(GL_TEXTURE_ENV, (isAlphaOp) ? GL_SOURCE0_ALPHA_EXT : GL_SOURCE0_RGB_EXT, source); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')"); + glTexEnvi(GL_TEXTURE_ENV, (isAlphaOp) ? GL_OPERAND0_ALPHA_EXT : GL_OPERAND0_RGB_EXT, operand); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'operand')"); + } + break; + case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */ case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */ case D3DTOP_MODULATE : @@ -3570,9 +3666,17 @@ break; case D3DTOP_SUBTRACT : - /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */ - case D3DTOP_SELECTARG2 : - /* GL_REPLACE, swap args 0 and 1? */ +#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 : @@ -3654,44 +3758,64 @@ break; case D3DTSS_TEXCOORDINDEX : - /* CameraSpacePosition means use the vertex position, transformed to camera space, - as the input texture coordinates for this stage's texture transformation. This - equates roughly to EYE_LINEAR */ - if (Value & D3DTSS_TCI_CAMERASPACEPOSITION) { - float s_plane[] = { 1.0, 0.0, 0.0, 0.0 }; - float t_plane[] = { 0.0, 1.0, 0.0, 0.0 }; - float r_plane[] = { 0.0, 0.0, 1.0, 0.0 }; - float q_plane[] = { 0.0, 0.0, 0.0, 1.0 }; - TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n"); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glTexGenfv(GL_S, GL_EYE_PLANE, s_plane); - glTexGenfv(GL_T, GL_EYE_PLANE, t_plane); - glTexGenfv(GL_R, GL_EYE_PLANE, r_plane); - glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane); - glPopMatrix(); - - TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n"); - glEnable(GL_TEXTURE_GEN_S); - checkGLcall("glEnable(GL_TEXTURE_GEN_S);"); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); - glEnable(GL_TEXTURE_GEN_T); - checkGLcall("glEnable(GL_TEXTURE_GEN_T);"); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); - glEnable(GL_TEXTURE_GEN_R); - checkGLcall("glEnable(GL_TEXTURE_GEN_R);"); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); - } - - /* Todo: */ - if (Value && Value != D3DTSS_TCI_CAMERASPACEPOSITION) { - /* ? disable GL_TEXTURE_GEN_n ? */ - FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value); + { + /* CameraSpacePosition means use the vertex position, transformed to camera space, + as the input texture coordinates for this stage's texture transformation. This + equates roughly to EYE_LINEAR */ + + /** + * To Jason: i don't understand what to do with the (Value & 0x00FF) index + * it seems a texture coordinate index (0 <= x <= 7) seeing msdn and logs + * have you any idea ? + */ + + /** + * Be carefull the value of the mask 0xF0000 come from d3d8types.h infos + */ + switch (Value & 0xFFFFFF00) { + case D3DTSS_TCI_PASSTHRU: + /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/ + break; + + case D3DTSS_TCI_CAMERASPACEPOSITION: + { + float s_plane[] = { 1.0, 0.0, 0.0, 0.0 }; + float t_plane[] = { 0.0, 1.0, 0.0, 0.0 }; + float r_plane[] = { 0.0, 0.0, 1.0, 0.0 }; + float q_plane[] = { 0.0, 0.0, 0.0, 1.0 }; + TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n"); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glTexGenfv(GL_S, GL_EYE_PLANE, s_plane); + glTexGenfv(GL_T, GL_EYE_PLANE, t_plane); + glTexGenfv(GL_R, GL_EYE_PLANE, r_plane); + glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane); + glPopMatrix(); + + TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n"); + glEnable(GL_TEXTURE_GEN_S); + checkGLcall("glEnable(GL_TEXTURE_GEN_S);"); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); + glEnable(GL_TEXTURE_GEN_T); + checkGLcall("glEnable(GL_TEXTURE_GEN_T);"); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); + glEnable(GL_TEXTURE_GEN_R); + checkGLcall("glEnable(GL_TEXTURE_GEN_R);"); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)"); + } + break; + + default: + /* Todo: */ + /* ? disable GL_TEXTURE_GEN_n ? */ + FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value); + break; + } } break;