[D3D 83] Some reorg / fixes / rewrite

Lionel Ulmer lionel.ulmer at free.fr
Mon Jan 6 15:43:54 CST 2003


Changelog:
 - rewrote a little bit the state magagement to remove the RenderState
   stucture and use only the state_block code
 - factorize some code between interface revisions
 - fix some smalls bugs
 
Note: this patch was against CVS + Christoph's ClipPlane patch (that I
      'nicknamed' D3D 82 thus this patch is D3D 83).

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- ../wine_base/dlls/ddraw/d3d_private.h	Mon Jan  6 21:46:44 2003
+++ dlls/ddraw/d3d_private.h	Mon Jan  6 21:46:55 2003
@@ -26,9 +26,11 @@
 
 #include "d3d.h"
 
+#define MAX_TEXTURES 8
+#define MAX_LIGHTS  16
+
 #define HIGHEST_RENDER_STATE         152
 #define HIGHEST_TEXTURE_STAGE_STATE   24
-#define HIGHEST_LIGHT_STATE            8
 
 /*****************************************************************************
  * Predeclare the interface implementation structures
@@ -45,15 +47,13 @@
 
 typedef struct STATEBLOCKFLAGS {
    BOOL render_state[HIGHEST_RENDER_STATE];
-   BOOL texture_stage_state[8][HIGHEST_TEXTURE_STAGE_STATE];
-   BOOL light_state[HIGHEST_LIGHT_STATE];
+   BOOL texture_stage_state[MAX_TEXTURES][HIGHEST_TEXTURE_STAGE_STATE];
 } STATEBLOCKFLAGS;
 
 typedef struct STATEBLOCK {
    STATEBLOCKFLAGS set_flags; 
    DWORD render_state[HIGHEST_RENDER_STATE];
-   DWORD texture_stage_state[8][HIGHEST_TEXTURE_STAGE_STATE];
-   DWORD light_state[HIGHEST_LIGHT_STATE];
+   DWORD texture_stage_state[MAX_TEXTURES][HIGHEST_TEXTURE_STAGE_STATE];
 } STATEBLOCK;
 
 /*****************************************************************************
@@ -187,9 +187,6 @@
 /*****************************************************************************
  * IDirect3DDevice implementation structure
  */
-
-#define MAX_TEXTURES 8
-#define MAX_LIGHTS  16
 
 #define WORLDMAT_CHANGED (0x00000001 << 0)
 #define VIEWMAT_CHANGED  (0x00000001 << 1)
--- ../wine_base/dlls/ddraw/d3dexecutebuffer.c	Sun Jan  5 23:58:59 2003
+++ dlls/ddraw/d3dexecutebuffer.c	Mon Jan  6 20:59:15 2003
@@ -185,7 +185,6 @@
 		    IDirect3DDeviceImpl *lpDevice,
 		    IDirect3DViewportImpl *lpViewport)
 {
-    IDirect3DDeviceGLImpl* lpDeviceGL = (IDirect3DDeviceGLImpl*) lpDevice;
     /* DWORD bs = This->desc.dwBufferSize; */
     DWORD vs = This->data.dwVertexOffset;
     /* DWORD vc = This->data.dwVertexCount; */
@@ -439,8 +438,10 @@
 		for (i = 0; i < count; i++) {
 		    LPD3DSTATE ci = (LPD3DSTATE) instr;
 		    
-		    /* Handle the state transform */
-		    set_render_state(lpDeviceGL, ci->u1.drstRenderStateType, ci->u2.dwArg[0]);
+		    LEAVE_GL();
+		    IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(lpDevice, IDirect3DDevice7),
+						    ci->u1.drstRenderStateType, ci->u2.dwArg[0]);
+		    ENTER_GL();
 
 		    instr += size;
 		}
--- ../wine_base/dlls/ddraw/d3dtexture.c	Sun Jan  5 23:58:59 2003
+++ dlls/ddraw/d3dtexture.c	Mon Jan  6 20:59:15 2003
@@ -147,7 +147,7 @@
 	} else {
 	    DWORD i;
 	    BYTE *src = (BYTE *) src_d->lpSurface, *dst;
-	    
+
 	    surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
 	    dst = (BYTE *) surface;
 	    
--- ../wine_base/dlls/ddraw/mesa.c	Mon Jan  6 21:46:44 2003
+++ dlls/ddraw/mesa.c	Mon Jan  6 21:51:18 2003
@@ -62,10 +62,30 @@
     return GL_KEEP;
 }
 
