From 4b445124d36d051c15ec7910c9e414085aa2e62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Wed, 14 Mar 2007 18:04:56 +0100 Subject: [PATCH] direct3d: Add a fixed function fog test. --- dlls/d3d8/tests/visual.c | 135 +++++++++++++++++++++++++++++++++++++ dlls/d3d9/tests/visual.c | 137 ++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/visual.c | 128 +++++++++++++++++++++++++++++++++++ dlls/wined3d/state.c | 25 +++++-- 4 files changed, 421 insertions(+), 4 deletions(-) diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c index 961cab002e4..b8833f29523 100644 --- a/dlls/d3d8/tests/visual.c +++ b/dlls/d3d8/tests/visual.c @@ -307,6 +307,140 @@ static void clear_test(IDirect3DDevice8 *device) ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color); } +struct sVertex { + float x, y, z; + DWORD diffuse; + DWORD specular; +}; + +struct sVertexT { + float x, y, z, rhw; + DWORD diffuse; + DWORD specular; +}; + +static void fog_test(IDirect3DDevice8 *device) +{ + HRESULT hr; + DWORD color; + float start = 0.0, end = 1.0; + + /* Gets full z based fog with linear fog, no fog with specular color */ + struct sVertex unstransformed_1[] = { + {-1, -1, 0.1, 0xFFFF0000, 0xFF000000 }, + {-1, 0, 0.1, 0xFFFF0000, 0xFF000000 }, + { 0, 0, 0.1, 0xFFFF0000, 0xFF000000 }, + { 0, -1, 0.1, 0xFFFF0000, 0xFF000000 }, + }; + /* Ok, I am too lazy to deal with transform matrices */ + struct sVertex unstransformed_2[] = { + {-1, 0, 1.0, 0xFFFF0000, 0xFF000000 }, + {-1, 1, 1.0, 0xFFFF0000, 0xFF000000 }, + { 0, 1, 1.0, 0xFFFF0000, 0xFF000000 }, + { 0, 0, 1.0, 0xFFFF0000, 0xFF000000 }, + }; + /* Untransformed ones. Give them a different diffuse color to make the test look + * nicer. It also makes making sure that they are drawn correctly easier. + */ + struct sVertexT transformed_1[] = { + {320, 0, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 0, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {320, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + }; + struct sVertexT transformed_2[] = { + {320, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 480, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {320, 480, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + }; + WORD Indices[] = {0, 1, 2, 2, 3, 0}; + + hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0); + ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %s\n", DXGetErrorString8(hr)); + + /* Setup initial states: No lighting, fog on, fog color */ + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE); + ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString8(hr)); + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE); + ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString8(hr)); + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */); + ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString8(hr)); + + /* First test: Both table fog and vertex fog off */ + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE); + ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString8(hr)); + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE); + ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString8(hr)); + + /* Start = 0, end = 1. Should be default, but set them */ + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start)); + ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString8(hr)); + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end)); + ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString8(hr)); + + if(IDirect3DDevice8_BeginScene(device) == D3D_OK) + { + hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR); + ok( hr == D3D_OK, "SetVertexShader returned %s\n", DXGetErrorString8(hr)); + /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */ + hr = IDirect3DDevice8_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", DXGetErrorString8(hr)); + + /* That makes it use the Z value */ + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); + ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString8(hr)); + /* Untransformed, vertex fog != none (or table fog != none): + * Use the Z value as input into the equation + */ + hr = IDirect3DDevice8_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", DXGetErrorString8(hr)); + + /* transformed verts */ + hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR); + ok( hr == D3D_OK, "SetVertexShader returned %s\n", DXGetErrorString8(hr)); + /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */ + hr = IDirect3DDevice8_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", DXGetErrorString8(hr)); + + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); + ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString8(hr)); + /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog + * equation + */ + hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */, + 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, + sizeof(transformed_2[0])); + + hr = IDirect3DDevice8_EndScene(device); + ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString8(hr)); + } + else + { + ok(FALSE, "BeginScene failed\n"); + } + + IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL); + color = getPixelColor(device, 160, 360); + ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color); + color = getPixelColor(device, 160, 120); + ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color); + color = getPixelColor(device, 480, 120); + ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color); + color = getPixelColor(device, 480, 360); + ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color); + + /* Turn off the fog master switch to avoid confusing other tests */ + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE); + ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString8(hr)); +} + START_TEST(visual) { IDirect3DDevice8 *device_ptr; @@ -357,6 +491,7 @@ START_TEST(visual) /* Now run the real test */ lighting_test(device_ptr); clear_test(device_ptr); + fog_test(device_ptr); cleanup: if(device_ptr) IDirect3DDevice8_Release(device_ptr); diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index d1d39b125b3..67729dbc62b 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -412,6 +412,142 @@ static void test_mova(IDirect3DDevice9 *device) IDirect3DVertexShader9_Release(mova_shader); } +struct sVertex { + float x, y, z; + DWORD diffuse; + DWORD specular; +}; + +struct sVertexT { + float x, y, z, rhw; + DWORD diffuse; + DWORD specular; +}; + +static void fog_test(IDirect3DDevice9 *device) +{ + HRESULT hr; + DWORD color; + float start = 0.0, end = 1.0; + + /* Gets full z based fog with linear fog, no fog with specular color */ + struct sVertex unstransformed_1[] = { + {-1, -1, 0.1, 0xFFFF0000, 0xFF000000 }, + {-1, 0, 0.1, 0xFFFF0000, 0xFF000000 }, + { 0, 0, 0.1, 0xFFFF0000, 0xFF000000 }, + { 0, -1, 0.1, 0xFFFF0000, 0xFF000000 }, + }; + /* Ok, I am too lazy to deal with transform matrices */ + struct sVertex unstransformed_2[] = { + {-1, 0, 1.0, 0xFFFF0000, 0xFF000000 }, + {-1, 1, 1.0, 0xFFFF0000, 0xFF000000 }, + { 0, 1, 1.0, 0xFFFF0000, 0xFF000000 }, + { 0, 0, 1.0, 0xFFFF0000, 0xFF000000 }, + }; + /* Untransformed ones. Give them a different diffuse color to make the test look + * nicer. It also makes making sure that they are drawn correctly easier. + */ + struct sVertexT transformed_1[] = { + {320, 0, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 0, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {320, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + }; + struct sVertexT transformed_2[] = { + {320, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 480, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {320, 480, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + }; + WORD Indices[] = {0, 1, 2, 2, 3, 0}; + + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0); + ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr)); + + /* Setup initial states: No lighting, fog on, fog color */ + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE); + ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr)); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE); + ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr)); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */); + ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr)); + + /* First test: Both table fog and vertex fog off */ + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE); + ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr)); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE); + ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr)); + + /* Start = 0, end = 1. Should be default, but set them */ + 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)); + + if(IDirect3DDevice9_BeginScene(device) == D3D_OK) + { + hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR); + ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr)); + /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */ + 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)); + + /* That makes it use the Z value */ + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); + ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr)); + /* Untransformed, vertex fog != none (or table fog != none): + * Use the Z value as input into the equation + */ + 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)); + + /* transformed verts */ + 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_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); + ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr)); + /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog + * equation + */ + hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */, + 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, + sizeof(transformed_2[0])); + + 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 == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color); + color = getPixelColor(device, 160, 120); + ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color); + color = getPixelColor(device, 480, 120); + ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color); + color = getPixelColor(device, 480, 360); + ok(color == 0x0000FF00, "Transformed vertex with linear table 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)); + + IDirect3DDevice9_SetVertexDeclaration(device, NULL); +} + START_TEST(visual) { IDirect3DDevice9 *device_ptr; @@ -465,6 +601,7 @@ START_TEST(visual) /* Now execute the real tests */ lighting_test(device_ptr); clear_test(device_ptr); + fog_test(device_ptr); if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0)) { diff --git a/dlls/ddraw/tests/visual.c b/dlls/ddraw/tests/visual.c index f79586cd187..e970a9f989e 100644 --- a/dlls/ddraw/tests/visual.c +++ b/dlls/ddraw/tests/visual.c @@ -347,6 +347,133 @@ static void clear_test(IDirect3DDevice7 *device) ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color); } +struct sVertex { + float x, y, z; + DWORD diffuse; + DWORD specular; +}; + +struct sVertexT { + float x, y, z, rhw; + DWORD diffuse; + DWORD specular; +}; + +static void fog_test(IDirect3DDevice7 *device) +{ + HRESULT hr; + DWORD color; + float start = 0.0, end = 1.0; + + /* Gets full z based fog with linear fog, no fog with specular color */ + struct sVertex unstransformed_1[] = { + {-1, -1, 0.1, 0xFFFF0000, 0xFF000000 }, + {-1, 0, 0.1, 0xFFFF0000, 0xFF000000 }, + { 0, 0, 0.1, 0xFFFF0000, 0xFF000000 }, + { 0, -1, 0.1, 0xFFFF0000, 0xFF000000 }, + }; + /* Ok, I am too lazy to deal with transform matrices */ + struct sVertex unstransformed_2[] = { + {-1, 0, 1.0, 0xFFFF0000, 0xFF000000 }, + {-1, 1, 1.0, 0xFFFF0000, 0xFF000000 }, + { 0, 1, 1.0, 0xFFFF0000, 0xFF000000 }, + { 0, 0, 1.0, 0xFFFF0000, 0xFF000000 }, + }; + /* Untransformed ones. Give them a different diffuse color to make the test look + * nicer. It also makes making sure that they are drawn correctly easier. + */ + struct sVertexT transformed_1[] = { + {320, 0, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 0, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {320, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + }; + struct sVertexT transformed_2[] = { + {320, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 240, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {640, 480, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + {320, 480, 1.0, 1.0, 0xFFFFFF00, 0xFF000000 }, + }; + WORD Indices[] = {0, 1, 2, 2, 3, 0}; + + hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0); + ok(hr == D3D_OK, "IDirect3DDevice7_Clear returned %08x\n", hr); + + /* Setup initial states: No lighting, fog on, fog color */ + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE); + ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, TRUE); + ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGCOLOR, 0xFF00FF00 /* A nice green */); + ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr); + + /* First test: Both table fog and vertex fog off */ + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE); + ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE); + ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr); + + /* Start = 0, end = 1. Should be default, but set them */ + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGSTART, *((DWORD *) &start)); + ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGEND, *((DWORD *) &end)); + ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr); + + if(IDirect3DDevice7_BeginScene(device) == D3D_OK) + { + /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */ + hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + unstransformed_1, 4, Indices, 6, 0); + ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr); + + /* That makes it use the Z value */ + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR); + ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr); + /* Untransformed, vertex fog != none (or table fog != none): + * Use the Z value as input into the equation + */ + hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + unstransformed_2, 4, Indices, 6, 0); + ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr); + + /* transformed verts */ + ok( hr == D3D_OK, "SetFVF returned %08x\n", hr); + /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */ + hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + transformed_1, 4, Indices, 6, 0); + ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr); + + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR); + ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr); + /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog + * equation + */ + hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, + transformed_2, 4, Indices, 6, 0); + ok(hr == D3D_OK, "DrawIndexedPrimitive returned %08x\n", hr); + + hr = IDirect3DDevice7_EndScene(device); + ok(hr == D3D_OK, "EndScene returned %08x\n", hr); + } + else + { + ok(FALSE, "BeginScene failed\n"); + } + + color = getPixelColor(device, 160, 360); + ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color); + color = getPixelColor(device, 160, 120); + ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color); + color = getPixelColor(device, 480, 120); + ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color); + color = getPixelColor(device, 480, 360); + ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color); + + /* Turn off the fog master switch to avoid confusing other tests */ + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE); + ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr); +} + START_TEST(visual) { HRESULT hr; @@ -389,6 +516,7 @@ START_TEST(visual) /* Now run the tests */ lighting_test(Direct3DDevice); clear_test(Direct3DDevice); + fog_test(Direct3DDevice); cleanup: releaseObjects(); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 9bb34a00034..2a567b8ccc1 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -708,7 +708,26 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND]; fogend = tmpvalue.f; - /* Activate when vertex shaders are in the state table */ + /* Fog Rules: + * + * With fixed function vertex processing, Direct3D knows 2 different fog input sources. + * It can use the Z value of the vertex, or the alpha component of the specular color. + * This depends on the fog vertex, fog table and the vertex declaration. If the Z value + * is used, fogstart, fogend and the equation type are used, otherwise linear fog with + * start = 255, end = 0 is used. Obviously the msdn is not very clear on that. + * + * FOGTABLEMODE != NONE: + * The Z value is used, with the equation specified, no matter what vertex type. + * + * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed: + * Per vertex fog is calculated using the specified fog equation and the parameters + * + * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR + * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed: + * Linear fog with start = 255.0, end = 0.0, input comes from the specular color + * + * Vertex shaders work in a simmilar way, but need more testing + */ if (use_vs(stateblock->wineD3DDevice) && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog) { glFogi(GL_FOG_MODE, GL_LINEAR); @@ -728,9 +747,7 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo context->last_was_foggy_shader = FALSE; switch (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 - */ + /* If processed vertices are used, fall through to the NONE case */ case WINED3DFOG_EXP: { if(!context->last_was_rhw) { glFogi(GL_FOG_MODE, GL_EXP);