This is another update of the fog patch, it makes the BOOL warned static.

ChangeLog:
Stefan Dösinger(for CodeWeavers): Correct vertex fog for transformed vertices 
and correctly handle non-vertex, non-table fog
From nobody Mon Sep 17 00:00:00 2001
From: Stefan Dösinger <[EMAIL PROTECTED]>
Date: Mon Jun 12 13:20:28 2006 +0200
Subject: [PATCH] WineD3D: Fog fixes

---

 dlls/wined3d/device.c     |  137 ++++++++++++++++++++++++++++++++++-----------
 dlls/wined3d/drawprim.c   |   58 +++++++++++++++++++
 include/wine/wined3d_gl.h |   11 ++++
 3 files changed, 172 insertions(+), 34 deletions(-)

e3ffbda48c4202d6f88ad24e0c34df84bf2a3b52
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a0b0522..8fb2d58 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3767,7 +3767,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
 
     case WINED3DRS_FOGENABLE                 :
         {
-          if (Value/* && This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] 
!= D3DFOG_NONE*/) {
+          if (Value) {
                glEnable(GL_FOG);
                checkGLcall("glEnable GL_FOG");
             } else {
@@ -3798,45 +3798,116 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         break;
 
     case WINED3DRS_FOGTABLEMODE              :
-        {
-          glHint(GL_FOG_HINT, GL_NICEST);
-          switch (Value) {
-          case D3DFOG_NONE: {
-              if(This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == 
D3DFOG_NONE) {
-                  glFogi(GL_FOG_MODE, GL_LINEAR); 
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
-              }
-              /* Otherwise leave the vertex fog value */
-              break;
-          }
-          case D3DFOG_EXP:     glFogi(GL_FOG_MODE, GL_EXP); 
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
-          case D3DFOG_EXP2:    glFogi(GL_FOG_MODE, GL_EXP2); 
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
-          case D3DFOG_LINEAR:  glFogi(GL_FOG_MODE, GL_LINEAR); 
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
-          default:
-            FIXME("Unsupported Value(%lu) for WINED3DRS_FOGTABLEMODE!\n", 
Value);
-          }
-          if (GL_SUPPORT(NV_FOG_DISTANCE)) {
-            glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
-          }
-        }
-        break;
-
     case WINED3DRS_FOGVERTEXMODE             :
         {
-          glHint(GL_FOG_HINT, GL_FASTEST);
           /* DX 7 sdk: "If both render states(vertex and table fog) are set to 
valid modes, the system will apply only pixel(=table) fog effects." */
           if(This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == 
D3DFOG_NONE) {
-              switch (Value) {
-              case D3DFOG_EXP:     glFogi(GL_FOG_MODE, GL_EXP); 
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
-              case D3DFOG_EXP2:    glFogi(GL_FOG_MODE, GL_EXP2); 
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
-              case D3DFOG_NONE:
-              case D3DFOG_LINEAR:  glFogi(GL_FOG_MODE, GL_LINEAR); 
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
-              default:
-                FIXME("Unsupported Value(%lu) for WINED3DRS_FOGTABLEMODE!\n", 
Value);
+              glHint(GL_FOG_HINT, GL_FASTEST);
+              checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
+              switch (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE]) {
+                  /* Processed vertices have their fog factor stored in the 
specular value. Fall too the none case.
+                   * If we are drawing untransformed vertices atm, 
d3ddevice_set_ortho will update the fog
+                   */
+                  case D3DFOG_EXP:  {
+                      if(!This->last_was_rhw) {
+                          glFogi(GL_FOG_MODE, GL_EXP);
+                          checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
+                          if(GL_SUPPORT(EXT_FOG_COORD)) {
+                              glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH);
+                              checkGLcall("glFogi(GL_FOG_COORD_SRC, 
GL_FRAGMENT_DEPTH");
+                              IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGSTART, This->stateBlock->renderState[WINED3DRS_FOGSTART]);
+                              IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGEND, This->stateBlock->renderState[WINED3DRS_FOGEND]);
+                          }
+                          break;
+                      }
+                  }
+                  case D3DFOG_EXP2: {
+                      if(!This->last_was_rhw) {
+                          glFogi(GL_FOG_MODE, GL_EXP2);
+                          checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
+                          if(GL_SUPPORT(EXT_FOG_COORD)) {
+                              glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH);
+                              checkGLcall("glFogi(GL_FOG_COORD_SRC, 
GL_FRAGMENT_DEPTH");
+                              IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGSTART, This->stateBlock->renderState[WINED3DRS_FOGSTART]);
+                              IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGEND, This->stateBlock->renderState[WINED3DRS_FOGEND]);
+                          }
+                          break;
+                      }
+                  }
+                  case D3DFOG_LINEAR: {
+                      if(!This->last_was_rhw) {
+                          glFogi(GL_FOG_MODE, GL_LINEAR);
+                          checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
+                          if(GL_SUPPORT(EXT_FOG_COORD)) {
+                              glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH);
+                              checkGLcall("glFogi(GL_FOG_COORD_SRC, 
GL_FRAGMENT_DEPTH");
+                              IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGSTART, This->stateBlock->renderState[WINED3DRS_FOGSTART]);
+                              IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGEND, This->stateBlock->renderState[WINED3DRS_FOGEND]);
+                          }
+                          break;
+                      }
+                  }
+                  case D3DFOG_NONE: {
+                      /* Both are none? According to msdn the alpha channel of 
the specular
+                       * color contains a fog factor. Set it in 
drawStridedSlow.
+                       * Same happens with Vertexfog on transformed vertices
+                       */
+                      if(GL_SUPPORT(EXT_FOG_COORD)) {
+                          glFogi(GL_FOG_COORD_SRC, GL_FOG_COORD);
+                          checkGLcall("glFogi(GL_FOG_COORD_SRC, 
GL_FOG_COORD)\n");
+                          glFogi(GL_FOG_MODE, GL_LINEAR);
+                          checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
+                          glFogf(GL_FOG_START, (float) 0xff);
+                          checkGLcall("glFogfv GL_FOG_START");
+                          glFogf(GL_FOG_END, 0.0);
+                          checkGLcall("glFogfv GL_FOG_END");
+                      } else {
+                          /* Disable GL fog, handle this in software in 
drawStridedSlow */
+                          glDisable(GL_FOG);
+                          checkGLcall("glDisable(GL_FOG)");
+                      }
+                  break;
+                  }
+                  default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %ld\n", 
This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE]);
               }
