Module: wine Branch: master Commit: e2cf98eb76b9c8451b5f9d25b0c9c07f9fdc4e04 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e2cf98eb76b9c8451b5f9d25b0...
Author: Matteo Bruni mbruni@codeweavers.com Date: Mon Jul 22 20:24:29 2013 +0200
wined3d: Implement special fog behavior for orthogonal projection matrices.
---
dlls/d3d9/tests/visual.c | 2 +- dlls/wined3d/glsl_shader.c | 18 ++++++++++++++++-- dlls/wined3d/utils.c | 9 +++++++++ dlls/wined3d/wined3d_private.h | 3 ++- 4 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index e84e8fd..b24b1f3 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 98671aa..e1fe0ee 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 5b7fb3c..9bbd65e 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 dca0d61..3b75cf0 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]; };