[dx72] Color tracking fixes

Ann and Jason Edmeades us at the-edmeades.demon.co.uk
Sat Aug 2 15:57:11 CDT 2003


Hello

This is the 'proper' fix for the white ship in Unreal2. The problem is
that no diffuse color is supplied during the draw, and hence the diffuse
color should default to white (the line I commented out before).
However, in the case when there is no supplied diffuse, then the
material tracking options (ie EMISSIVEMATERIALSOURCE type) normally
default back to material, and the material in U2 is given colors.

Note the GL spec states that the changes to the material made by glColor
are permanent, so we need to reapply the material colors before doing a
draw in the cases where the last draw may have changed them

Phew... I think I have it right, but feel free to tell me I am wrong.

Changelog
glColorMaterial enable/disable setup is only done when really necessary
If glColorMaterial is set to track current color and none is supplied,
it gets disabled
glMaterial is reset when I think it is necessary
Slow mode now has defaults for when fvf parms are not supplied (as per
fast mode)
Slow mode now sets up the specular color (forgot that bit previously, I
think!)
Trace now lists the front, back and stencil buffers for ease of
debugging

Jason
-------------- next part --------------
? dlls/d3d8/dx70
? dlls/d3d8/wip
Index: dlls/d3d8/d3d8_private.h
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/d3d8_private.h,v
retrieving revision 1.41
diff -u -r1.41 d3d8_private.h
--- dlls/d3d8/d3d8_private.h	19 Jul 2003 03:02:42 -0000	1.41
+++ dlls/d3d8/d3d8_private.h	2 Aug 2003 20:06:08 -0000
@@ -330,7 +330,12 @@
     BOOL                          proj_valid;
     BOOL                          view_ident;        /* true iff view matrix is identity                */
     BOOL                          last_was_rhw;      /* true iff last draw_primitive was in xyzrhw mode */
-
+    GLenum                        tracking_parm;     /* Which source is tracking current colour         */
+    LONG                          tracking_color;    /* used iff GL_COLOR_MATERIAL was enabled          */
+      #define                         DISABLED_TRACKING  0  /* Disabled                                 */
+      #define                         IS_TRACKING        1  /* tracking_parm is tracking diffuse color  */
+      #define                         NEEDS_TRACKING     2  /* Tracking needs to be enabled when needed */
+      #define                         NEEDS_DISABLE      3  /* Tracking needs to be disabled when needed*/
 
     /* OpenGL related */
     GLXContext                    glCtx;
Index: dlls/d3d8/device.c
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/device.c,v
retrieving revision 1.76
diff -u -r1.76 device.c
--- dlls/d3d8/device.c	19 Jul 2003 03:02:42 -0000	1.76
+++ dlls/d3d8/device.c	2 Aug 2003 20:06:15 -0000
@@ -2402,9 +2402,6 @@
             GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
 
             if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
-                glEnable(GL_COLOR_MATERIAL);
-                checkGLcall("glEnable GL_COLOR_MATERIAL");
-
                 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
                       This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
                       This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE],
@@ -2428,17 +2425,14 @@
                 }
 
                 if (Parm == -1) {
-                    glDisable(GL_COLOR_MATERIAL);
-                    checkGLcall("glDisable GL_COLOR_MATERIAL");
+                    if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE;
                 } else {
-                    TRACE("glColorMaterial Parm=%d\n", Parm);
-                    glColorMaterial(GL_FRONT_AND_BACK, Parm);
-                    checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
+                    This->tracking_color = NEEDS_TRACKING;
+                    This->tracking_parm  = Parm;
                 }
 
             } else {
-                glDisable(GL_COLOR_MATERIAL);
-                checkGLcall("glDisable GL_COLOR_MATERIAL");
+                if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE;
             }
         }
         break; 
Index: dlls/d3d8/directx.c
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/directx.c,v
retrieving revision 1.45
diff -u -r1.45 directx.c
--- dlls/d3d8/directx.c	19 Jul 2003 03:02:42 -0000	1.45
+++ dlls/d3d8/directx.c	2 Aug 2003 20:06:17 -0000
@@ -1025,6 +1025,7 @@
     } else {
       object->depthStencilBuffer = NULL;
     }
+    TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer);
 
     /* init the default renderTarget management */
     object->drawable = object->win;
Index: dlls/d3d8/drawprim.c
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/drawprim.c,v
retrieving revision 1.7
diff -u -r1.7 drawprim.c
--- dlls/d3d8/drawprim.c	21 Jul 2003 20:01:23 -0000	1.7
+++ dlls/d3d8/drawprim.c	2 Aug 2003 20:06:19 -0000
@@ -158,6 +158,58 @@
     return NumVertexes;
 }
 