-              if (GL_SUPPORT(NV_FOG_DISTANCE)) {
-                glFogi(GL_FOG_DISTANCE_MODE_NV, 
This->stateBlock->renderState[WINED3DRS_RANGEFOGENABLE] ? GL_EYE_RADIAL_NV : 
GL_EYE_PLANE_ABSOLUTE_NV);
+          } else {
+              glHint(GL_FOG_HINT, GL_NICEST);
+              checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
+              switch (This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE]) {
+                  case D3DFOG_EXP:    glFogi(GL_FOG_MODE, GL_EXP);
+                                      checkGLcall("glFogi(GL_FOG_MODE, 
GL_EXP");
+                                      if(GL_SUPPORT(EXT_FOG_COORD)) {
+                                          glFogi(GL_FOG_COORD_SRC, 
GL_FRAGMENT_DEPTH);
+                                          
checkGLcall("glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH");
+                                          IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGSTART, This->stateBlock->renderState[WINED3DRS_FOGSTART]);
+                                          IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGEND, This->stateBlock->renderState[WINED3DRS_FOGEND]);
+                                      }
+                                      break;
+                  case D3DFOG_EXP2:   glFogi(GL_FOG_MODE, GL_EXP2);
+                                      checkGLcall("glFogi(GL_FOG_MODE, 
GL_EXP2");
+                                      if(GL_SUPPORT(EXT_FOG_COORD)) {
+                                          glFogi(GL_FOG_COORD_SRC, 
GL_FRAGMENT_DEPTH);
+                                          
checkGLcall("glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH");
+                                          IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGSTART, This->stateBlock->renderState[WINED3DRS_FOGSTART]);
+                                          IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGEND, This->stateBlock->renderState[WINED3DRS_FOGEND]);
+                                      }
+                                      break;
+                  case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR);
+                                      checkGLcall("glFogi(GL_FOG_MODE, 
GL_LINEAR");
+                                      if(GL_SUPPORT(EXT_FOG_COORD)) {
+                                          glFogi(GL_FOG_COORD_SRC, 
GL_FRAGMENT_DEPTH);
+                                          
checkGLcall("glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH");
+                                          IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGSTART, This->stateBlock->renderState[WINED3DRS_FOGSTART]);
+                                          IWineD3DDevice_SetRenderState(iface, 
WINED3DRS_FOGEND, This->stateBlock->renderState[WINED3DRS_FOGEND]);
+                                      }
+                                      break;
+                  case D3DFOG_NONE:   /* Won't happen */
+                  default:            FIXME("Unexpected WINED3DRS_FOGTABLEMODE 
%ld\n", This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE]);
               }
           }
