[PATCH] WineD3D: Split the remains of state_fog=0A=

Stefan Doesinger stefan at codeweavers.com
Mon Dec 15 19:37:36 CST 2008


=0A=
This patch separates the code in state_fog in 3 different parts:=0A=
=0A=
*) A vertex pipeline part that takes care of selecting the proper fog =
coordinate source(fragment=0A=
depth vs explicit fog coord)=0A=
=0A=
*) A fragment pipeline fog type part that takes care of selecting the =
proper fog formula(linear,=0A=
exp, exp2) and enabling/disabling fog.=0A=
=0A=
*) A fragment pipeline part that takes care of setting the linear fog =
fog start and fog end=0A=
parameters. This code interacts with the former parameter to properly =
select the fog start and=0A=
end in case a vertex shader or explicit fog coordinates are used=0A=
---=0A=
 dlls/wined3d/arb_program_shader.c    |   29 +++++=0A=
 dlls/wined3d/ati_fragment_shader.c   |    9 +-=0A=
 dlls/wined3d/nvidia_texture_shader.c |    5 +=0A=
 dlls/wined3d/state.c                 |  200 =
+++++++++++++++++++---------------=0A=
 dlls/wined3d/wined3d_private.h       |    9 ++=0A=
 5 files changed, 161 insertions(+), 91 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 270a912..7ff3cd4 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -3043,9 +3043,36 @@ static void fragment_prog_arbfp(DWORD state, =
IWineD3DStateBlockImpl *stateblock,=0A=
  * fragment_prog_arbfp function being called because FOGENABLE is =
dirty, which calls this function here=0A=
  */=0A=
 static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
+    enum fogsource new_source;=0A=
+=0A=
     if(!isStateDirty(context, STATE_PIXELSHADER)) {=0A=
         fragment_prog_arbfp(state, stateblock, context);=0A=
     }=0A=
+=0A=
+    if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return;=0A=
+=0A=
+    if(use_vs(stateblock)=0A=
+       && ((IWineD3DVertexShaderImpl =
*)stateblock->vertexShader)->baseShader.reg_maps.fog) {=0A=
+        if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] !=3D =
WINED3DFOG_NONE ) {=0A=
+            FIXME("vertex shader with table fog used\n");=0A=
+        }=0A=
+        context->last_was_foggy_shader =3D TRUE;=0A=
+        new_source =3D FOGSOURCE_VS;=0A=
+    } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] =3D=3D =
WINED3DFOG_NONE) {=0A=
+        context->last_was_foggy_shader =3D FALSE;=0A=
+        if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] =3D=3D =
WINED3DFOG_NONE || context->last_was_rhw) {=0A=
+            new_source =3D FOGSOURCE_COORD;=0A=
+        } else {=0A=
+            new_source =3D FOGSOURCE_FFP;=0A=
+        }=0A=
+    } else {=0A=
+        context->last_was_foggy_shader =3D FALSE;=0A=
+        new_source =3D FOGSOURCE_FFP;=0A=
+    }=0A=
+    if(new_source !=3D context->fog_source) {=0A=
+        context->fog_source =3D new_source;=0A=
+        state_fogstartend(STATE_RENDER(WINED3DRS_FOGSTART), stateblock, =
context);=0A=
+    }=0A=
 }=0A=
 =0A=
 static void textransform(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
@@ -3190,6 +3217,8 @@ static const struct StateEntryTemplate =
arbfp_fragmentstate_template[] =3D {=0A=
     { STATE_RENDER(WINED3DRS_FOGENABLE),                  { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog      =
   }, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog      =
   }, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog      =
   }, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGSTART),                   { =
STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend    =
   }, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGEND),                     { =
STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend    =
   }, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { =
STATE_PIXELSHADER,                                  fragment_prog_arbfp  =
   }, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { =
STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      =
}, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { =
STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    =
}, 0                               },=0A=
diff --git a/dlls/wined3d/ati_fragment_shader.c =
b/dlls/wined3d/ati_fragment_shader.c=0A=
index 7152a85..c01ec1a 100644=0A=
--- a/dlls/wined3d/ati_fragment_shader.c=0A=
+++ b/dlls/wined3d/ati_fragment_shader.c=0A=
@@ -909,8 +909,13 @@ static void atifs_apply_pixelshader(DWORD state, =
IWineD3DStateBlockImpl *statebl=0A=
 =0A=
 static const struct StateEntryTemplate atifs_fragmentstate_template[] =
=3D {=0A=
     {STATE_RENDER(WINED3DRS_TEXTUREFACTOR),               { =
STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              =
state_texfactor_atifs   }, 0                               },=0A=
-    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { =
STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      =
}, 0                               },=0A=
-    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { =
STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    =
}, 0                               },=0A=
+    {STATE_RENDER(WINED3DRS_FOGCOLOR),                    { =
STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor       =
   }, 0                               },=0A=