-void set_render_state(IDirect3DDeviceGLImpl* This,
-		      D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState)
+GLenum convert_D3D_blendop_to_GL(D3DBLEND dwRenderState)
 {
-    RenderState* rs = &This->render_state;
+    switch ((D3DBLEND) dwRenderState) {
+        case D3DBLEND_ZERO: return GL_ZERO;
+        case D3DBLEND_ONE: return GL_ONE;
+	case D3DBLEND_SRCALPHA: return GL_SRC_ALPHA;
+	case D3DBLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA;
+	case D3DBLEND_DESTALPHA: return GL_DST_ALPHA;
+	case D3DBLEND_INVDESTALPHA: return GL_ONE_MINUS_DST_ALPHA;
+	case D3DBLEND_DESTCOLOR: return GL_DST_COLOR;
+	case D3DBLEND_INVDESTCOLOR: return GL_ONE_MINUS_DST_COLOR;
+	case D3DBLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE;
+	case D3DBLEND_SRCCOLOR: return GL_SRC_COLOR;
+	case D3DBLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR;
+        default: ERR("Unhandled blend mode %d !\n", dwRenderState); return GL_ZERO;
+    }
+}
+
+void set_render_state(IDirect3DDeviceImpl* This,
+		      D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock)
+{
+    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
+    DWORD dwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
+
     if (TRACE_ON(ddraw))
         TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
 
@@ -82,7 +102,7 @@
 	        IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
 		
 		LEAVE_GL();
-		IDirect3DDevice7_SetTexture(ICOM_INTERFACE(&(This->parent), IDirect3DDevice7),
+		IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
 					    0, 
 					    ICOM_INTERFACE(tex, IDirectDrawSurface7));
 		ENTER_GL();
@@ -91,19 +111,17 @@
 	    case D3DRENDERSTATE_TEXTUREADDRESSU:  /* 44 */
 	    case D3DRENDERSTATE_TEXTUREADDRESSV:  /* 45 */
 	    case D3DRENDERSTATE_TEXTUREADDRESS: { /*  3 */
-	        GLenum arg = GL_REPEAT; /* Default value */
-	        switch ((D3DTEXTUREADDRESS) dwRenderState) {
-		    case D3DTADDRESS_WRAP:   arg = GL_REPEAT; break;
-		    case D3DTADDRESS_CLAMP:  arg = GL_CLAMP; break;
-		    case D3DTADDRESS_BORDER: arg = GL_CLAMP_TO_EDGE; break;
-		    default: ERR("Unhandled TEXTUREADDRESS mode %ld !\n", dwRenderState);
-		}
-		if ((dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) ||
-		    (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS))
-		    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
-		if ((dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSV) ||
-		    (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS))
-		    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
+	        D3DTEXTURESTAGESTATETYPE d3dTexStageStateType;
+
+		if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) d3dTexStageStateType = D3DTSS_ADDRESS;
+		else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) d3dTexStageStateType = D3DTSS_ADDRESSU;
+		else d3dTexStageStateType = D3DTSS_ADDRESSV;
+
+		LEAVE_GL();
+		IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
+						      0, d3dTexStageStateType,
+						      dwRenderState);
+		ENTER_GL();
 	    } break;
 	      
 	    case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
@@ -181,113 +199,52 @@
 		    glDisable(GL_ALPHA_TEST);
 	        break;
 
-	    case D3DRENDERSTATE_TEXTUREMAG:       /* 17 */
+	    case D3DRENDERSTATE_TEXTUREMAG: {     /* 17 */
+	        DWORD tex_mag = 0xFFFFFFFF;
+
 	        switch ((D3DTEXTUREFILTER) dwRenderState) {
 		    case D3DFILTER_NEAREST:
-		        rs->mag = GL_NEAREST;
+		        tex_mag = D3DTFG_POINT;
 			break;
 		    case D3DFILTER_LINEAR:
-			rs->mag = GL_LINEAR;
+		        tex_mag = D3DTFG_LINEAR;
 			break;
 		    default:
 			ERR("Unhandled texture mag %ld !\n",dwRenderState);
 	        }
-	        break;
 
-	    case D3DRENDERSTATE_TEXTUREMIN:         /* 18 */
+		if (tex_mag != 0xFFFFFFFF) {
+		    LEAVE_GL();
+		    IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MAGFILTER, tex_mag);
+		    ENTER_GL();
+		}
+	    } break;
+
+	    case D3DRENDERSTATE_TEXTUREMIN: {       /* 18 */
+	        DWORD tex_min = 0xFFFFFFFF;
+
 	        switch ((D3DTEXTUREFILTER) dwRenderState) {
 		    case D3DFILTER_NEAREST:
-		        rs->min = GL_NEAREST;
+		        tex_min = D3DTFN_POINT;
 			break;
 		    case D3DFILTER_LINEAR:
-			rs->mag = GL_LINEAR;
+		        tex_min = D3DTFN_LINEAR;
 			break;
 		    default:
 			ERR("Unhandled texture min %ld !\n",dwRenderState);
-		}
-	        break;
+	        }
 
-	    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
-	        switch ((D3DBLEND) dwRenderState) {
-		    case D3DBLEND_ZERO:
-		          rs->src = GL_ZERO;
-			  break;
-		    case D3DBLEND_ONE:
-		          rs->src = GL_ONE;
-			  break;
-		    case D3DBLEND_SRCALPHA:
-		          rs->src = GL_SRC_ALPHA;
-			  break;
-		    case D3DBLEND_INVSRCALPHA:
-		          rs->src = GL_ONE_MINUS_SRC_ALPHA;
-			  break;
-		    case D3DBLEND_DESTALPHA:
-		          rs->src = GL_DST_ALPHA;
-			  break;
-		    case D3DBLEND_INVDESTALPHA:
-		          rs->src = GL_ONE_MINUS_DST_ALPHA;
-			  break;
-		    case D3DBLEND_DESTCOLOR:
-		          rs->src = GL_DST_COLOR;
-			  break;
-		    case D3DBLEND_INVDESTCOLOR:
-		          rs->src = GL_ONE_MINUS_DST_COLOR;
-			  break;
-		    case D3DBLEND_BOTHSRCALPHA:
-		          rs->src = GL_SRC_ALPHA;
-			  rs->dst = GL_SRC_ALPHA;
-			  break;
-		    case D3DBLEND_BOTHINVSRCALPHA:
-		          rs->src = GL_ONE_MINUS_SRC_ALPHA;
-			  rs->dst = GL_ONE_MINUS_SRC_ALPHA;
-			  break;
-		    case D3DBLEND_SRCALPHASAT:
-		          rs->src = GL_SRC_ALPHA_SATURATE;
-			  break;
-		    case D3DBLEND_SRCCOLOR:
-		    case D3DBLEND_INVSRCCOLOR:
-		          /* Cannot be supported with OpenGL */
-			  break;
-		    default:
-			  ERR("Unhandled src blend mode %ld !\n",dwRenderState);
+		if (tex_min != 0xFFFFFFFF) {
+		    LEAVE_GL();
+		    IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MINFILTER, tex_min);
+		    ENTER_GL();
 		}
