Jason Green : wined3d: Fix for vertex shaders.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jul 17 08:15:02 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 6a97f2202e91fed286ff6ca254926e5f57ca17c1
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=6a97f2202e91fed286ff6ca254926e5f57ca17c1

Author: Jason Green <jave27 at gmail.com>
Date:   Mon Jul 17 01:41:53 2006 -0400

wined3d: Fix for vertex shaders.

---

 dlls/wined3d/arb_program_shader.c |    2 +-
 dlls/wined3d/baseshader.c         |    3 +++
 dlls/wined3d/drawprim.c           |   13 +++++++++++--
 dlls/wined3d/vertexshader.c       |   15 +++++++++++++++
 dlls/wined3d/wined3d_private.h    |    6 +++++-
 5 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 4eb8494..b18666e 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -339,7 +339,7 @@ static void vshader_program_add_param(SH
   IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) arg->shader;
 
   /* oPos, oFog and oPts in D3D */
-  static const char* hwrastout_reg_names[] = { "result.position", "result.fogcoord", "result.pointsize" };
+  static const char* hwrastout_reg_names[] = { "result.position", "TMP_FOG", "result.pointsize" };
 
   DWORD reg = param & D3DSP_REGNUM_MASK;
   DWORD regtype = shader_get_regtype(param);
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index b3823c2..7595bc9 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -343,6 +343,9 @@ HRESULT shader_get_registers_used(
 
                 else if (D3DSPR_INPUT == regtype && !pshader)
                     reg_maps->attributes[reg] = 1;
+
+                else if (D3DSPR_RASTOUT == regtype && reg == 1)
+                    reg_maps->fog = 1;
              }
         }
     }
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 1a1d01e..4939969 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -327,8 +327,17 @@ static void primitiveInitState(
         }
         This->last_was_rhw = FALSE;
 
-        /* Restore fogging */
-        if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] && This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] != D3DFOG_NONE) {
+        /* Setup fogging */
+        if (useVS && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->usesFog) {
+            /* In D3D vertex shader return the 'final' fog value, while in OpenGL it is the 'input' fog value.
+             * The code below 'disables' the OpenGL postprocessing by setting the formula to '1'. */
+            glFogi(GL_FOG_MODE, GL_LINEAR);
+            glFogf(GL_FOG_START, 1.0f);
+            glFogf(GL_FOG_END, 0.0f);
+
+        } else if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] 
+                  && This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] != D3DFOG_NONE) {
+            
             if(GL_SUPPORT(EXT_FOG_COORD)) {
                 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
                 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)\n");
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 0262079..54b8520 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -712,6 +712,12 @@ #endif
         if (This->baseShader.hex_version >= D3DVS_VERSION(3,0))
             vshader_glsl_output_unpack(&buffer, This->semantics_out);
 
+        /* Clamp the fog from 0 to 1 if it's used */
+        if (reg_maps->fog) {
+            This->usesFog = 1;
+            shader_addline(&buffer, "gl_FogFragCoord = clamp(gl_FogFragCoord, 0.0, 1.0);\n");
+        }
+
         shader_addline(&buffer, "}\n\0");
 
         TRACE("Compiling shader object %u\n", shader_obj);
@@ -735,9 +741,18 @@ #endif
         /* Base Declarations */
         shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
 
+        if (reg_maps->fog) {
+            This->usesFog = 1;
+            shader_addline(&buffer, "TEMP TMP_FOG;\n");
+        }
+
         /* Base Shader Body */
         shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
 
+        /* Make sure the fog value is positive - values above 1.0 are ignored */
+        if (reg_maps->fog)
+            shader_addline(&buffer, "MAX result.fogcoord, TMP_FOG, 0.0;\n");
+
         shader_addline(&buffer, "END\n\0"); 
 
         /* TODO: change to resource.glObjectHandle or something like that */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index c1ce763..03ce7d7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1314,6 +1314,9 @@ typedef struct shader_reg_maps {
     /* Whether or not a loop is used in this shader */
     char loop;
 
+    /* Whether or not this shader uses fog */
+    char fog;
+
 } shader_reg_maps;
 
 #define SHADER_PGMSIZE 65535
@@ -1608,7 +1611,8 @@ typedef struct IWineD3DVertexShaderImpl 
     IUnknown                    *parent;
     IWineD3DDeviceImpl          *wineD3DDevice;
 
-    DWORD usage;
+    char                        usesFog;
+    DWORD                       usage;
 
     /* Vertex shader input and output semantics */
     semantic semantics_in [MAX_ATTRIBS];




More information about the wine-cvs mailing list