+          if (GL_SUPPORT(NV_FOG_DISTANCE)) {
+            glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
+          }
         }
         break;
 
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 0164339..087b1d0 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -218,8 +218,30 @@ void d3ddevice_set_ortho(IWineD3DDeviceI
             glMultMatrixf(invymat);
             checkGLcall("glMultMatrixf(invymat)");
         }
-    }
 
+        /* Vertex fog on transformed vertices? Use the calculated fog factor 
stored in the specular color */
+        if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] && 
This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] != D3DFOG_NONE) {
+            if(GL_SUPPORT(EXT_FOG_COORD)) {
+                glFogi(GL_FOG_COORD_SRC, GL_FOG_COORD);
+                checkGLcall("glFogi(GL_FOG_COORD_SRC, GL_FOG_COORD)");
+                glFogi(GL_FOG_MODE, GL_LINEAR);
+                checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
+                /* The dx fog range in this case is fixed to 0 - 255,
+                 * but in GL it still depends on the fog start and end 
(according to the ext)
+                 * Use this to turn around the fog as it's needed. That 
prevents some
+                 * calculations during drawing :-)
+                 */
+                glFogf(GL_FOG_START, (float) 0xff);
+                checkGLcall("glFogfv GL_FOG_END");
+                glFogf(GL_FOG_END, 0.0);
+                checkGLcall("glFogfv GL_FOG_START");
+            } else {
+                /* Disable GL fog, handle this in software in drawStridedSlow 
*/
+                glDisable(GL_FOG);
+                checkGLcall("glDisable(GL_FOG)");
+            }
+        }
+    }
 }
 /* Setup views - Transformed & lit if RHW, else untransformed.
        Only unlit if Normals are supplied
@@ -240,6 +262,7 @@ static BOOL primitiveInitState(IWineD3DD
 
     if (!useVS && vtx_transformed) {
         d3ddevice_set_ortho(This);
+
     } else {
 
         /* Untransformed, so relies on the view and projection matrices */
@@ -311,6 +334,23 @@ static BOOL primitiveInitState(IWineD3DD
             This->proj_valid = FALSE;
         }
         This->last_was_rhw = FALSE;
+
+        /* Restore fogging */
+        if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] && 
This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] != D3DFOG_NONE) {
+            if(GL_SUPPORT(EXT_FOG_COORD)) {
+                glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH);
+                checkGLcall("glFogi(GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH)\n");
+                /* Reapply the fog range */
+                IWineD3DDevice_SetRenderState(iface, WINED3DRS_FOGSTART, 
This->stateBlock->renderState[WINED3DRS_FOGSTART]);
+                IWineD3DDevice_SetRenderState(iface, WINED3DRS_FOGEND, 
This->stateBlock->renderState[WINED3DRS_FOGEND]);
+                /* Restore the fog mode */
+                IWineD3DDevice_SetRenderState(iface, WINED3DRS_FOGTABLEMODE, 
This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE]);
+            } else {
+                /* Enable GL_FOG again because we disabled it above */
+                glEnable(GL_FOG);
+                checkGLcall("glEnable(GL_FOG)");
+            }
+        }
     }
     return isLightingOn;
 }