-	        glBlendFunc(rs->src, rs->dst);
-	        break;
+	    } break;
 
+	    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
 	    case D3DRENDERSTATE_DESTBLEND:          /* 20 */
-	        switch ((D3DBLEND) dwRenderState) {
-		    case D3DBLEND_ZERO:
-		        rs->dst = GL_ZERO;
-			break;
-		    case D3DBLEND_ONE:
-		        rs->dst = GL_ONE;
-			break;
-		    case D3DBLEND_SRCCOLOR:
-		        rs->dst = GL_SRC_COLOR;
-			break;
-		    case D3DBLEND_INVSRCCOLOR:
-		        rs->dst = GL_ONE_MINUS_SRC_COLOR;
-			break;
-		    case D3DBLEND_SRCALPHA:
-		        rs->dst = GL_SRC_ALPHA;
-			break;
-		    case D3DBLEND_INVSRCALPHA:
-		        rs->dst = GL_ONE_MINUS_SRC_ALPHA;
-			break;
-		    case D3DBLEND_DESTALPHA:
-		        rs->dst = GL_DST_ALPHA;
-			break;
-		    case D3DBLEND_INVDESTALPHA:
-		        rs->dst = GL_ONE_MINUS_DST_ALPHA;
-			break;
-		    case D3DBLEND_DESTCOLOR:
-		    case D3DBLEND_INVDESTCOLOR:
-		        /* Cannot be supported with OpenGL */
-			break;
-		    default:
-			ERR("Unhandled dest blend mode %ld !\n",dwRenderState);
-		}
-	        glBlendFunc(rs->src, rs->dst);
+	        glBlendFunc(convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1]),
+			    convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1]));
 	        break;
 
 	    case D3DRENDERSTATE_TEXTUREMAPBLEND:    /* 21 */
@@ -297,7 +254,7 @@
 		        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 			break;
 		    default:
-			  ERR("Unhandled texture environment %ld !\n",dwRenderState);
+		        ERR("Unhandled texture environment %ld !\n",dwRenderState);
 		}
 	        break;
 
@@ -306,7 +263,6 @@
 		    case D3DCULL_NONE:
 		         glDisable(GL_CULL_FACE);
 			 break;
-			 /* Not sure about these... The DirectX doc is, well, pretty unclear :-) */
 		    case D3DCULL_CW:
 			 glEnable(GL_CULL_FACE);
 			 glFrontFace(GL_CCW);
@@ -327,13 +283,9 @@
 	        break;
 	      
 	    case D3DRENDERSTATE_ALPHAREF:   /* 24 */
-	        rs->alpha_ref = dwRenderState / 255.0;
-	        glAlphaFunc(rs->alpha_func, rs->alpha_ref);
-	        break;
-	      
-	    case D3DRENDERSTATE_ALPHAFUNC: /* 25 */
-	        rs->alpha_func = convert_D3D_compare_to_GL(dwRenderState);
-	        glAlphaFunc(rs->alpha_func, rs->alpha_ref);
+	    case D3DRENDERSTATE_ALPHAFUNC:  /* 25 */
+	        glAlphaFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_ALPHAFUNC - 1]),
+			    (lpStateBlock->render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) / 255.0);
 	        break;
 
 	    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
@@ -346,20 +298,17 @@
 	    case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
 	        if (dwRenderState) {
 		    glEnable(GL_BLEND);
-		    rs->alpha_blend_enable = TRUE;
 		} else {
 		    glDisable(GL_BLEND);
-		    rs->alpha_blend_enable = FALSE;
 		}
 	        break;
 	      
 	    case D3DRENDERSTATE_FOGENABLE: /* 28 */
-	        if (dwRenderState) {
+	        if ((dwRenderState == TRUE) &&
+		    (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
 		    glEnable(GL_FOG);
-		    rs->fog_on = TRUE;
 		} else {
 		    glDisable(GL_FOG);
-		    rs->fog_on = FALSE;
 		}
 	        break;
 
@@ -415,57 +364,43 @@
 
 	    case D3DRENDERSTATE_STENCILENABLE:    /* 52 */
 	        if (dwRenderState)
-		    glDisable(GL_STENCIL_TEST);
+		    glEnable(GL_STENCIL_TEST);
 		else
 		    glDisable(GL_STENCIL_TEST);
 		break;
 	    
 	    case D3DRENDERSTATE_STENCILFAIL:      /* 53 */
-	        rs->stencil_fail = convert_D3D_stencilop_to_GL(dwRenderState);
-		glStencilOp(rs->stencil_fail, rs->stencil_zfail, rs->stencil_pass);
-		break;
-
 	    case D3DRENDERSTATE_STENCILZFAIL:     /* 54 */
-	        rs->stencil_zfail = convert_D3D_stencilop_to_GL(dwRenderState);
-		glStencilOp(rs->stencil_fail, rs->stencil_zfail, rs->stencil_pass);
-		break;
-
 	    case D3DRENDERSTATE_STENCILPASS:      /* 55 */
-	        rs->stencil_pass = convert_D3D_stencilop_to_GL(dwRenderState);
-		glStencilOp(rs->stencil_fail, rs->stencil_zfail, rs->stencil_pass);
+		glStencilOp(convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFAIL - 1]),
+			    convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILZFAIL - 1]),
+			    convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILPASS - 1]));
 		break;
 
 	    case D3DRENDERSTATE_STENCILFUNC:      /* 56 */
-	        rs->stencil_func = convert_D3D_compare_to_GL(dwRenderState);
-		glStencilFunc(rs->stencil_func, rs->stencil_ref, rs->stencil_mask);
-		break;
-
 	    case D3DRENDERSTATE_STENCILREF:       /* 57 */
