Henri Verbeet : wined3d: Fix the half pixel offset.

Alexandre Julliard julliard at winehq.org
Wed Sep 10 06:01:46 CDT 2008


Module: wine
Branch: master
Commit: 27b8f719ca7f26e1edbec6f7e46cc612dce12b41
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=27b8f719ca7f26e1edbec6f7e46cc612dce12b41

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Wed Sep 10 11:08:10 2008 +0200

wined3d: Fix the half pixel offset.

Turns out the original fix was correct for fixed function, but for the
wrong reason. The shader path was already correct. This fixes a
regresssion introduced by 932e95c111118b643650d6643e47be0ddb5528a1.

---

 dlls/wined3d/state.c |   32 ++++++++++++++++++++------------
 1 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 61ccab6..358ad14 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3905,16 +3905,6 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
             divide by the Width/Height, so we need the half range(1.0) to translate by
             half a pixel.
 
-            Note that when rendering offscreen, we need to translate 1 pixel
-            (2/h in normalized device coordinates) down after doing the flip,
-            because of the way the viewport transformation works in OpenGL:
-            (-1,1) in normalized device coordinates corresponds to the upper
-            left corner of the upper left pixel in the viewport. (-1,-1)
-            corresponds to lower left corner of the lower left pixel in the
-            viewport. In other words, the upper left corner of the pixel
-            *below* the lower left pixel in the viewport. See also section
-            2.11.1 "Controlling the Viewport" of the GL 2.1 spec.
-
             The other fun is that d3d's output z range after the transformation is [0;1],
             but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
             scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
@@ -3922,6 +3912,24 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
             [0;1] to [-1;1], so when gl undoes that we utilize the full z range
          */
 
+        /*
+         * Careful with the order of operations here, we're essentially working backwards:
+         * x = x + 1/w;
+         * y = (y - 1/h) * flip;
+         * z = z * 2 - 1;
+         *
+         * Becomes:
+         * glTranslatef(0.0, 0.0, -1.0);
+         * glScalef(1.0, 1.0, 2.0);
+         *
+         * glScalef(1.0, flip, 1.0);
+         * glTranslatef(1/w, -1/h, 0.0);
+         *
+         * This is equivalent to:
+         * glTranslatef(1/w, -flip/h, -1.0)
+         * glScalef(1.0, flip, 2.0);
+         */
+
         if (stateblock->wineD3DDevice->render_offscreen) {
             /* D3D texture coordinates are flipped compared to OpenGL ones, so
              * render everything upside down when rendering offscreen. */
@@ -4517,7 +4525,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
          */
         if (useVertexShaderFunction) {
             device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
-            device->posFixup[3] = -1.0 / stateblock->viewport.Height;
+            device->posFixup[3] = -device->posFixup[1] / stateblock->viewport.Height;
         }
     }
 
@@ -4649,7 +4657,7 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, W
 
 static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width;
-    stateblock->wineD3DDevice->posFixup[3] = -1.0 / stateblock->viewport.Height;
+    stateblock->wineD3DDevice->posFixup[3] = -stateblock->wineD3DDevice->posFixup[1] / stateblock->viewport.Height;
     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
         transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
     }




More information about the wine-cvs mailing list