+    {STATE_RENDER(WINED3DRS_FOGDENSITY),                  { =
STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity     =
   }, 0                               },=0A=
+    {STATE_RENDER(WINED3DRS_FOGENABLE),                   { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart   =
   }, 0                               },=0A=
+    {STATE_RENDER(WINED3DRS_FOGTABLEMODE),                { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart   =
   }, 0                               },=0A=
+    {STATE_RENDER(WINED3DRS_FOGVERTEXMODE),               { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart   =
   }, 0                               },=0A=
+    {STATE_RENDER(WINED3DRS_FOGSTART),                    { =
STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend    =
   }, 0                               },=0A=
+    {STATE_RENDER(WINED3DRS_FOGEND),                      { =
STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend    =
   }, 0                               },=0A=
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),           { =
STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs     =
   }, 0                               },=0A=
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),         { =
STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs     =
   }, 0                               },=0A=
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),         { =
STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs     =
   }, 0                               },=0A=
diff --git a/dlls/wined3d/nvidia_texture_shader.c =
b/dlls/wined3d/nvidia_texture_shader.c=0A=
index bd7fc9d..fc727d6 100644=0A=
--- a/dlls/wined3d/nvidia_texture_shader.c=0A=
+++ b/dlls/wined3d/nvidia_texture_shader.c=0A=
@@ -794,6 +794,11 @@ static const struct StateEntryTemplate =
nvrc_fragmentstate_template[] =3D {=0A=
     { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { =
STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              nvrc_texfactor      =
}, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { =
STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      =
}, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { =
STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGSTART),                   { =
STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGEND),                     { =
STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   =
}, 0                               },=0A=
     { STATE_SAMPLER(0),                                   { =
STATE_SAMPLER(0),                                   nvts_texdim         =
}, NV_TEXTURE_SHADER2              },=0A=
     { STATE_SAMPLER(0),                                   { =
STATE_SAMPLER(0),                                   sampler_texdim      =
}, 0                               },=0A=
     { STATE_SAMPLER(1),                                   { =
STATE_SAMPLER(1),                                   nvts_texdim         =
}, NV_TEXTURE_SHADER2              },=0A=
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c=0A=
index 03cdaae..5beadbf 100644=0A=
--- a/dlls/wined3d/state.c=0A=
+++ b/dlls/wined3d/state.c=0A=
@@ -896,14 +896,91 @@ static void state_stencilwrite(DWORD state, =
IWineD3DStateBlockImpl *stateblock,=0A=
     checkGLcall("glStencilMask");=0A=
 }=0A=
 =0A=
-static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, =
WineD3DContext *context) {=0A=
-    float fogstart, fogend;=0A=
+static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
+    if (!stateblock->renderState[WINED3DRS_FOGENABLE]) return;=0A=
+=0A=
+    /* Table fog on: Never use fog coords, and use per-fragment fog */=0A=
+    if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] !=3D =
WINED3DFOG_NONE) {=0A=
+        glHint(GL_FOG_HINT, GL_NICEST);=0A=
+        if(context->fog_coord) {=0A=
+            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);=0A=
+            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
+            context->fog_coord =3D FALSE;=0A=
+        }=0A=
+        return;=0A=
+    }=0A=
+=0A=
+    /* Otherwise use per-vertex fog in any case */=0A=
+    glHint(GL_FOG_HINT, GL_FASTEST);=0A=
+=0A=
+    if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] =3D=3D =
WINED3DFOG_NONE || context->last_was_rhw) {=0A=
+        /* No fog at all, or transformed vertices: Use fog coord */=0A=
+        if(!context->fog_coord) {=0A=
+            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);=0A=
+            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FOG_COORDINATE_EXT)");=0A=
+            context->fog_coord =3D TRUE;=0A=
+        }=0A=
+    } else {=0A=
+        /* Otherwise, use the fragment depth */=0A=
+        if(context->fog_coord) {=0A=
+            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);=0A=
+            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
+            context->fog_coord =3D FALSE;=0A=
+        }=0A=
+    }=0A=
+}=0A=
 =0A=