-	        rs->stencil_ref = dwRenderState;
-		glStencilFunc(rs->stencil_func, rs->stencil_ref, rs->stencil_mask);
-		break;
-
 	    case D3DRENDERSTATE_STENCILMASK:      /* 58 */
-	        rs->stencil_mask = dwRenderState;
-		glStencilFunc(rs->stencil_func, rs->stencil_ref, rs->stencil_mask);
+		glStencilFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFUNC - 1]),
+			      lpStateBlock->render_state[D3DRENDERSTATE_STENCILREF - 1],
+			      lpStateBlock->render_state[D3DRENDERSTATE_STENCILMASK - 1]);
 		break;
 	  
 	    case D3DRENDERSTATE_STENCILWRITEMASK: /* 59 */
 	        glStencilMask(dwRenderState);
 	        break;
 
-	    case D3DRENDERSTATE_CLIPPING:    /* 136 */
-	    case D3DRENDERSTATE_CLIPPLANEENABLE: /*152*/
-		{
+	    case D3DRENDERSTATE_CLIPPING:          /* 136 */
+	    case D3DRENDERSTATE_CLIPPLANEENABLE: { /* 152 */
 		    GLint i;
 		    DWORD mask, runner;
 		    
-		    if (dwRenderStateType==D3DRENDERSTATE_CLIPPING) {
-			mask = ((dwRenderState)?(This->parent.state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE-1]):(0x0000));
+		    if (dwRenderStateType == D3DRENDERSTATE_CLIPPING) {
+			mask = ((dwRenderState) ?
+				(This->state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE - 1]) : (0x0000));
 		    } else {
 			mask = dwRenderState;
 		    }
-		    for (i = 0, runner = 1; i < This->parent.max_clipping_planes; i++, runner = (runner<<1)) {
+		    for (i = 0, runner = 0x00000001; i < This->max_clipping_planes; i++, runner = (runner << 1)) {
 			if (mask & runner) {
 			    glEnable(GL_CLIP_PLANE0 + i);
 			} else {
@@ -510,19 +445,10 @@
 		break;
 
 	    case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE:    /* 145 */
-	        rs->color_diffuse = dwRenderState;
-		break;
-
 	    case D3DRENDERSTATE_SPECULARMATERIALSOURCE:   /* 146 */
-	        rs->color_specular = dwRenderState;
-		break;
-
 	    case D3DRENDERSTATE_AMBIENTMATERIALSOURCE:    /* 147 */
-	        rs->color_ambient = dwRenderState;
-		break;
-
 	    case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE:   /* 148 */
-	        rs->color_emissive = dwRenderState;
+	        /* Nothing to do here. Only the storage matters :-) */
 		break;
 
 	    default:
@@ -532,26 +458,44 @@
     }
 }
 
-void store_render_state(D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState,
-		        STATEBLOCK* lpStateBlock)
+void store_render_state(IDirect3DDeviceImpl *This,
+			D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK *lpStateBlock)
 {
     TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
-    lpStateBlock->render_state[dwRenderStateType-1] = dwRenderState;
+    
+    /* Some special cases first.. */
+    if (dwRenderStateType == D3DRENDERSTATE_SRCBLEND) {
+        if (dwRenderState == D3DBLEND_BOTHSRCALPHA) {
+	    lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_SRCALPHA;
+	    lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_SRCALPHA;
+	    return;
+	} else if (dwRenderState == D3DBLEND_BOTHINVSRCALPHA) {
+	    lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_INVSRCALPHA;
+	    lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_INVSRCALPHA;
+	    return;
+	}
+    } else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) {
+        lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSU - 1] = dwRenderState;
+        lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSV - 1] = dwRenderState;
+    }
+    
+    /* Default case */
+    lpStateBlock->render_state[dwRenderStateType - 1] = dwRenderState;
 }
 
-void get_render_state(D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState,
-		      STATEBLOCK* lpStateBlock)
+void get_render_state(IDirect3DDeviceImpl *This,
+		      D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK *lpStateBlock)
 {
-    *lpdwRenderState = lpStateBlock->render_state[dwRenderStateType-1];
+    *lpdwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
     if (TRACE_ON(ddraw))
         TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
 }
 
-void apply_render_state(IDirect3DDeviceGLImpl* This, STATEBLOCK* lpStateBlock)
+void apply_render_state(IDirect3DDeviceImpl *This, STATEBLOCK *lpStateBlock)
 {
     DWORD i;
     TRACE("(%p,%p)\n", This, lpStateBlock);
-    for(i=0;i<HIGHEST_RENDER_STATE;i++)
+    for(i = 0; i < HIGHEST_RENDER_STATE; i++)
 	if (lpStateBlock->set_flags.render_state[i])
-            set_render_state(This, i+1, lpStateBlock->render_state[i]);    
+            set_render_state(This, i + 1, lpStateBlock);
 }
--- ../wine_base/dlls/ddraw/mesa_private.h	Sun Jan  5 23:58:59 2003
+++ dlls/ddraw/mesa_private.h	Mon Jan  6 20:59:15 2003
@@ -58,32 +58,6 @@
 
 extern const GUID IID_D3DDEVICE_OpenGL;
 
