[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, ®_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, ®_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