+void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, =
WineD3DContext *context) {=0A=
+    float fogstart, fogend;=0A=
     union {=0A=
         DWORD d;=0A=
         float f;=0A=
     } tmpvalue;=0A=
 =0A=
+    switch(context->fog_source) {=0A=
+        case FOGSOURCE_VS:=0A=
+            fogstart =3D 1.0;=0A=
+            fogend =3D 0.0;=0A=
+            break;=0A=
+=0A=
+        case FOGSOURCE_COORD:=0A=
+            fogstart =3D 255.0;=0A=
+            fogend =3D 0.0;=0A=
+            break;=0A=
+=0A=
+        case FOGSOURCE_FFP:=0A=
+            tmpvalue.d =3D stateblock->renderState[WINED3DRS_FOGSTART];=0A=
+            fogstart =3D tmpvalue.f;=0A=
+            tmpvalue.d =3D stateblock->renderState[WINED3DRS_FOGEND];=0A=
+            fogend =3D tmpvalue.f;=0A=
+            /* In GL, fogstart =3D=3D fogend disables fog, in D3D =
everything's fogged.*/=0A=
+            if(fogstart =3D=3D fogend) {=0A=
+                fogstart =3D -1.0 / 0.0;=0A=
+                fogend =3D 0.0;=0A=
+            }=0A=
+            break;=0A=
+=0A=
+        default:=0A=
+            /* This should not happen.context->fog_source is set in =
wined3d, not the app.=0A=
+             * Still this is needed to make the compiler happy=0A=
+             */=0A=
+            ERR("Unexpected fog coordinate source\n");=0A=
+            fogstart =3D 0.0;=0A=
+            fogend =3D 0.0;=0A=
+    }=0A=
+=0A=
+    glFogf(GL_FOG_START, fogstart);=0A=
+    checkGLcall("glFogf(GL_FOG_START, fogstart)");=0A=
+    TRACE("Fog Start =3D=3D %f\n", fogstart);=0A=
+=0A=
+    glFogf(GL_FOG_END, fogend);=0A=
+    checkGLcall("glFogf(GL_FOG_END, fogend)");=0A=
+    TRACE("Fog End =3D=3D %f\n", fogend);=0A=
+}=0A=
+=0A=
+void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
+    enum fogsource new_source;=0A=
+=0A=
     if (!stateblock->renderState[WINED3DRS_FOGENABLE]) {=0A=
         /* No fog? Disable it, and we're done :-) */=0A=
         glDisable(GL_FOG);=0A=
@@ -911,11 +988,6 @@ static void state_fog(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DCo=0A=
         return;=0A=
     }=0A=
 =0A=
-    tmpvalue.d =3D stateblock->renderState[WINED3DRS_FOGSTART];=0A=
-    fogstart =3D tmpvalue.f;=0A=
-    tmpvalue.d =3D stateblock->renderState[WINED3DRS_FOGEND];=0A=
-    fogend =3D tmpvalue.f;=0A=
-=0A=
     /* Fog Rules:=0A=
      *=0A=
      * With fixed function vertex processing, Direct3D knows 2 =
different fog input sources.=0A=
@@ -959,115 +1031,79 @@ static void state_fog(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DCo=0A=
             /* Set fog computation in the rasterizer to pass through =
the value (just blend it) */=0A=
             glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
             checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
-            fogstart =3D 1.0;=0A=
-            fogend =3D 0.0;=0A=
-        }=0A=
-=0A=
-        if(context->fog_coord) {=0A=
-            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);=0A=
-            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
-            context->fog_coord =3D FALSE;=0A=
         }=0A=
         context->last_was_foggy_shader =3D TRUE;=0A=
+        new_source =3D FOGSOURCE_VS;=0A=
     }=0A=
     /* DX 7 sdk: "If both render states(vertex and table fog) are set =
to valid modes,=0A=
      * the system will apply only pixel(=3Dtable) fog effects."=0A=
      */=0A=
     else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] =3D=3D =