-typedef struct render_state {
-    /* This is used for the device mode */
-    GLenum src, dst;
-    /* This is used for textures */
-    GLenum mag, min;
-
-    /* This is needed for the Alpha stuff */
-    GLenum alpha_func;
-    GLclampf alpha_ref;
-    BOOLEAN alpha_blend_enable;
-
-    /* This is needed for the stencil stuff */
-    GLint stencil_ref;
-    GLuint stencil_mask;
-    GLenum stencil_func;
-    BOOLEAN stencil_enable;
-    GLenum stencil_fail, stencil_zfail, stencil_pass;
-  
-    /* This is needed for proper lighting */
-    BOOLEAN lighting_enable, specular_enable;
-    D3DMATERIALCOLORSOURCE color_diffuse, color_specular, color_ambient, color_emissive;
-
-    /* This is needed to re-enable fogging when XYZRHW and XYZ primitives are mixed */
-    BOOLEAN fog_on;
-} RenderState;
-
 typedef struct IDirect3DGLImpl
 {
     struct IDirect3DImpl parent;
@@ -127,9 +101,6 @@
     
     GLXContext gl_context;
 
-    /* The current render state */
-    RenderState render_state;
-
     /* The last type of vertex drawn */
     GL_TRANSFORM_STATE transform_state;
 
@@ -167,20 +138,17 @@
 /* Used to set-up our orthographic projection */
 extern void d3ddevice_set_ortho(IDirect3DDeviceImpl *This) ;
 
-/* Common functions defined in d3dcommon.c */
-void set_render_state(IDirect3DDeviceGLImpl* This,
-		      D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState);
-void store_render_state(D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState,
-		        STATEBLOCK* lpStateBlock);
-void get_render_state(D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState,
-		      STATEBLOCK* lpStateBlock);
-void apply_render_state(IDirect3DDeviceGLImpl* This, STATEBLOCK* lpStateBlock);
+/* Rendering state management functions */
+extern void set_render_state(IDirect3DDeviceImpl* This, D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock);
+extern void store_render_state(IDirect3DDeviceImpl *This, D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK* lpStateBlock);
+extern void get_render_state(IDirect3DDeviceImpl *This, D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK* lpStateBlock);
+extern void apply_render_state(IDirect3DDeviceImpl* This, STATEBLOCK* lpStateBlock);
 
 /* This structure contains all the function pointers to OpenGL extensions
    that are used by Wine */
 typedef struct {
-  void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
-			     GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+    void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
+			       GLsizei width, GLenum format, GLenum type, const GLvoid *table);
 } Mesa_DeviceCapabilities;
 
 #endif /* HAVE_OPENGL */
--- ../wine_base/dlls/ddraw/d3ddevice/main.c	Mon Jan  6 21:46:44 2003
+++ dlls/ddraw/d3ddevice/main.c	Mon Jan  6 21:46:55 2003
@@ -104,7 +104,7 @@
     D3DRENDERSTATE_WRAP6,                   0,
     D3DRENDERSTATE_WRAP7,                   0,
     D3DRENDERSTATE_CLIPPING,                FALSE,
-    D3DRENDERSTATE_LIGHTING,                FALSE, /* FIXME: Should be TRUE */
+    D3DRENDERSTATE_LIGHTING,                TRUE,
     D3DRENDERSTATE_EXTENTS,                 FALSE,
     D3DRENDERSTATE_AMBIENT,                 D3DRGBA(0,0,0,0),
     D3DRENDERSTATE_FOGVERTEXMODE,           D3DFOG_NONE,
@@ -160,42 +160,35 @@
 {
     int i,j;  
     TRACE("(%p,%d)\n", lpStateBlock, version);    
-    memset(lpStateBlock,0,sizeof(STATEBLOCK));
+    memset(lpStateBlock, 0, sizeof(STATEBLOCK));
     
     /* Initialize render states */
-    for(i=0;i<sizeof(InitRenderStateTab)/4;i+=2)
+    for(i = 0; i < sizeof(InitRenderStateTab) / sizeof(InitRenderStateTab[0]); i += 2)
     {
-        lpStateBlock->render_state[InitRenderStateTab[i]-1] = InitRenderStateTab[i+1];
-	lpStateBlock->set_flags.render_state[InitRenderStateTab[i]-1] = TRUE;
-    }
-
-    /* Initialize render states */
-    for(i=0;i<sizeof(InitLightStateTab)/4;i+=2)
-    {
-        lpStateBlock->light_state[InitLightStateTab[i]-1] = InitLightStateTab[i+1];
-	lpStateBlock->set_flags.light_state[InitLightStateTab[i]-1] = TRUE;
+        lpStateBlock->render_state[InitRenderStateTab[i] - 1] = InitRenderStateTab[i + 1];
+	lpStateBlock->set_flags.render_state[InitRenderStateTab[i] - 1] = TRUE;
     }
 
     /* Initialize texture stages states */
-    for(i=0;i<8;i++)
+    for(i = 0; i < MAX_TEXTURES; i++)
     {
-       for(j=0;j<sizeof(InitTextureStageStateTab)/4;j+=2)
+       for(j = 0; j < sizeof(InitTextureStageStateTab) / sizeof(InitTextureStageStateTab[0]); j += 2)
        {
-           lpStateBlock->texture_stage_state[i][InitTextureStageStateTab[j]-1] = InitTextureStageStateTab[j+1];
-           lpStateBlock->set_flags.texture_stage_state[i][InitTextureStageStateTab[j]-1] = TRUE;
+           lpStateBlock->texture_stage_state[i][InitTextureStageStateTab[j] - 1] = InitTextureStageStateTab[j + 1];
+           lpStateBlock->set_flags.texture_stage_state[i][InitTextureStageStateTab[j] - 1] = TRUE;
        }
        /* Map texture coords 0 to stage 0, 1 to stage 1, etc... */
-       lpStateBlock->texture_stage_state[i][D3DTSS_TEXCOORDINDEX-1] = i;
-       lpStateBlock->set_flags.texture_stage_state[i][D3DTSS_TEXCOORDINDEX-1] = TRUE;
+       lpStateBlock->texture_stage_state[i][D3DTSS_TEXCOORDINDEX - 1] = i;
+       lpStateBlock->set_flags.texture_stage_state[i][D3DTSS_TEXCOORDINDEX - 1] = TRUE;
     }
     
     /* The first texture is particular, update it consequently */
-    lpStateBlock->texture_stage_state[0][D3DTSS_COLOROP-1] = D3DTOP_MODULATE;
-    lpStateBlock->texture_stage_state[0][D3DTSS_ALPHAOP-1] = D3DTOP_SELECTARG1;
+    lpStateBlock->texture_stage_state[0][D3DTSS_COLOROP - 1] = D3DTOP_MODULATE;
+    lpStateBlock->texture_stage_state[0][D3DTSS_ALPHAOP - 1] = D3DTOP_SELECTARG1;
     
     /* Updates for particular versions */
-    if ((version == 1)||(version==2))
-       lpStateBlock->render_state[D3DRENDERSTATE_SPECULARENABLE-1] = TRUE;
+    if ((version == 1) || (version==2))
+       lpStateBlock->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] = TRUE;
 }
 
 HRESULT WINAPI
