wined3d: Update clip planes when switching to/from offscreen rendering.

Matteo Bruni matteo.mystral at gmail.com
Mon Jan 31 10:08:34 CST 2011


2011/1/31 Stefan Dösinger <stefandoesinger at gmx.at>:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
>
> Am 31.01.2011 um 15:57 schrieb Henri Verbeet:
>
>> On 31 January 2011 15:45, Stefan Dösinger <stefandoesinger at gmx.at> wrote:
>>>
>>> If we change the shader code to write gl_ClipVertex and result.clip before applying the y inversion then we should be able to avoid this. That should also make it more compatible to fixed function vertex processing - here the clipping is performed before the projection matrix is applied.
>>
>> Wouldn't it still have to be after the half-pixel offset is applied though?
> That's what I am not sure about, but my gut feeling says no. In the ffp pipeline clipping wrt user clip planes is done in eye coordinates, so the half pixel offset should have no effect on it. I see no reason why it shouldn't work with shaders in the same way.
>

The attached patch should follow your idea, does it look right? FWIW,
I can't see any 1-pixel offset in The Sims 3 with this patch. Yes, I
know that's not how it should be tested...

> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
>
> iQIcBAEBAgAGBQJNRtD8AAoJEN0/YqbEcdMwVOUP/1x8ZB6vutkspZU2fhspi1tE
> s+b1drKBfHMu3LxswKwo/tA+xB/3h+qyKLuo6GT0kqQ+kF4IbFE3No1oX//baRDn
> 9eWYke1dz/Q0Jh6K1dA72moptYvbpplgvjr4/8bnBCFGChkbQsaK2O0o6zxFtIXc
> yeTxB+oymu0tNxLXzJn+nrOT3qMp1yN9c/MX7crK7O0B56RAUTTg8P4i2Zz4r9L8
> WBHQ8sGGBtpeN9lf65MZeJNZvchLrWsJjq5iDvGxl1vRVuEsMzMEM7xqosOeQgul
> dFlYQFRTNxQk0XCdprq2jIdc/HiZANjvXO7U0eBiV6Orjo91Rbjtg2UCr43Q3hQH
> wdtoXYyPRbCuvttEpnQBg6vg/UegTGIqKNl2QynN/wFocoJ/2FX+aNC49KGnrhEj
> RzUCPuLuQ4y2DqX5zqggnbmrFPHke2Gbz4RJZy085X+FbKGpWen3o+iZCK2rX294
> 8nrlfO1JEGu2Gay+gqUJUQFUhdI1DRr0i5c+Lw7sLztqTZDeGt4/Al+wEDmkS1XA
> lRJVdOtib+BtBzXB2k9H5vawJt2xmqxSmMfjBu7tvkdoINISmDRNHZoow/Io2sid
> P2ZYNXt1AFnRFrvtC5CMLkTYEqMhh5/mcAzrmsVVD8WR4mwAR8dGUMCH17R3+C3L
> P9sP1J5E/M1B9Yx5YV8M
> =gL/E
> -----END PGP SIGNATURE-----
>
>
>
-------------- next part --------------
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 101de6d..d2734d0 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -3118,17 +3118,7 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx,
         shader_addline(buffer, "ADD result.fogcoord, posFixup.x, -posFixup.x;\n");
     }
 
-    /* Write the final position.
-     *
-     * OpenGL coordinates specify the center of the pixel while d3d coords specify
-     * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
-     * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
-     * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that.
-     */
-    shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n");
-    shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n");
-    shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n");
-
+    /* Clipplanes are always stored without y inversion */
     if(use_nv_clip(gl_info) && priv_ctx->target_version >= NV2)
     {
         if(args->super.clip_enabled)
@@ -3172,6 +3162,17 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx,
                        args->clip.boolclip.clip_texcoord - 1);
     }
 
+    /* Write the final position.
+     *
+     * OpenGL coordinates specify the center of the pixel while d3d coords specify
+     * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
+     * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
+     * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that.
+     */
+    shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n");
+    shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n");
+    shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n");
+
     /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
      * and the glsl equivalent
      */
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index efd6d55..f984c96 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -4106,6 +4106,11 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
         shader_addline(buffer, "gl_FogFragCoord = 0.0;\n");
     }
 
+    /* We always store the clipplanes without y inversion */
+    if(args->clip_enabled) {
+        shader_addline(buffer, "gl_ClipVertex = gl_Position;\n");
+    }
+
     /* Write the final position.
      *
      * OpenGL coordinates specify the center of the pixel while d3d coords specify
@@ -4115,9 +4120,6 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
      */
     shader_addline(buffer, "gl_Position.y = gl_Position.y * posFixup.y;\n");
     shader_addline(buffer, "gl_Position.xy += posFixup.zw * gl_Position.ww;\n");
-    if(args->clip_enabled) {
-        shader_addline(buffer, "gl_ClipVertex = gl_Position;\n");
-    }
 
     /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
      *
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index a34ac4f..34ceff2 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3798,24 +3798,18 @@ static void clipplane(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct
         return;
     }
 
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+
     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
     if (!use_vs(state))
-    {
-        glMatrixMode(GL_MODELVIEW);
-        glPushMatrix();
         glLoadMatrixf(&state->transforms[WINED3DTS_VIEW].u.m[0][0]);
-    }
     else
-    {
         /* with vertex shaders, clip planes are not transformed in direct3d,
          * in OpenGL they are still transformed by the model view.
          * Use this to swap the y coordinate if necessary
          */
-        glMatrixMode(GL_MODELVIEW);
-        glPushMatrix();
         glLoadIdentity();
-        if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f);
-    }
 
     TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
             state->clip_planes[index][0],


More information about the wine-devel mailing list