diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index e84e8fdf43f..b24b1f38cea 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -1324,7 +1324,7 @@ static void fog_test(IDirect3DDevice9 *device) } color = getPixelColor(device, 160, 360); - todo_wine ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color); + ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color); color = getPixelColor(device, 160, 120); ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Fogged out quad has color %08x\n", color); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 98671aa69c5..e1fe0ee71d6 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -5082,7 +5082,11 @@ static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_ break; case WINED3D_FFP_VS_FOG_DEPTH: - shader_addline(buffer, "gl_FogFragCoord = ec_pos.z;\n"); + if (settings->ortho_fog) + /* 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"); break; default: @@ -6814,6 +6818,16 @@ static void glsl_vertex_pipe_shader(struct wined3d_context *context, context->select_shader = 1; } +static void glsl_vertex_pipe_projection(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + /* Table fog behavior depends on the projection matrix. */ + if (state->render_states[WINED3D_RS_FOGENABLE] + && state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) + context->select_shader = 1; + transform_projection(context, state, state_id); +} + static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = { {STATE_VDECL, {STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, @@ -6867,7 +6881,7 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_VIEWPORT, {STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE }, /* Transform states */ {STATE_TRANSFORM(WINED3D_TS_VIEW), {STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_PROJECTION), {STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection }, WINED3D_GL_EXT_NONE }, + {STATE_TRANSFORM(WINED3D_TS_PROJECTION), {STATE_TRANSFORM(WINED3D_TS_PROJECTION), glsl_vertex_pipe_projection}, WINED3D_GL_EXT_NONE }, {STATE_TRANSFORM(WINED3D_TS_TEXTURE0), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TRANSFORM(WINED3D_TS_TEXTURE1), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TRANSFORM(WINED3D_TS_TEXTURE2), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 5b7fb3c3b8a..9bbd65e11d1 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -3614,10 +3614,19 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct & WINED3D_FFP_LIGHT_TYPE_MASK) << WINED3D_FFP_LIGHT_TYPE_SHIFT(i); } + settings->ortho_fog = 0; if (!state->render_states[WINED3D_RS_FOGENABLE]) settings->fog_mode = WINED3D_FFP_VS_FOG_OFF; else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE) + { settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH; + + if (state->transforms[WINED3D_TS_PROJECTION].u.m[0][3] == 0.0f + && state->transforms[WINED3D_TS_PROJECTION].u.m[1][3] == 0.0f + && state->transforms[WINED3D_TS_PROJECTION].u.m[2][3] == 0.0f + && state->transforms[WINED3D_TS_PROJECTION].u.m[3][3] == 1.0f) + settings->ortho_fog = 1; + } else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE) settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD; else if (state->render_states[WINED3D_RS_RANGEFOGENABLE]) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index dca0d616926..3b75cf0f303 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1737,7 +1737,8 @@ struct wined3d_ffp_vs_settings DWORD point_size : 1; DWORD fog_mode : 2; DWORD texcoords : 8; /* MAX_TEXTURES */ - DWORD padding : 15; + DWORD ortho_fog : 1; + DWORD padding : 14; BYTE texgen[MAX_TEXTURES]; };