WineD3D: Apply the half pixel correction for shaders too

Stefan Dösinger stefan at codeweavers.com
Mon Aug 28 16:46:00 CDT 2006


OpenGL coordinates specify the middle of the pixel, white d3d coords the 
corner. This is addressed by moving the entire image using the projection 
matrix, but this matrix isn't applied automatically if vertex shaders are 
used. This patch applies the coordinate correction after every vertex shader. 
To avoid a full transform multiplication with 2 matrices only 2 additions are 
performed.

This fixes the bad fonts in half-life 2 in dxlevel 80
-------------- next part --------------
From 5ce2ebc1fd7c4bb263407e1576a6beb95536a0e3 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=F6singer?= <stefan at codeweavers.com>
Date: Mon, 28 Aug 2006 23:41:33 +0200
Subject: [PATCH] WineD3D: apply the half pixel correction for shaders too
---
 dlls/wined3d/vertexshader.c |   35 ++++++++++++++++++++++++++++-------
 1 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 2f3de86..9719264 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -735,8 +735,18 @@ #endif
         }
         
         /* Write the final position.
-         * Account for any inverted textures (render to texture case) by reversing the y coordinate
-         *  (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices) */
+         *
+         * OpenGL coordinates specify the center of the pixel while d3d coords specify
+         * the corner. For that reason a translation is done with the projection matrix,
+         * which sets the offsets to move in the w coords of the matrix(see glTranslate manpage)
+         * Add the w coordinates to x and y, this avoids the need for a full matrix
+         * multiplication. The matrix is set up in drawprim.c, primitiveInitState.
+         */
+        shader_addline(&buffer, "gl_Position.x = gl_Position.x + gl_ProjectionMatrix[3][0];\n");
+        shader_addline(&buffer, "gl_Position.y = gl_Position.y + gl_ProjectionMatrix[3][1];\n");
+        /* Account for any inverted textures (render to texture case) by reversing the y coordinate
+         *  (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices)
+         */
         shader_addline(&buffer, "gl_Position.y = gl_Position.y * gl_ProjectionMatrix[1][1];\n");
 
         shader_addline(&buffer, "}\n\0");
@@ -763,7 +773,8 @@ #endif
         shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
         
         /* We need the projection matrix to correctly render upside-down objects (render to texture) */
-        shader_addline(&buffer, "PARAM PROJECTION = state.matrix.projection.row[1];\n");
+        shader_addline(&buffer, "PARAM PROJECTIONX = state.matrix.projection.row[0];\n");
+        shader_addline(&buffer, "PARAM PROJECTIONY = state.matrix.projection.row[1];\n");
 
         if (reg_maps->fog) {
             This->usesFog = 1;
@@ -777,11 +788,21 @@ #endif
         if (reg_maps->fog)
             shader_addline(&buffer, "MAX result.fogcoord, TMP_FOG, 0.0;\n");
 
-        /* Write the final position.
-         * Account for any inverted textures (render to texture case) by reversing the y coordinate
-         *  (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices) */
         shader_addline(&buffer, "MOV result.position, TMP_OUT;\n");
-        shader_addline(&buffer, "MUL result.position.y, TMP_OUT.y, PROJECTION.y;\n");
+        /* Write the final position.
+         *
+         * OpenGL coordinates specify the center of the pixel while d3d coords specify
+         * the corner. For that reason a translation is done with the projection matrix,
+         * which sets the offsets to move in the w coords of the matrix(see glTranslate manpage)
+         * Add the w coordinates to x and y, this avoids the need for a full matrix
+         * multiplication. The matrix is set up in drawprim.c, primitiveInitState.
+         */
+        shader_addline(&buffer, "ADD result.position.x, TMP_OUT.x, PROJECTIONX.w;\n");
+        shader_addline(&buffer, "ADD result.position.y, TMP_OUT.y, PROJECTIONY.w;\n");
+        /* Account for any inverted textures (render to texture case) by reversing the y coordinate
+         *  (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices)
+         */
+        shader_addline(&buffer, "MUL result.position.y, TMP_OUT.y, PROJECTIONY.y;\n");
         
         shader_addline(&buffer, "END\n\0"); 
 
-- 
1.4.1.1



More information about the wine-patches mailing list