WINED3DFOG_NONE) {=0A=
-        glHint(GL_FOG_HINT, GL_FASTEST);=0A=
-        checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");=0A=
         context->last_was_foggy_shader =3D FALSE;=0A=
 =0A=
         switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {=0A=
             /* If processed vertices are used, fall through to the NONE =
case */=0A=
-            case WINED3DFOG_EXP:  {=0A=
+            case WINED3DFOG_EXP:=0A=
                 if(!context->last_was_rhw) {=0A=
                     glFogi(GL_FOG_MODE, GL_EXP);=0A=
                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");=0A=
-                    if(context->fog_coord) {=0A=
-                        glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT);=0A=
-                        =
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
-                        context->fog_coord =3D FALSE;=0A=
-                    }=0A=
+                    new_source =3D FOGSOURCE_FFP;=0A=
                     break;=0A=
                 }=0A=
-            }=0A=
-            case WINED3DFOG_EXP2: {=0A=
+                /* drop through */=0A=
+=0A=
+            case WINED3DFOG_EXP2:=0A=
                 if(!context->last_was_rhw) {=0A=
                     glFogi(GL_FOG_MODE, GL_EXP2);=0A=
                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");=0A=
-                    if(context->fog_coord) {=0A=
-                        glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT);=0A=
-                        =
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
-                        context->fog_coord =3D FALSE;=0A=
-                    }=0A=
+                    new_source =3D FOGSOURCE_FFP;=0A=
                     break;=0A=
                 }=0A=
-            }=0A=
-            case WINED3DFOG_LINEAR: {=0A=
+                /* drop through */=0A=
+=0A=
+            case WINED3DFOG_LINEAR:=0A=
                 if(!context->last_was_rhw) {=0A=
                     glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
-                    if(context->fog_coord) {=0A=
-                        glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT);=0A=
-                        =
checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
-                        context->fog_coord =3D FALSE;=0A=
-                    }=0A=
+                    new_source =3D FOGSOURCE_FFP;=0A=
                     break;=0A=
                 }=0A=
-            }=0A=
-            case WINED3DFOG_NONE: {=0A=
+                /* drop through */=0A=
+=0A=
+            case WINED3DFOG_NONE:=0A=
                 /* Both are none? According to msdn the alpha channel =
of the specular=0A=
                  * color contains a fog factor. Set it in =
drawStridedSlow.=0A=
                  * Same happens with Vertexfog on transformed vertices=0A=
                  */=0A=
-                if(context->fog_coord =3D=3D FALSE) {=0A=
-                    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FOG_COORDINATE_EXT);=0A=
-                    checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FOG_COORDINATE_EXT)");=0A=
-                    context->fog_coord =3D TRUE;=0A=
-                }=0A=
+                new_source =3D FOGSOURCE_COORD;=0A=
                 glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
                 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
-                fogstart =3D 0xff;=0A=
-                fogend =3D 0x0;=0A=
                 break;=0A=
-            }=0A=
-            default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", =
stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);=0A=
+=0A=
+            default:=0A=
+                FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", =
stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);=0A=
+                new_source =3D FOGSOURCE_FFP; /* Make the compiler =
happy */=0A=
         }=0A=
     } else {=0A=
         glHint(GL_FOG_HINT, GL_NICEST);=0A=
         checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");=0A=
         context->last_was_foggy_shader =3D FALSE;=0A=
+        new_source =3D FOGSOURCE_FFP;=0A=
 =0A=
         switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {=0A=
             case WINED3DFOG_EXP:=0A=
                 glFogi(GL_FOG_MODE, GL_EXP);=0A=
                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");=0A=
-                if(context->fog_coord) {=0A=
-                    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT);=0A=
-                    checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
-                    context->fog_coord =3D FALSE;=0A=
-                }=0A=
                 break;=0A=
 =0A=
             case WINED3DFOG_EXP2:=0A=
                 glFogi(GL_FOG_MODE, GL_EXP2);=0A=
                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");=0A=
-                if(context->fog_coord) {=0A=
-                    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT);=0A=
-                    checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
-                    context->fog_coord =3D FALSE;=0A=
-                }=0A=
                 break;=0A=
 =0A=
             case WINED3DFOG_LINEAR:=0A=
                 glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
                 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
-                if(context->fog_coord) {=0A=
-                    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT);=0A=
-                    checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, =
GL_FRAGMENT_DEPTH_EXT)");=0A=
-                    context->fog_coord =3D FALSE;=0A=
-                }=0A=
                 break;=0A=
 =0A=
             case WINED3DFOG_NONE:   /* Won't happen */=0A=
