Stefan Dösinger : wined3d: fogstart == fogend means full fog.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Aug 21 07:21:01 CDT 2007


Module: wine
Branch: master
Commit: 04d62b4322abfc11f726e6998217569e87c452cf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=04d62b4322abfc11f726e6998217569e87c452cf

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Mon Aug 13 23:19:37 2007 +0200

wined3d: fogstart == fogend means full fog.

---

 dlls/d3d9/tests/visual.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/state.c     |   35 +++++++++++++++++++----
 2 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 6807fc8..ed7266e 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -557,9 +557,77 @@ static void fog_test(IDirect3DDevice9 *device)
         trace("Info: Table fog not supported by this device\n");
     }
 
+    /* Now test the special case fogstart == fogend */
+    hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
+    ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
+
+    if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
+    {
+        start = 512;
+        end = 512;
+        hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
+        ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
+        hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
+        ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
+
+        hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
+        ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
+        hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
+        ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
+        hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
+        ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
+
+        /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
+         * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
+         * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
+         * The third transformed quad remains unfogged because the fogcoords are read from the specular
+         * color and has fixed fogstart and fogend.
+         */
+        hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
+                2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
+                sizeof(unstransformed_1[0]));
+        ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
+        hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
+                2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
+                sizeof(unstransformed_1[0]));
+        ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
+
+        hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
+        ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
+        /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
+        hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
+                2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
+                sizeof(transformed_1[0]));
+        ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
+
+        hr = IDirect3DDevice9_EndScene(device);
+        ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
+    }
+    else
+    {
+        ok(FALSE, "BeginScene failed\n");
+    }
+    IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+    color = getPixelColor(device, 160, 360);
+    ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
+    color = getPixelColor(device, 160, 120);
+    ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
+    color = getPixelColor(device, 480, 120);
+    ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
+
     /* Turn off the fog master switch to avoid confusing other tests */
     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
     ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
+    start = 0.0;
+    end = 1.0;
+    hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
+    ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
+    hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
+    ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
+    hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
+    ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
+    hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
+    ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
 }
 
 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 99fdfdc..be2f902 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -802,6 +802,11 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
             fogstart = 1.0;
             fogend = 0.0;
         }
+
+        if(GL_SUPPORT(EXT_FOG_COORD)) {
+            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
+            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
+        }
         context->last_was_foggy_shader = TRUE;
     }
     else if( use_ps(stateblock->wineD3DDevice) ) {
@@ -837,6 +842,11 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
                 break;
             default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
         }
+
+        if(GL_SUPPORT(EXT_FOG_COORD)) {
+            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
+            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
+        }
     }
     /* 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."
@@ -944,13 +954,26 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
         glEnable(GL_FOG);
         checkGLcall("glEnable GL_FOG");
 
-        glFogfv(GL_FOG_START, &fogstart);
-        checkGLcall("glFogf(GL_FOG_START, fogstart");
-        TRACE("Fog Start == %f\n", fogstart);
+        if(fogstart != fogend)
+        {
+            glFogfv(GL_FOG_START, &fogstart);
+            checkGLcall("glFogf(GL_FOG_START, fogstart");
+            TRACE("Fog Start == %f\n", fogstart);
+
+            glFogfv(GL_FOG_END, &fogend);
+            checkGLcall("glFogf(GL_FOG_END, fogend");
+            TRACE("Fog End == %f\n", fogend);
+        }
+        else
+        {
+            glFogf(GL_FOG_START, -1.0 / 0.0);
+            checkGLcall("glFogf(GL_FOG_START, fogstart");
+            TRACE("Fog Start == %f\n", fogstart);
 
-        glFogfv(GL_FOG_END, &fogend);
-        checkGLcall("glFogf(GL_FOG_END, fogend");
-        TRACE("Fog End == %f\n", fogend);
+            glFogf(GL_FOG_END, 0.0);
+            checkGLcall("glFogf(GL_FOG_END, fogend");
+            TRACE("Fog End == %f\n", fogend);
+        }
     } else {
         glDisable(GL_FOG);
         checkGLcall("glDisable GL_FOG");




More information about the wine-cvs mailing list