+/* Ensure the appropriate material states are set up - only change
+   state if really required                                        */
+void init_materials(LPDIRECT3DDEVICE8 iface, BOOL isDiffuseSupplied) {
+
+    BOOL requires_material_reset = FALSE;
+    ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+    if (This->tracking_color == NEEDS_TRACKING && isDiffuseSupplied == TRUE) {
+        /* If we have not set up the material color tracking, do it now as required */
+        glDisable(GL_COLOR_MATERIAL); /* Note: Man pages state must enable AFTER calling glColorMaterial! Required?*/
+        checkGLcall("glDisable GL_COLOR_MATERIAL");
+        TRACE("glColorMaterial Parm=%x\n", This->tracking_parm);
+        glColorMaterial(GL_FRONT_AND_BACK, This->tracking_parm);
+        checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
+        glEnable(GL_COLOR_MATERIAL); 
+        checkGLcall("glEnable GL_COLOR_MATERIAL");
+        This->tracking_color = IS_TRACKING;
+        requires_material_reset = TRUE; /* Restore material settings as will be used */
+
+    } else if ((This->tracking_color == IS_TRACKING && isDiffuseSupplied == FALSE) ||
+               (This->tracking_color == NEEDS_TRACKING && isDiffuseSupplied == FALSE)) {
+        /* If we are tracking the current color but one isnt supplied, dont! */
+        glDisable(GL_COLOR_MATERIAL);
+        checkGLcall("glDisable GL_COLOR_MATERIAL");
+        This->tracking_color = NEEDS_TRACKING;
+        requires_material_reset = TRUE; /* Restore material settings as will be used */
+
+    } else if (This->tracking_color == IS_TRACKING && isDiffuseSupplied == TRUE) {
+        /* No need to reset material colors since no change to gl_color_material */
+        requires_material_reset = FALSE;
+
+    } else if (This->tracking_color == NEEDS_DISABLE) {
+        glDisable(GL_COLOR_MATERIAL);
+        checkGLcall("glDisable GL_COLOR_MATERIAL");
+        This->tracking_color = DISABLED_TRACKING;
+        requires_material_reset = TRUE; /* Restore material settings as will be used */
+    }
+
+    /* Reset the material colors which may have been tracking the color*/
+    if (requires_material_reset == TRUE) {
+        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &This->StateBlock->material.Ambient);
+        checkGLcall("glMaterialfv");
+        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->StateBlock->material.Diffuse);
+        checkGLcall("glMaterialfv");
+        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->StateBlock->material.Specular);
+        checkGLcall("glMaterialfv");
+        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &This->StateBlock->material.Emissive);
+        checkGLcall("glMaterialfv");
+    }
+
+}
+
 /* Setup views - Transformed & lit if RHW, else untransformed.
        Only unlit if Normals are supplied                       
     Returns: Whether to restore lighting afterwards           */
@@ -679,6 +731,8 @@
 
         glDisableClientState(GL_COLOR_ARRAY);
         checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
+        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+        checkGLcall("glColor4f(1, 1, 1, 1)");
     }
 
     /* Specular Colour ------------------------------------------*/
@@ -1062,13 +1116,52 @@
                     ((diffuseColor >>  8) & 0xFF) / 255.0f,
                     ((diffuseColor >>  0) & 0xFF) / 255.0f, 
                     ((diffuseColor >> 24) & 0xFF) / 255.0f));
+        } else {
+            if (vx_index == 0) glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+        }
+
+#if 1
+        /* Specular ------------------------------- */
+        if (sd->u.s.diffuse.lpData != NULL) {
+            VTRACE(("glSecondaryColor4ub: r,g,b=%f,%f,%f\n", 
+                    ((specularColor >> 16) & 0xFF) / 255.0f, 
+                    ((specularColor >>  8) & 0xFF) / 255.0f,
+                    ((specularColor >>  0) & 0xFF) / 255.0f));
+#if defined(GL_VERSION_1_4)
+            glSecondaryColor3ub((specularColor >> 16) & 0xFF,
+                                (specularColor >>  8) & 0xFF,
+                                (specularColor >>  0) & 0xFF);
+#elif defined(GL_EXT_secondary_color)
+            if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+                GL_EXTCALL(glSecondaryColor3ubEXT)(
+                           (specularColor >> 16) & 0xFF,
+                           (specularColor >>  8) & 0xFF,
+                           (specularColor >>  0) & 0xFF);
+            }
+#else
+            /* Do not worry if specular colour missing and disable request */
+            VTRACE(("Specular color extensions not supplied\n"));
+#endif
+        } else {
+#if defined(GL_VERSION_1_4)
+            if (vx_index == 0) glSecondaryColor3f(0, 0, 0);
+#elif defined(GL_EXT_secondary_color)
+            if (vx_index == 0 && GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+                GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
+            }
+#else
+            /* Do not worry if specular colour missing and disable request */
+#endif
         }
+#endif
 
         /* Normal -------------------------------- */
         if (sd->u.s.normal.lpData != NULL) {
             VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
             glNormal3f(nx, ny, nz);
-        } 
+        } else {
+            if (vx_index == 0) glNormal3f(0, 0, 1);
+        }
         
         /* Position -------------------------------- */
         if (sd->u.s.position.lpData != NULL) {
@@ -1294,6 +1387,9 @@
         TRACE_STRIDED((&dataLocations), texCoords[6]);
         TRACE_STRIDED((&dataLocations), texCoords[7]);
     }
+
+    /* Now initialize the materials state */
+    init_materials(iface, (dataLocations.u.s.diffuse.lpData != NULL));
 
     /* Now draw the graphics to the screen */
     if  (useVertexShaderFunction == TRUE) {



More information about the wine-patches mailing list