@@ -1078,26 +1114,9 @@ static void state_fog(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DCo=0A=
 =0A=
     glEnable(GL_FOG);=0A=
     checkGLcall("glEnable GL_FOG");=0A=
-=0A=
-    if(fogstart !=3D fogend)=0A=
-    {=0A=
-        glFogfv(GL_FOG_START, &fogstart);=0A=
-        checkGLcall("glFogf(GL_FOG_START, fogstart)");=0A=
-        TRACE("Fog Start =3D=3D %f\n", fogstart);=0A=
-=0A=
-        glFogfv(GL_FOG_END, &fogend);=0A=
-        checkGLcall("glFogf(GL_FOG_END, fogend)");=0A=
-        TRACE("Fog End =3D=3D %f\n", fogend);=0A=
-    }=0A=
-    else=0A=
-    {=0A=
-        glFogf(GL_FOG_START, -1.0 / 0.0);=0A=
-        checkGLcall("glFogf(GL_FOG_START, fogstart)");=0A=
-        TRACE("Fog Start =3D=3D %f\n", fogstart);=0A=
-=0A=
-        glFogf(GL_FOG_END, 0.0);=0A=
-        checkGLcall("glFogf(GL_FOG_END, fogend)");=0A=
-        TRACE("Fog End =3D=3D %f\n", fogend);=0A=
+    if(new_source !=3D context->fog_source) {=0A=
+        context->fog_source =3D new_source;=0A=
+        state_fogstartend(STATE_RENDER(WINED3DRS_FOGSTART), stateblock, =
context);=0A=
     }=0A=
 }=0A=
 =0A=
@@ -4444,7 +4463,7 @@ static void vertexdeclaration(DWORD state, =
IWineD3DStateBlockImpl *stateblock, W=0A=
     context->last_was_vshader =3D useVertexShaderFunction;=0A=
 =0A=
     if(updateFog) {=0A=
-        state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, =
context);=0A=
+        =
device->StateTable[STATE_RENDER(WINED3DRS_FOGVERTEXMODE)].apply(STATE_REN=
DER(WINED3DRS_FOGVERTEXMODE), stateblock, context);=0A=
     }=0A=
     if(!useVertexShaderFunction) {=0A=
         int i;=0A=
@@ -5160,11 +5179,9 @@ const struct StateEntryTemplate =
ffp_vertexstate_template[] =3D {=0A=
     { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    { =
STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      =
}, 0                               },=0A=
     { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    { =
STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      =
}, 0                               },=0A=
       /* Fog */=0A=
-    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           =
}, 0                               },=0A=
-    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           =
}, 0                               },=0A=
-    { STATE_RENDER(WINED3DRS_FOGSTART),                   { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           =
}, 0                               },=0A=
-    { STATE_RENDER(WINED3DRS_FOGEND),                     { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           =
}, 0                               },=0A=
-    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  =
state_fog_vertexpart}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  =
state_fog_vertexpart}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  =
state_fog_vertexpart}, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { =
STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      =
}, NV_FOG_DISTANCE                 },=0A=
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { =
STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog_w    =
}, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_CLIPPING),                   { =
STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      =
}, 0                               },=0A=
@@ -5311,6 +5328,11 @@ static const struct StateEntryTemplate =
ffp_fragmentstate_template[] =3D {=0A=
     { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { =
STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     =
}, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { =
STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      =
}, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { =
STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGSTART),                   { =
STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   =
}, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_FOGEND),                     { =
STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   =
}, 0                               },=0A=
     { STATE_SAMPLER(0),                                   { =
STATE_SAMPLER(0),                                   sampler_texdim      =
}, 0                               },=0A=
     { STATE_SAMPLER(1),                                   { =
STATE_SAMPLER(1),                                   sampler_texdim      =
}, 0                               },=0A=
     { STATE_SAMPLER(2),                                   { =
STATE_SAMPLER(2),                                   sampler_texdim      =
}, 0                               },=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index 2cc6b23..9c83424 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -776,6 +776,12 @@ struct blit_shader {=0A=
 extern const struct blit_shader ffp_blit;=0A=
 extern const struct blit_shader arbfp_blit;=0A=
 =0A=
+enum fogsource {=0A=
+    FOGSOURCE_FFP,=0A=
+    FOGSOURCE_VS,=0A=
+    FOGSOURCE_COORD,=0A=
+};=0A=
+=0A=
 /* The new context manager that should deal with onscreen and offscreen =
rendering */=0A=
 struct WineD3DContext {=0A=
     /* State dirtification=0A=
@@ -812,6 +818,7 @@ struct WineD3DContext {=0A=
     GLenum                  tracking_parm;     /* Which source is =
tracking current colour         */=0A=
     GLenum                  untracked_materials[2];=0A=
     UINT                    blit_w, blit_h;=0A=
+    enum fogsource          fog_source;=0A=
 =0A=
     char                    *vshader_const_dirty, *pshader_const_dirty;=0A=
 =0A=
@@ -2023,6 +2030,8 @@ void tex_alphaop(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DContext=0A=
 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, =
WineD3DContext *context);=0A=
 void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, =
WineD3DContext *context);=0A=
 void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, =
WineD3DContext *context);=0A=
+void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, =
WineD3DContext *context);=0A=
+void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context);=0A=
 =0A=
 void surface_force_reload(IWineD3DSurface *iface);=0A=
 GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain =
*swapchain);=0A=
-- =0A=
1.6.0.6=0A=
=0A=

------=_NextPart_000_0017_01C97342.DD5F83F0--




More information about the wine-patches mailing list