@@ -1112,12 +1105,8 @@
                                             LPDWORD lpdwLightState)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwLightStateType, lpdwLightState);
-    if (lpdwLightState && dwLightStateType && (dwLightStateType <= HIGHEST_LIGHT_STATE) ) {
-       *lpdwLightState = This->state_block.light_state[dwLightStateType-1];
-       return DD_OK;
-    }
-    return DDERR_INVALIDPARAMS;
+    FIXME("(%p/%p)->(%08x,%p): stub !\n", This, iface, dwLightStateType, lpdwLightState);
+    return DD_OK;
 }
 
 HRESULT WINAPI
--- ../wine_base/dlls/ddraw/d3ddevice/mesa.c	Mon Jan  6 21:46:44 2003
+++ dlls/ddraw/d3ddevice/mesa.c	Mon Jan  6 21:46:55 2003
@@ -539,12 +539,11 @@
 					      DWORD dwRenderState)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
     TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
 
     /* Call the render state functions */
-    set_render_state(glThis, dwRenderStateType, dwRenderState);
-    store_render_state(dwRenderStateType, dwRenderState, &glThis->parent.state_block);
+    store_render_state(This, dwRenderStateType, dwRenderState, &This->state_block);
+    set_render_state(This, dwRenderStateType, &This->state_block);
 
     return DD_OK;
 }
@@ -555,11 +554,12 @@
 					      LPDWORD lpdwRenderState)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
     TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwRenderStateType, lpdwRenderState);
 
     /* Call the render state functions */
-    get_render_state(dwRenderStateType, lpdwRenderState, &glThis->parent.state_block);
+    get_render_state(This, dwRenderStateType, lpdwRenderState, &This->state_block);
+
+    TRACE(" - asked for rendering state : %s, returning value %08lx.\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
 
     return DD_OK;
 }
@@ -570,7 +570,6 @@
 					  DWORD dwLightState)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
 
     TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
 
@@ -588,8 +587,9 @@
 	} break;
 
 	case D3DLIGHTSTATE_AMBIENT:     /* 2 */
-	    /* Call the render_state function... */
-	    set_render_state(glThis, D3DRENDERSTATE_AMBIENT, dwLightState);
+	    IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
+					    D3DRENDERSTATE_AMBIENT,
+					    dwLightState);
 	    break;
 
 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
@@ -605,8 +605,6 @@
 	    TRACE("Unexpected Light State Type\n");
 	    return DDERR_INVALIDPARAMS;
     }
-
-    This->state_block.light_state[dwLightStateType] = dwLightState;
     
     return DD_OK;
 }
@@ -665,7 +663,7 @@
 			   This->world_mat, This->view_mat, This->proj_mat);
 	glThis->transform_state = GL_TRANSFORM_NORMAL;
 
