wined3d: Correctly display fog for right-handed projection matrix (try 6)
Joachim Priesner
joachim.priesner at web.de
Fri Oct 10 08:21:29 CDT 2014
When using a right-handed projection matrix, z coordinates of
transformed vertices may be negative. This is not considered
in the code generating the GLSL shader for fixed-function fog.
The patch fixes that and adds a test.
Tested on openSUSE 13.1 and Windows 8.1.
Try 6 that fixes the issues pointed out by Stefan Doesinger (many thanks
for the review).
NOTE: The ddraw visual test currently fails on Windows 8.
This failure is not caused by this patch.
---
dlls/d3d8/tests/visual.c | 274 ++++++++++++++++++++++++++++++++++++
dlls/d3d9/tests/visual.c | 336 +++++++++++++++++++++++++++++++++++++++++++++
dlls/ddraw/tests/visual.c | 81 +++++++++++
dlls/wined3d/glsl_shader.c | 2 +-
4 files changed, 692 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c
index ba73bb6..ce5e8ec 100644
--- a/dlls/d3d8/tests/visual.c
+++ b/dlls/d3d8/tests/visual.c
@@ -696,6 +696,279 @@ done:
DestroyWindow(window);
}
+/* This test tests fog in combination with a right-handed projection matrix. */
+static void fog_righthanded_test(void)
+{
+ /* Some color constants to make tests easier to read. */
+ enum
+ {
+ COLOR_FOG = 0xff00ff00,
+ COLOR_FOGGED = 0x0000ff00,
+ COLOR_UNFOGGED = 0x00ff0000,
+ COLOR_CLEAR = 0xffff00ff
+ };
+
+ /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8) */
+ DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
+ DWORD pixel_shader[2] = {0, 0};
+ IDirect3DDevice8 *device;
+ unsigned int i;
+ IDirect3D8 *d3d;
+ D3DCOLOR color;
+ ULONG refcount;
+ D3DCAPS8 caps;
+ HWND window;
+ HRESULT hr;
+ union
+ {
+ float f;
+ DWORD i;
+ } start, end;
+
+ /* For all vertex shaders the view matrix goes in registers c0...c3,
+ * the projection matrix goes in registers c4...c7. */
+
+ /* Basic vertex shader without fog computation ("non foggy") */
+ static const DWORD vertex_shader_code1[] =
+ {
+ 0xfffe0100, /* vs_1_0 */
+ /* output.Pos = mul(input.Pos, View) */
+ 0x00000009, 0x80010000, 0x90e40000, 0xa0e40000, /* dp4 r0.x, v0, c0 */
+ 0x00000009, 0x80020000, 0x90e40000, 0xa0e40001, /* dp4 r0.y, v0, c1 */
+ 0x00000009, 0x80040000, 0x90e40000, 0xa0e40002, /* dp4 r0.z, v0, c2 */
+ 0x00000009, 0x80080000, 0x90e40000, 0xa0e40003, /* dp4 r0.w, v0, c3 */
+ /* output.Pos = mul(output.Pos, Projection) */
+ 0x00000009, 0xc0010000, 0x80e40000, 0xa0e40004, /* dp4 oPos.x, r0, c4 */
+ 0x00000009, 0xc0020000, 0x80e40000, 0xa0e40005, /* dp4 oPos.y, r0, c5 */
+ 0x00000009, 0xc0040000, 0x80e40000, 0xa0e40006, /* dp4 oPos.z, r0, c6 */
+ 0x00000009, 0xc0080000, 0x80e40000, 0xa0e40007, /* dp4 oPos.w, r0, c7 */
+ /* output.Color = input.Color */
+ 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
+ 0x0000ffff, /* END */
+ };
+
+ /* Basic vertex shader with fog computation ("foggy").
+ * Using the vertex' x coordinate as fog coordinate so that all test cases that use vertex fog
+ * will have a gradient from fully fogged (green, left) to unfogged (red, right). */
+ static const DWORD vertex_shader_code2[] =
+ {
+ 0xfffe0100, /* vs_1_0 */
+ /* output.Pos = mul(input.Pos, View) */
+ 0x00000009, 0x80010000, 0x90e40000, 0xa0e40000, /* dp4 r0.x, v0, c0 */
+ 0x00000009, 0x80020000, 0x90e40000, 0xa0e40001, /* dp4 r0.y, v0, c1 */
+ 0x00000009, 0x80040000, 0x90e40000, 0xa0e40002, /* dp4 r0.z, v0, c2 */
+ 0x00000009, 0x80080000, 0x90e40000, 0xa0e40003, /* dp4 r0.w, v0, c3 */
+ /* output.Pos = mul(output.Pos, Projection) */
+ 0x00000009, 0xc0010000, 0x80e40000, 0xa0e40004, /* dp4 oPos.x, r0, c4 */
+ 0x00000009, 0xc0020000, 0x80e40000, 0xa0e40005, /* dp4 oPos.y, r0, c5 */
+ 0x00000009, 0xc0040000, 0x80e40000, 0xa0e40006, /* dp4 oPos.z, r0, c6 */
+ 0x00000009, 0xc0080000, 0x80e40000, 0xa0e40007, /* dp4 oPos.w, r0, c7 */
+ /* output.Color = input.Color */
+ 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
+ /* output.Fog = input.Pos.x */
+ 0x00000001, 0xc00f0001, 0x90000000, /* mov oFog, v0.x */
+ 0x0000ffff, /* END */
+ };
+
+ /* Basic pixel shader */
+ static const DWORD pixel_shader_code[] =
+ {
+ 0xffff0101, /* ps_1_1 */
+ 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
+ 0x0000ffff
+ };
+
+ static const struct
+ {
+ struct vec3 position;
+ DWORD diffuse;
+ }
+ quad[] =
+ {
+ {{-1.0f, -1.0f, 0.0f}, COLOR_UNFOGGED},
+ {{-1.0f, 1.0f, 0.0f}, COLOR_UNFOGGED},
+ {{ 1.0f, -1.0f, 1.0f}, COLOR_UNFOGGED},
+ {{ 1.0f, 1.0f, 1.0f}, COLOR_UNFOGGED},
+ };
+ static const DWORD vertex_decl[] =
+ {
+ D3DVSD_STREAM(0),
+ D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
+ D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
+ D3DVSD_END()
+ };
+ static const struct test_data_t
+ {
+ int vshader;
+ int pshader;
+ D3DFOGMODE vfog;
+ D3DFOGMODE tfog;
+ DWORD color_left;
+ DWORD color_right;
+ }
+ test_data[] =
+ {
+ /* Test data that uses z-based fog has a gradient UNFOGGED->FOGGED.
+ * Test data that uses a vertex shader has a gradient FOGGED->UNFOGGED
+ * (except for the vertex shader without fog computation, where the
+ * quad is completely fogged). */
+
+ /* No vertex shader */
+ {0, 0, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 0, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_UNFOGGED, COLOR_FOGGED},
+
+ /* Vertex shader without vertex fog computation */
+ {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 0, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_FOGGED},
+ {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_FOGGED},
+
+ /* Vertex shader with vertex fog computation */
+ {2, 0, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_UNFOGGED},
+ {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_UNFOGGED},
+ };
+ static const D3DMATRIX proj_mat =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, 0.0f, -0.0f, 1.0f
+ }}};
+ static const D3DMATRIX view_mat =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ }}};
+
+ window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 0, 0, 640, 480, NULL, NULL, NULL, NULL);
+ d3d = Direct3DCreate8(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+
+ hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+
+ if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
+ {
+ hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
+ ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
+ }
+ else
+ {
+ skip("No ps_1_1 support, skipping some fog tests.\n");
+ }
+
+ if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 0))
+ {
+ hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code1, &vertex_shader[1], 0);
+ ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code2, &vertex_shader[2], 0);
+ ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
+ }
+ else
+ {
+ skip("No vs_1_0 support, skipping some fog tests.\n");
+ }
+
+ start.f = 0.1f;
+ end.f = 0.9f;
+
+ /* Setup initial states: No depth test, no lighting, fog on, fog color */
+ hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
+ ok(SUCCEEDED(hr), "Turning off depth test failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+ ok(SUCCEEDED(hr), "Turning off lighting failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
+ ok(SUCCEEDED(hr), "Turning on fog calculations failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, COLOR_FOG);
+ ok(SUCCEEDED(hr), "Setting fog color failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
+ ok(SUCCEEDED(hr), "Setting fog start failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
+ ok(SUCCEEDED(hr), "Setting fog end failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
+ ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
+ hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &view_mat);
+ ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
+
+ /* Note: Shaders expect matrices in column-major form, so they have
+ * to be transposed if they are not symmetrical (which is the case at the moment). */
+ hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &view_mat, 4);
+ ok(SUCCEEDED(hr), "SetVertexShaderConstant (view matrix) failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_SetVertexShaderConstant(device, 4, &proj_mat, 4);
+ ok(SUCCEEDED(hr), "SetVertexShaderConstant (projection matrix) failed (%08x)\n", hr);
+
+ for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
+ {
+ if ((test_data[i].pshader != 0 && pixel_shader[test_data[i].pshader] == 0)
+ || (test_data[i].vshader != 0 && vertex_shader[test_data[i].vshader] == 0))
+ continue;
+
+ hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
+ ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
+ ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
+ ok(SUCCEEDED(hr), "Setting fog vertex mode to %d failed (%08x)\n", test_data[i].vfog, hr);
+ hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
+ ok(SUCCEEDED(hr), "Setting fog table mode to %d failed (%08x)\n", test_data[i].tfog, hr);
+
+ hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, COLOR_CLEAR, 1.0f, 0);
+ ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
+ hr = IDirect3DDevice8_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
+
+ /* Use 5% tolerance on the colors since there may be a gradient
+ * between left and right vertices. */
+ color = getPixelColor(device, 10, 240);
+ ok(color_match(color, test_data[i].color_left, 13),
+ "fog vs%i ps%i fvm%i ftm%i: got left color %08x, expected %08x+-5%%\n",
+ test_data[i].vshader, test_data[i].pshader, test_data[i].vfog,
+ test_data[i].tfog, color, test_data[i].color_left);
+ color = getPixelColor(device, 630, 240);
+ ok(color_match(color, test_data[i].color_right, 13),
+ "fog vs%i ps%i fvm%i ftm%i: got right color %08x, expected %08x+-5%%\n",
+ test_data[i].vshader, test_data[i].pshader, test_data[i].vfog,
+ test_data[i].tfog, color, test_data[i].color_right);
+
+ IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
+ }
+ for (i = 0; i < sizeof(vertex_shader)/sizeof(vertex_shader[0]); i++)
+ if (vertex_shader[i])
+ IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[i]);
+ for (i = 0; i < sizeof(pixel_shader)/sizeof(pixel_shader[0]); i++)
+ if (pixel_shader[i])
+ IDirect3DDevice8_DeletePixelShader(device, pixel_shader[i]);
+ refcount = IDirect3DDevice8_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+done:
+ IDirect3D8_Release(d3d);
+ DestroyWindow(window);
+}
+
/* This tests fog in combination with shaders.
* What's tested: linear fog (vertex and table) with pixel shader
* linear table fog with non foggy vertex shader
@@ -5092,6 +5365,7 @@ START_TEST(visual)
offscreen_test();
alpha_test();
test_scalar_instructions();
+ fog_righthanded_test();
fog_with_shader_test();
cnd_test();
p8_texture_test();
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 117c8eb..4964aa0 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -1825,6 +1825,341 @@ done:
DestroyWindow(window);
}
+/* This test tests fog in combination with a right-handed projection matrix. */
+static void fog_righthanded_test(void)
+{
+ /* Some color constants to make tests more easier to read. */
+ enum
+ {
+ COLOR_FOG = 0xff00ff00,
+ COLOR_FOGGED = 0x0000ff00,
+ COLOR_UNFOGGED = 0x00ff0000,
+ COLOR_CLEAR = 0xffff00ff
+ };
+
+ IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
+ IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
+ IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
+ IDirect3DDevice9 *device;
+ unsigned int i;
+ IDirect3D9 *d3d;
+ ULONG refcount;
+ D3DCAPS9 caps;
+ DWORD color;
+ HWND window;
+ HRESULT hr;
+ union
+ {
+ float f;
+ DWORD i;
+ } start, end;
+
+ /* For all vertex shaders the view matrix goes in registers c0...c3,
+ * the projection matrix goes in registers c4...c7. */
+
+ /* Basic vertex shader without fog computation ("non foggy") */
+ static const DWORD vertex_shader_code1[] =
+ {
+ 0xfffe0101, /* vs_1_1 */
+ 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
+ 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
+ /* output.Pos = mul(input.Pos, View) */
+ 0x00000009, 0x80010000, 0x90e40000, 0xa0e40000, /* dp4 r0.x, v0, c0 */
+ 0x00000009, 0x80020000, 0x90e40000, 0xa0e40001, /* dp4 r0.y, v0, c1 */
+ 0x00000009, 0x80040000, 0x90e40000, 0xa0e40002, /* dp4 r0.z, v0, c2 */
+ 0x00000009, 0x80080000, 0x90e40000, 0xa0e40003, /* dp4 r0.w, v0, c3 */
+ /* output.Pos = mul(output.Pos, Projection) */
+ 0x00000009, 0xc0010000, 0x80e40000, 0xa0e40004, /* dp4 oPos.x, r0, c4 */
+ 0x00000009, 0xc0020000, 0x80e40000, 0xa0e40005, /* dp4 oPos.y, r0, c5 */
+ 0x00000009, 0xc0040000, 0x80e40000, 0xa0e40006, /* dp4 oPos.z, r0, c6 */
+ 0x00000009, 0xc0080000, 0x80e40000, 0xa0e40007, /* dp4 oPos.w, r0, c7 */
+ /* output.Color = input.Color */
+ 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
+ 0x0000ffff, /* END */
+ };
+
+ /* Basic vertex shader with fog computation ("foggy").
+ * Using the vertex' x coordinate as fog coordinate so that all test cases that use vertex fog
+ * will have a gradient from fully fogged (green, left) to unfogged (red, right). */
+ static const DWORD vertex_shader_code2[] =
+ {
+ 0xfffe0101, /* vs_1_1 */
+ 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
+ 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
+ /* output.Pos = mul(input.Pos, View) */
+ 0x00000009, 0x80010000, 0x90e40000, 0xa0e40000, /* dp4 r0.x, v0, c0 */
+ 0x00000009, 0x80020000, 0x90e40000, 0xa0e40001, /* dp4 r0.y, v0, c1 */
+ 0x00000009, 0x80040000, 0x90e40000, 0xa0e40002, /* dp4 r0.z, v0, c2 */
+ 0x00000009, 0x80080000, 0x90e40000, 0xa0e40003, /* dp4 r0.w, v0, c3 */
+ /* output.Pos = mul(output.Pos, Projection) */
+ 0x00000009, 0xc0010000, 0x80e40000, 0xa0e40004, /* dp4 oPos.x, r0, c4 */
+ 0x00000009, 0xc0020000, 0x80e40000, 0xa0e40005, /* dp4 oPos.y, r0, c5 */
+ 0x00000009, 0xc0040000, 0x80e40000, 0xa0e40006, /* dp4 oPos.z, r0, c6 */
+ 0x00000009, 0xc0080000, 0x80e40000, 0xa0e40007, /* dp4 oPos.w, r0, c7 */
+ /* output.Color = input.Color */
+ 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
+ /* output.Fog = input.Pos.x */
+ 0x00000001, 0xc00f0001, 0x90000000, /* mov oFog, v0.x */
+ 0x0000ffff, /* END */
+ };
+
+ /* Basic vertex shader with fog computation ("foggy"), vs_2_0 */
+ static const DWORD vertex_shader_code3[] =
+ {
+ 0xfffe0200, /* vs_2_0 */
+ 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
+ 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
+ /* output.Pos = mul(input.Pos, View) */
+ 0x03000009, 0x80010000, 0x90e40000, 0xa0e40000, /* dp4 r0.x, v0, c0 */
+ 0x03000009, 0x80020000, 0x90e40000, 0xa0e40001, /* dp4 r0.y, v0, c1 */
+ 0x03000009, 0x80040000, 0x90e40000, 0xa0e40002, /* dp4 r0.z, v0, c2 */
+ 0x03000009, 0x80080000, 0x90e40000, 0xa0e40003, /* dp4 r0.w, v0, c3 */
+ /* output.Pos = mul(output.Pos, Projection) */
+ 0x03000009, 0xc0010000, 0x80e40000, 0xa0e40004, /* dp4 oPos.x, r0, c4 */
+ 0x03000009, 0xc0020000, 0x80e40000, 0xa0e40005, /* dp4 oPos.y, r0, c5 */
+ 0x03000009, 0xc0040000, 0x80e40000, 0xa0e40006, /* dp4 oPos.z, r0, c6 */
+ 0x03000009, 0xc0080000, 0x80e40000, 0xa0e40007, /* dp4 oPos.w, r0, c7 */
+ /* output.Color = input.Color */
+ 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
+ /* output.Fog = input.Pos.x */
+ 0x02000001, 0xc00f0001, 0x90000000, /* mov oFog, v0.x */
+ 0x0000ffff, /* END */
+ };
+
+ /* Basic pixel shader */
+ static const DWORD pixel_shader_code[] =
+ {
+ 0xffff0101, /* ps_1_1 */
+ 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
+ 0x0000ffff
+ };
+ static const DWORD pixel_shader_code2[] =
+ {
+ 0xffff0200, /* ps_2_0 */
+ 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
+ 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
+ 0x0000ffff
+ };
+ static const struct
+ {
+ struct vec3 position;
+ DWORD diffuse;
+ }
+ quad[] =
+ {
+ {{-1.0f, -1.0f, 0.0f}, COLOR_UNFOGGED},
+ {{-1.0f, 1.0f, 0.0f}, COLOR_UNFOGGED},
+ {{ 1.0f, -1.0f, 1.0f}, COLOR_UNFOGGED},
+ {{ 1.0f, 1.0f, 1.0f}, COLOR_UNFOGGED},
+ };
+ static const D3DVERTEXELEMENT9 decl_elements[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ static const struct test_data_t
+ {
+ int vshader;
+ int pshader;
+ D3DFOGMODE vfog;
+ D3DFOGMODE tfog;
+ DWORD color_left;
+ DWORD color_right;
+ }
+ test_data[] =
+ {
+ /* Test data that uses z-based fog has a gradient UNFOGGED->FOGGED.
+ * Test data that uses a vertex shader has a gradient FOGGED->UNFOGGED
+ * (except for the vertex shader without fog computation, where the
+ * quad is completely fogged). */
+
+ /* No vertex shader */
+ {0, 0, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 2, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 2, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 0, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_UNFOGGED, COLOR_FOGGED},
+ {0, 2, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_UNFOGGED, COLOR_FOGGED},
+
+ /* Vertex shader without vertex fog computation */
+ {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 2, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 2, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {1, 0, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_FOGGED},
+ {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_FOGGED},
+ {1, 2, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_FOGGED},
+
+ /* Vertex shader vs_1_1 with vertex fog computation */
+ {2, 0, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 2, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 2, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_UNFOGGED},
+ {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_UNFOGGED},
+ {2, 2, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_UNFOGGED},
+
+ /* Vertex shader vs_2_0 with vertex fog computation */
+ {3, 0, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {3, 1, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {3, 2, D3DFOG_NONE, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {3, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {3, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {3, 2, D3DFOG_LINEAR, D3DFOG_LINEAR, COLOR_UNFOGGED, COLOR_FOGGED},
+ {3, 0, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_UNFOGGED},
+ {3, 1, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_UNFOGGED},
+ {3, 2, D3DFOG_LINEAR, D3DFOG_NONE, COLOR_FOGGED, COLOR_UNFOGGED},
+ };
+ static const D3DMATRIX proj_mat =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ }}};
+ static const D3DMATRIX view_mat =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ }}};
+
+ window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 0, 0, 640, 480, NULL, NULL, NULL, NULL);
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
+ {
+ hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
+ ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
+ ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
+ ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
+
+ if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
+ {
+ hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
+ ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
+ ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
+ }
+ else
+ {
+ skip("No shader model 2 support, skipping some fog tests.\n");
+ }
+ }
+ else
+ {
+ skip("No shader model 1.1 support, skipping some fog tests.\n");
+ }
+
+ start.f = 0.1f;
+ end.f = 0.9f;
+
+ hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
+ ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
+
+ /* Setup initial states: No depth test, no lighting, fog on, fog color */
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
+ ok(SUCCEEDED(hr), "Turning off depth test failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+ ok(SUCCEEDED(hr), "Turning off lighting failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
+ ok(SUCCEEDED(hr), "Turning on fog calculations failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, COLOR_FOG);
+ ok(SUCCEEDED(hr), "Setting fog color failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
+ ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
+ ok(SUCCEEDED(hr), "Setting fog start failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
+ ok(SUCCEEDED(hr), "Setting fog end failed (%08x)\n", hr);
+
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
+ ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
+ ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
+
+ /* Note: Shaders expect matrices in column-major form, so they have
+ * to be transposed if they are not symmetrical (which is the case at the moment). */
+ hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, (const float*)&view_mat, 4);
+ ok(SUCCEEDED(hr), "SetVertexShaderConstantF (view matrix) failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, (const float*)&proj_mat, 4);
+ ok(SUCCEEDED(hr), "SetVertexShaderConstantF (projection matrix) failed (%08x)\n", hr);
+
+ for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
+ {
+ if ((test_data[i].pshader != 0 && pixel_shader[test_data[i].pshader] == NULL)
+ || (test_data[i].vshader != 0 && vertex_shader[test_data[i].vshader] == NULL))
+ continue;
+
+ hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
+ ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
+ ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
+ ok( SUCCEEDED(hr), "Setting fog vertex mode to %d failed (%08x)\n", test_data[i].vfog, hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
+ ok( SUCCEEDED(hr), "Setting fog table mode to %d failed (%08x)\n", test_data[i].tfog, hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, COLOR_CLEAR, 1.0f, 0);
+ ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
+
+ /* Use 5% tolerance on the colors since there may be a gradient
+ * between left and right vertices. */
+ color = getPixelColor(device, 10, 240);
+ ok(color_match(color, test_data[i].color_left, 13),
+ "fog vs%i ps%i fvm%i ftm%i: got left color %08x, expected %08x+-5%%\n",
+ test_data[i].vshader, test_data[i].pshader, test_data[i].vfog,
+ test_data[i].tfog, color, test_data[i].color_left);
+ color = getPixelColor(device, 630, 240);
+ ok(color_match(color, test_data[i].color_right, 13),
+ "fog vs%i ps%i fvm%i ftm%i: got right color %08x, expected %08x+-5%%\n",
+ test_data[i].vshader, test_data[i].pshader, test_data[i].vfog,
+ test_data[i].tfog, color, test_data[i].color_right);
+
+ IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ }
+
+ for (i = 0; i < sizeof(vertex_shader)/sizeof(vertex_shader[0]); i++)
+ if (vertex_shader[i])
+ IDirect3DVertexShader9_Release(vertex_shader[i]);
+ for (i = 0; i < sizeof(pixel_shader)/sizeof(pixel_shader[0]); i++)
+ if (pixel_shader[i])
+ IDirect3DPixelShader9_Release(pixel_shader[i]);
+ IDirect3DVertexDeclaration9_Release(vertex_declaration);
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+done:
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
/* This test tests fog in combination with shaders.
* What's tested: linear fog (vertex and table) with pixel shader
* linear table fog with non foggy vertex shader
@@ -16729,6 +17064,7 @@ START_TEST(visual)
test_vshader_input();
test_vshader_float16();
stream_test();
+ fog_righthanded_test();
fog_with_shader_test();
texbem_test();
texdepth_test();
diff --git a/dlls/ddraw/tests/visual.c b/dlls/ddraw/tests/visual.c
index 0385044..23542ff 100644
--- a/dlls/ddraw/tests/visual.c
+++ b/dlls/ddraw/tests/visual.c
@@ -451,6 +451,7 @@ static void fog_test(IDirect3DDevice7 *device)
HRESULT hr;
DWORD color;
float start = 0.0, end = 1.0;
+ int i;
D3DDEVICEDESC7 caps;
struct
@@ -488,6 +489,13 @@ static void fog_test(IDirect3DDevice7 *device)
{{-1.0f, 1.0f, 1.5f}, 0xffff0000, 0xff000000},
{{ 0.0f, 1.0f, 1.5f}, 0xffff0000, 0xff000000},
{{ 0.0f, 0.0f, 1.5f}, 0xffff0000, 0xff000000},
+ },
+ far_quad3[] =
+ {
+ {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
+ {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
+ {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0xff000000},
+ {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0xff000000},
};
/* Untransformed ones. Give them a different diffuse color to make the
* test look nicer. It also helps making sure that they are drawn
@@ -541,6 +549,20 @@ static void fog_test(IDirect3DDevice7 *device)
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, -1.0f, 1.0f,
};
+ D3DMATRIX proj_mat_rh =
+ {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ };
+ D3DMATRIX view_mat_rh =
+ {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ };
memset(&caps, 0, sizeof(caps));
hr = IDirect3DDevice7_GetCaps(device, &caps);
@@ -707,6 +729,65 @@ static void fog_test(IDirect3DDevice7 *device)
skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
}
+ /* Test fog in combination with a right-handed projection matrix. */
+ hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &proj_mat_rh);
+ ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
+ hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &view_mat_rh);
+ ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
+
+ /* i=0: Table fog. i=1: Vertex fog. */
+ for (i = 0; i <= 1; i++)
+ {
+ if (i == 0)
+ {
+ if (!(caps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE))
+ {
+ skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
+ continue;
+ }
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_LINEAR);
+ ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE);
+ ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
+ }
+ else
+ {
+ 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_LINEAR);
+ ok(hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR returned %#08x\n", hr);
+ }
+
+ hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
+ ok(hr == D3D_OK, "i=%d, IDirect3DDevice7_Clear returned %#08x\n", i, hr);
+
+ if (IDirect3DDevice7_BeginScene(device) == D3D_OK)
+ {
+ hr = IDirect3DDevice7_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
+ D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, far_quad3, 4, Indices, 6, 0);
+ ok(hr == D3D_OK, "i=%d, DrawIndexedPrimitive returned %#08x\n", i, hr);
+
+ hr = IDirect3DDevice7_EndScene(device);
+ ok(hr == D3D_OK, "i=%d, EndScene returned %#08x\n", i, hr);
+ }
+ else
+ {
+ ok(FALSE, "i=%d, BeginScene failed\n", i);
+ }
+
+ color = getPixelColor(device, 10, 240);
+ ok(color_match(color, 0x00ff0000, 13),
+ "i=%d, got left color %08x, expected 0x00ff0000+-5%%\n", i, color);
+ color = getPixelColor(device, 630, 240);
+ ok(color_match(color, 0x0000ff00, 13),
+ "i=%d, got right color %08x, expected 0x0000ff00+-5%%\n", i, color);
+ }
+
+ hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &ident_mat);
+ ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
+ hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &ident_mat);
+ ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
+
/* 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);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 34cc567..f158ee2 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -5005,7 +5005,7 @@ static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_
/* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */
shader_addline(buffer, "gl_FogFragCoord = gl_Position.z * 0.5 + 0.5;\n");
else
- shader_addline(buffer, "gl_FogFragCoord = ec_pos.z;\n");
+ shader_addline(buffer, "gl_FogFragCoord = abs(ec_pos.z);\n");
break;
default:
--
1.8.4.5
More information about the wine-patches
mailing list