[WINED3D 3/3] Fix fog in the case of vertex shaders

Jason Green jave27 at gmail.com
Mon Jun 19 16:54:23 CDT 2006


- Fixes both ARB and GLSL shaders that use fog.
-------------- next part --------------
From nobody Mon Sep 17 00:00:00 2001
From: Jason <jason at jave02.(none)>
Date: Sat, 17 Jun 2006 16:41:14 -0400
Subject: [PATCH 3/4] Fix fog in the case of vertex shaders

- Fixes both ARB and GLSL shaders that use fog.

---

 dlls/wined3d/baseshader.c      |    3 +++
 dlls/wined3d/drawprim.c        |    8 ++++++++
 dlls/wined3d/vertexshader.c    |   18 +++++++++++++++++-
 dlls/wined3d/wined3d_private.h |    6 +++++-
 4 files changed, 33 insertions(+), 2 deletions(-)

1a6886d08086b83d5d573c69aa19a50dc4704e04
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 9f0b88c..b8e4992 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -416,6 +416,9 @@ void 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 65a3df1..0f946de 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1854,6 +1854,14 @@ #endif
 
             TRACE("Using vertex shader\n");
 
+            /* 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'. */
+            if (((IWineD3DVertexShaderImpl*)This->stateBlock->vertexShader)->usesFog) {
+                    glFogi(GL_FOG_MODE, GL_LINEAR);
+                    glFogf(GL_FOG_START, 1.0f);
+                    glFogf(GL_FOG_END, 0.0f);
+            }
+
             if (wined3d_settings.shader_mode == SHADER_ARB) {
                 /* Bind the vertex program */
                 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB,
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 86eff1f..c31fccc 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -628,7 +628,7 @@ inline static void vshader_program_add_p
   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);
@@ -881,6 +881,12 @@ #endif
         if (This->baseShader.hex_version >= D3DVS_VERSION(3,0))
             vshader_glsl_output_unpack(&buffer, 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);
@@ -904,9 +910,19 @@ #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);
 
+        if (reg_maps.fog) {
+            /* Make sure fog coord is bigger than 0.0 */
+            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 e8322a2..108d9dd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1283,6 +1283,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
@@ -1504,7 +1507,8 @@ typedef struct IWineD3DVertexShaderImpl 
     IUnknown                    *parent;
     IWineD3DDeviceImpl          *wineD3DDevice;
 
-    DWORD usage;
+    char                        usesFog;
+    DWORD                       usage;
 
     /* vertex declaration array mapping */
     DWORD arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE];
-- 
1.3.3


More information about the wine-patches mailing list