-	if (glThis->render_state.fog_on == TRUE)
+	if (This->state_block.render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE)
 	    glEnable(GL_FOG);
     } else if ((vertex_transformed == TRUE) &&
 	       (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
@@ -678,18 +676,18 @@
     }
 
     /* Handle the 'no-normal' case */
-    if (vertex_lit == FALSE)
+    if (vertex_lit == TRUE)
         glDisable(GL_LIGHTING);
-    else if (glThis->render_state.lighting_enable == TRUE)
+    else if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)
         glEnable(GL_LIGHTING);
 
     /* Handle the code for pre-vertex material properties */
     if (vertex_transformed == FALSE) {
-        if (glThis->render_state.lighting_enable == TRUE) {
-	    if ((glThis->render_state.color_diffuse != D3DMCS_MATERIAL) ||
-		(glThis->render_state.color_specular != D3DMCS_MATERIAL) ||
-		(glThis->render_state.color_ambient != D3DMCS_MATERIAL) ||
-		(glThis->render_state.color_emissive != D3DMCS_MATERIAL)) {
+        if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) {
+	    if ((This->state_block.render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
+		(This->state_block.render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
+		(This->state_block.render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
+		(This->state_block.render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] != D3DMCS_MATERIAL)) {
 	        glEnable(GL_COLOR_MATERIAL);
 	    }
 	}
@@ -824,8 +822,9 @@
     glNormal3fv(coords);
 }
 
-inline static void handle_diffuse_base(RenderState *rs, DWORD *color) {
-    if (rs->alpha_blend_enable == TRUE) {
+inline static void handle_diffuse_base(STATEBLOCK *sb, DWORD *color) {
+    if ((sb->render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1] == TRUE) ||
+	(sb->render_state[D3DRENDERSTATE_ALPHABLENDENABLE - 1] == TRUE)) {
         glColor4ub((*color >> 16) & 0xFF,
 		   (*color >>  8) & 0xFF,
 		   (*color >>  0) & 0xFF,
@@ -837,74 +836,78 @@
     }
 }
 
-inline static void handle_specular_base(RenderState *rs, DWORD *color) {
+inline static void handle_specular_base(STATEBLOCK *sb, DWORD *color) {
     glColor4ub((*color >> 16) & 0xFF,
 	       (*color >>  8) & 0xFF,
 	       (*color >>  0) & 0xFF,
 	       (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
 }
 
-inline static void handle_diffuse(RenderState *rs, DWORD *color) {
-    if (rs->lighting_enable == TRUE) {
-        if (rs->color_diffuse == D3DMCS_COLOR1) {
+inline static void handle_diffuse(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
+    if ((lighted == FALSE) &&
+	(sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)) {
+        if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
 	    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-	    handle_diffuse_base(rs, color);
+	    handle_diffuse_base(sb, color);
 	}
-	if (rs->color_ambient == D3DMCS_COLOR1) {
+	if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
 	    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
-	    handle_diffuse_base(rs, color);
+	    handle_diffuse_base(sb, color);
 	}
-	if ((rs->color_specular == D3DMCS_COLOR1) && (rs->specular_enable == TRUE)) {
+	if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR1) &&
+	    (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE)) {
 	    glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
-	    handle_diffuse_base(rs, color);
+	    handle_diffuse_base(sb, color);
 	}
-	if (rs->color_emissive == D3DMCS_COLOR1) {
+	if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
 	    glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
-	    handle_diffuse_base(rs, color);
+	    handle_diffuse_base(sb, color);
 	}
     } else {
-        handle_diffuse_base(rs, color);
+        handle_diffuse_base(sb, color);
     }    
 }
 
-inline static void handle_specular(RenderState *rs, DWORD *color) {
-    if (rs->lighting_enable == TRUE) {
-        if (rs->color_diffuse == D3DMCS_COLOR2) {
+inline static void handle_specular(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
+    if ((lighted == FALSE) &&
+	(sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)) {
+        if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
 	    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-	    handle_specular(rs, color);
+	    handle_specular_base(sb, color);
 	}
-	if (rs->color_ambient == D3DMCS_COLOR2) {
+	if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
 	    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
-	    handle_specular(rs, color);
+	    handle_specular_base(sb, color);
 	}
-	if ((rs->color_specular == D3DMCS_COLOR2) && (rs->specular_enable == TRUE)) {
+	if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR2) &&
+	    (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE)) {
 	    glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
-	    handle_specular(rs, color);
+	    handle_specular_base(sb, color);
 	}
-	if (rs->color_emissive == D3DMCS_COLOR2) {
+	if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
 	    glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
-	    handle_specular(rs, color);
+	    handle_specular_base(sb, color);
 	}
     }
     /* No else here as we do not know how to handle 'specular' on its own in any case.. */
 }
 
-inline static void handle_diffuse_and_specular(RenderState *rs, DWORD *color_d, DWORD *color_s, BOOLEAN transformed) {
-    if (transformed == TRUE) {
-        if (rs->fog_on == TRUE) {
+inline static void handle_diffuse_and_specular(STATEBLOCK *sb, DWORD *color_d, DWORD *color_s, BOOLEAN lighted) {
+    if (lighted == TRUE) {
+        if (sb->render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE) {
 	    /* Special case where the specular value is used to do fogging. TODO */
 	}
-	if (rs->specular_enable == TRUE) {
+	if (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE) {
 	    /* Standard specular value in transformed mode. TODO */
 	}
-	handle_diffuse_base(rs, color_d);
+	handle_diffuse_base(sb, color_d);
     } else {
-        if (rs->lighting_enable == TRUE) {
-	    handle_diffuse(rs, color_d);
-	    handle_specular(rs, color_s);
+        if (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) {
+	    handle_diffuse(sb, color_d, FALSE);
+	    handle_specular(sb, color_s, FALSE);
 	} else {
 	    /* In that case, only put the diffuse color... */
-	    handle_diffuse_base(rs, color_d);	  
+	    handle_diffuse_base(sb, color_d);
 	}
     }
 }
@@ -927,7 +930,8 @@
 				   DWORD dwIndexCount,
 				   DWORD dwFlags)
 {
-    IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
+    BOOLEAN vertex_lighted = (d3dvtVertexType & D3DFVF_NORMAL) == 0;
+  
     if (TRACE_ON(ddraw)) {
         TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
     }
@@ -935,7 +939,7 @@
     ENTER_GL();
     draw_primitive_handle_GL_state(This,
 				   (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
-				   (d3dvtVertexType & D3DFVF_NORMAL) == 0);
+				   vertex_lighted);
     draw_primitive_start_GL(d3dptPrimitiveType);
 
     /* Some fast paths first before the generic case.... */
@@ -974,7 +978,7 @@
 	    D3DVALUE *position =
 	      (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
 
-	    handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, TRUE);
+	    handle_diffuse_and_specular(&(This->state_block), color_d, color_s, TRUE);
 	    handle_texture(tex_coord);
 	    handle_xyzrhw(position);
 
@@ -1009,16 +1013,16 @@
 		  (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
 		DWORD *color_s = 
 		  (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
-		handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, (d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW);
+		handle_diffuse_and_specular(&(This->state_block), color_d, color_s, vertex_lighted);
 	    } else {
 	        if (d3dvtVertexType & D3DFVF_SPECULAR) { 
 		    DWORD *color_s = 
 		      (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
-		    handle_specular(&(glThis->render_state), color_s);
+		    handle_specular(&(This->state_block), color_s, vertex_lighted);
 		} else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
 		    DWORD *color_d = 
 		      (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
-		    handle_diffuse(&(glThis->render_state), color_d);
+		    handle_diffuse(&(This->state_block), color_d, vertex_lighted);
 		}
 	    }
 		
@@ -1264,6 +1268,44 @@
     return DD_OK;
 }
 
+static GLenum
+convert_min_filter_to_GL(D3DTEXTUREMINFILTER dwState)
+{
+    GLenum gl_state;
+
+    switch (dwState) {
+        case D3DTFN_POINT:
+	    gl_state = GL_NEAREST;
+	    break;
+        case D3DTFN_LINEAR:
+	    gl_state = GL_LINEAR;
+	    break;
+        default:
+	    gl_state = GL_LINEAR;
+	    break;
+    }
+    return gl_state;
+}
+
+static GLenum
+convert_mag_filter_to_GL(D3DTEXTUREMAGFILTER dwState)
+{
+    GLenum gl_state;
+
+    switch (dwState) {
+        case D3DTFG_POINT:
+	    gl_state = GL_NEAREST;
+	    break;
+        case D3DTFG_LINEAR:
+	    gl_state = GL_LINEAR;
+	    break;
+        default:
+	    gl_state = GL_LINEAR;
+	    break;
+    }
+    return gl_state;
+}
+
 HRESULT WINAPI
 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
 						 DWORD dwStage,
@@ -1271,11 +1313,11 @@
 						 DWORD dwState)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-    GLenum gl_state;
     
     TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
 
+    if (dwStage > 0) return DD_OK; /* We nothing in this case for now */
+
     if (TRACE_ON(ddraw)) {
         TRACE(" Stage type is : ");
 	switch (d3dTexStageStateType) {
@@ -1312,41 +1354,25 @@
 
     switch (d3dTexStageStateType) {
         case D3DTSS_MINFILTER:
-            switch ((D3DTEXTUREMINFILTER) dwState) {
-	        case D3DTFN_POINT:
-	            if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
-		    gl_state = GL_NEAREST;
-		    break;
-		case D3DTFN_LINEAR:
-	            if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
-		    gl_state = GL_LINEAR;
-		    break;
-		default:
-		    if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
-		    gl_state = GL_LINEAR;
-		    break;
+	    if (TRACE_ON(ddraw)) {
+	        switch ((D3DTEXTUREMINFILTER) dwState) {
+	            case D3DTFN_POINT:  DPRINTF("D3DTFN_POINT\n"); break;
+		    case D3DTFN_LINEAR: DPRINTF("D3DTFN_LINEAR\n"); break;
+		    default: DPRINTF(" state unhandled (%ld).\n", dwState); break;
+		}
 	    }
-	    glThis->render_state.min = gl_state;
-	    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
+	    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert_min_filter_to_GL(dwState));
             break;
 	    
         case D3DTSS_MAGFILTER:
-            switch ((D3DTEXTUREMAGFILTER) dwState) {
-	        case D3DTFG_POINT:
-	            if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
-		    gl_state = GL_NEAREST;
-		    break;
-		case D3DTFG_LINEAR:
-	            if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
-		    gl_state = GL_LINEAR;
-		    break;
-		default:
-		    if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
-		    gl_state = GL_LINEAR;
-		    break;
+	    if (TRACE_ON(ddraw)) {
+	        switch ((D3DTEXTUREMAGFILTER) dwState) {
+	            case D3DTFG_POINT:  DPRINTF("D3DTFN_POINT\n"); break;
+		    case D3DTFG_LINEAR: DPRINTF("D3DTFN_LINEAR\n"); break;
+		    default: DPRINTF(" state unhandled (%ld).\n", dwState); break;
+		}
 	    }
-	    glThis->render_state.mag = gl_state;
-	    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
+	    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert_mag_filter_to_GL(dwState));
             break;
 
         case D3DTSS_ADDRESS:
@@ -1371,8 +1397,13 @@
 	    if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
     }
    
-    This->state_block.texture_stage_state[dwStage][d3dTexStageStateType-1] = dwState;
-    
+    This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1] = dwState;
+    /* Some special cases when one state modifies more than one... */
+    if (d3dTexStageStateType == D3DTSS_ADDRESS) {
+        This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1] = dwState;
+	This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1] = dwState;
+    }
+
     return DD_OK;
 }
 
@@ -1382,10 +1413,11 @@
 				       LPDIRECTDRAWSURFACE7 lpTexture2)
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
     
     TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
     
+    if (dwStage > 0) return DD_OK;
+
     if (This->current_texture[dwStage] != NULL) {
 	IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7));
     }
@@ -1406,8 +1438,10 @@
         glEnable(GL_TEXTURE_2D);
 	gltex_upload_texture(tex_impl);
 
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glThis->render_state.mag);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glThis->render_state.min);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
+			convert_mag_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MAGFILTER - 1]));
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+			convert_min_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MINFILTER - 1]));
     }
     LEAVE_GL();
     
@@ -2139,13 +2173,6 @@
 	surf->d3ddevice = object;
     }
 
-    /* FIXME: These 4 statements are kept for compatibility but should be removed as soon
-       as they are correctly handled */
-    gl_object->render_state.fog_on = FALSE;
-    gl_object->render_state.stencil_enable = FALSE;
-    gl_object->render_state.lighting_enable = FALSE;
-    gl_object->render_state.specular_enable = FALSE;
-
     /* Set the various light parameters */
     for (light = 0; light < MAX_LIGHTS; light++) {
         /* Only set the fields that are not zero-created */
@@ -2203,9 +2230,9 @@
     object->d3d->added_device(object->d3d, object);
 
     /* FIXME: Should handle other versions than just 7 */
-    InitDefaultStateBlock(&object->state_block,7);
+    InitDefaultStateBlock(&object->state_block, 7);
     /* Apply default render state values */
-    apply_render_state(gl_object, &object->state_block);
+    apply_render_state(object, &object->state_block);
     /* FIXME: do something similar for ligh_state and texture_stage_state */
 
     return DD_OK;


More information about the wine-patches mailing list