@@ -1495,6 +1535,22 @@ static void drawStridedSlow(IWineD3DDevi
 
         /* Specular ------------------------------- */
         if (sd->u.s.specular.lpData != NULL) {
+            /* special case where the fog density is stored in the diffuse 
alpha channel */
+            if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
+              (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == 
D3DFOG_NONE || sd->u.s.position.dwType == D3DDECLTYPE_FLOAT4 )&&
+              This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == 
D3DFOG_NONE) {
+                if(GL_SUPPORT(EXT_FOG_COORD)) {
+                    GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
+                } else {
+                    static BOOL warned = FALSE;
+                    if(!warned) {
+                        /* TODO: Use the fog table code from old ddraw */
+                        FIXME("Implement fog for transformed vertices in 
software\n");
+                        warned = TRUE;
+                    }
+                }
+            }
+
             VTRACE(("glSecondaryColor4ub: r,g,b=%lu,%lu,%lu\n", 
                     D3DCOLOR_B_R(specularColor), 
                     D3DCOLOR_B_G(specularColor), 
diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h
index 50717fc..a865760 100644
--- a/include/wine/wined3d_gl.h
+++ b/include/wine/wined3d_gl.h
@@ -646,6 +646,12 @@ typedef GLvoid* (APIENTRY * PGLFNMAPBUFF
 typedef GLboolean (APIENTRY * PGLFNUNMAPBUFFERARBPROC) (GLenum target);
 typedef void (APIENTRY * PGLFNGETBUFFERPARAMETERIVARBPROC) (GLenum target, 
GLenum pname, GLint *params);
 typedef void (APIENTRY * PGLFNGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum 
pname, GLvoid* *params);
+/* GL_EXT_fog_coord */
+typedef void (APIENTRY * PGLFNGLFOGCOORDFEXTPROC) (GLfloat intesity);
+typedef void (APIENTRY * PGLFNGLFOGCOORDFVEXTPROC) (GLfloat intesity);
+typedef void (APIENTRY * PGLFNGLFOGCOORDDEXTPROC) (GLfloat intesity);
+typedef void (APIENTRY * PGLFNGLFOGCOORDDVEXTPROC) (GLfloat intesity);
+typedef void (APIENTRY * PGLFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei 
stride, GLvoid *data);
 /* GL_ARB_shader_objects (GLSL) */
 #ifndef GL_ARB_shader_objects
 #define GL_ARB_shader_objects 1
@@ -1424,6 +1430,11 @@ typedef enum _GL_SupportedExt {
     USE_GL_FUNC(PGLFNGETBUFFERPOINTERVARBPROC,       glGetBufferPointervARB); \
     /** EXT Extensions **/ \
     /* GL_EXT_fog_coord */ \
+    USE_GL_FUNC(PGLFNGLFOGCOORDFEXTPROC,                glFogCoordfEXT); \
+    USE_GL_FUNC(PGLFNGLFOGCOORDFVEXTPROC,               glFogCoordfvEXT); \
+    USE_GL_FUNC(PGLFNGLFOGCOORDDEXTPROC,                glFogCoorddEXT); \
+    USE_GL_FUNC(PGLFNGLFOGCOORDDVEXTPROC,               glFogCoordvEXT); \
+    USE_GL_FUNC(PGLFNGLFOGCOORDPOINTEREXTPROC,          glFogCoordPointerEXT); 
\
     /* GL_EXT_framebuffer_object */ \
     USE_GL_FUNC(PGLFNGLISRENDERBUFFEREXTPROC,          glIsRenderbufferEXT); \
     USE_GL_FUNC(PGLFNGLBINDRENDERBUFFEREXTPROC,        glBindRenderbufferEXT); 
\
-- 
1.2.4

Attachment: pgpkoQsU8CzGi.pgp
Description: PGP signature



Reply via email to