[PATCH] WineD3D: Make pixelshaders disable fog properly=0A=
Stefan Doesinger
stefan at codeweavers.com
Mon Dec 15 19:35:40 CST 2008
=0A=
This is a first step towards cleaning up the fog mess. The fog parameter =
is=0A=
added to the pixelshader compile args structure. That way multiple =
pshaders=0A=
are compiled for different fog settings, and the pixel shader can remove =
the=0A=
fog line if fog is not enabled. That way we don't need special fog start =
and=0A=
end settings, and this allows us to implement EXP and EXP2 fog in the =
future=0A=
too.=0A=
---=0A=
dlls/wined3d/arb_program_shader.c | 42 =
+++++++++++++++++++++++++-----------=0A=
dlls/wined3d/glsl_shader.c | 18 ++++++++++++---=0A=
dlls/wined3d/pixelshader.c | 26 ++++++++++++++++++++++-=0A=
dlls/wined3d/state.c | 22 -------------------=0A=
dlls/wined3d/wined3d_private.h | 15 ++++++++-----=0A=
5 files changed, 77 insertions(+), 46 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 612093f..93ae641 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -1890,27 +1890,43 @@ static GLuint =
shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF=0A=
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, =
reg_maps, buffer, &GLINFO_LOCATION);=0A=
=0A=
/* We need two variables for fog blending */=0A=
- shader_addline(buffer, "TEMP TMP_FOG;\n");=0A=
+ if(args->fog !=3D FOG_OFF) shader_addline(buffer, "TEMP =
TMP_FOG;\n");=0A=
if (shader_version >=3D WINED3DPS_VERSION(2,0)) =
shader_addline(buffer, "TEMP TMP_COLOR;\n");=0A=
=0A=
/* Base Shader Body */=0A=
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, =
function);=0A=
=0A=
- /* calculate fog and blend it=0A=
- * NOTE: state.fog.params.y and state.fog.params.z don't hold fog =
start s and end e but=0A=
- * -1/(e-s) and e/(e-s) respectively.=0A=
- */=0A=
- shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, =
state.fog.params.y, state.fog.params.z;\n");=0A=
-=0A=
- fragcolor =3D (shader_version < WINED3DPS_VERSION(2,0)) ? "R0" : =
"TMP_COLOR";=0A=
-=0A=
+ if (shader_version < WINED3DPS_VERSION(2,0)) {=0A=
+ fragcolor =3D "R0";=0A=
+ } else {=0A=
+ fragcolor =3D "TMP_COLOR";=0A=
+ }=0A=
if(args->srgb_correction) {=0A=
arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", =
"TA", "TB");=0A=
}=0A=
- if (shader_version < WINED3DPS_VERSION(3,0))=0A=
- {=0A=
- shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, =
state.fog.color;\n", fragcolor);=0A=
- shader_addline(buffer, "MOV result.color.a, %s.a;\n", =
fragcolor);=0A=
+ if (shader_version < WINED3DPS_VERSION(3,0)) {=0A=
+ /* calculate fog and blend it=0A=
+ * NOTE: state.fog.params.y and state.fog.params.z don't hold =
fog start s and end e but=0A=
+ * -1/(e-s) and e/(e-s) respectively.=0A=
+ */=0A=
+ switch(args->fog) {=0A=
+ case FOG_OFF:=0A=
+ shader_addline(buffer, "MOV result.color, %s;\n", =
fragcolor);=0A=
+ break;=0A=
+ case FOG_LINEAR:=0A=
+ shader_addline(buffer, "MAD_SAT TMP_FOG, =
fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n");=0A=
+ shader_addline(buffer, "LRP result.color.rgb, =
TMP_FOG.x, %s, state.fog.color;\n", fragcolor);=0A=
+ shader_addline(buffer, "MOV result.color.a, %s.a;\n", =
fragcolor);=0A=
+ break;=0A=
+ case FOG_EXP:=0A=
+ FIXME("Implement EXP fog in ARB\n");=0A=
+ shader_addline(buffer, "MOV result.color, %s;\n", =
fragcolor);=0A=
+ break;=0A=
+ case FOG_EXP2:=0A=
+ FIXME("Implement EXP2 fog in ARB\n");=0A=
+ shader_addline(buffer, "MOV result.color, %s;\n", =
fragcolor);=0A=
+ break;=0A=
+ }=0A=
}=0A=
=0A=
shader_addline(buffer, "END\n");=0A=
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c=0A=
index 8dd7672..7edfa1c 100644=0A=
--- a/dlls/wined3d/glsl_shader.c=0A=
+++ b/dlls/wined3d/glsl_shader.c=0A=
@@ -3637,10 +3637,20 @@ static GLuint =
shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU=0A=
* NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end =
e but=0A=
* -1/(e-s) and e/(e-s) respectively.=0A=
*/=0A=
- if (reg_maps->shader_version < WINED3DPS_VERSION(3,0))=0A=
- {=0A=
- shader_addline(buffer, "float Fog =3D clamp(gl_FogFragCoord * =
gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");=0A=
- shader_addline(buffer, "%s.xyz =3D mix(gl_Fog.color.xyz, =
%s.xyz, Fog);\n", fragcolor, fragcolor);=0A=
+ if(reg_maps->shader_version < WINED3DPS_VERSION(3,0)) {=0A=
+ switch(args->fog) {=0A=
+ case FOG_OFF: break;=0A=
+ case FOG_LINEAR:=0A=
+ shader_addline(buffer, "float Fog =3D =
clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");=0A=
+ shader_addline(buffer, "%s.xyz =3D =
mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);=0A=
+ break;=0A=
+ case FOG_EXP:=0A=
+ FIXME("Implement EXP fog in glsl\n");=0A=
+ break;=0A=
+ case FOG_EXP2:=0A=
+ FIXME("Implement EXP2 fog in glsl\n");=0A=
+ break;=0A=
+ }=0A=
}=0A=
=0A=
shader_addline(buffer, "}\n");=0A=
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c=0A=
index 94a45cf..15392d8 100644=0A=
--- a/dlls/wined3d/pixelshader.c=0A=
+++ b/dlls/wined3d/pixelshader.c=0A=
@@ -463,9 +463,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl =
*shader, IWineD3DStateBlockImp=0A=
UINT i, sampler;=0A=
IWineD3DBaseTextureImpl *tex;=0A=
=0A=
+ memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are =
set */=0A=
args->srgb_correction =3D =
stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;=0A=
=0A=
- memset(args->color_fixup, 0, sizeof(args->color_fixup));=0A=
for(i =3D 0; i < shader->baseShader.num_sampled_samplers; i++) {=0A=
sampler =3D shader->baseShader.sampled_samplers[i];=0A=
tex =3D (IWineD3DBaseTextureImpl *) =
stateblock->textures[sampler];=0A=
@@ -484,8 +484,32 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl =
*shader, IWineD3DStateBlockImp=0A=
} else {=0A=
args->vp_mode =3D fixedfunction;=0A=
}=0A=
+ args->fog =3D FOG_OFF;=0A=
} else {=0A=
args->vp_mode =3D vertexshader;=0A=
+ if(stateblock->renderState[WINED3DRS_FOGENABLE]) {=0A=
+ switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {=0A=
+ case WINED3DFOG_NONE:=0A=
+ if(((IWineD3DDeviceImpl *) =
shader->baseShader.device)->strided_streams.u.s.position_transformed ||=0A=
+ use_vs((IWineD3DDeviceImpl *) =
shader->baseShader.device)) {=0A=
+ args->fog =3D FOG_LINEAR;=0A=
+ break;=0A=
+ }=0A=
+ =
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {=0A=
+ case WINED3DFOG_NONE: /* Drop through */=0A=
+ case WINED3DFOG_LINEAR: args->fog =3D =
FOG_LINEAR; break;=0A=
+ case WINED3DFOG_EXP: args->fog =3D FOG_EXP; =
break;=0A=
+ case WINED3DFOG_EXP2: args->fog =3D FOG_EXP2; =
break;=0A=
+ }=0A=
+ break;=0A=
+=0A=
+ case WINED3DFOG_LINEAR: args->fog =3D FOG_LINEAR; break;=0A=
+ case WINED3DFOG_EXP: args->fog =3D FOG_EXP; break;=0A=
+ case WINED3DFOG_EXP2: args->fog =3D FOG_EXP2; break;=0A=
+ }=0A=
+ } else {=0A=
+ args->fog =3D FOG_OFF;=0A=
+ }=0A=
}=0A=
}=0A=
=0A=
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c=0A=
index 0bf357d..e4c819d 100644=0A=
--- a/dlls/wined3d/state.c=0A=
+++ b/dlls/wined3d/state.c=0A=
@@ -911,18 +911,6 @@ static void state_fog(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DCo=0A=
/* No fog? Disable it, and we're done :-) */=0A=
glDisable(GL_FOG);=0A=
checkGLcall("glDisable GL_FOG");=0A=
- if (use_ps(stateblock->wineD3DDevice)=0A=
- && ps_impl->baseShader.reg_maps.shader_version < =
WINED3DPS_VERSION(3,0))=0A=
- {=0A=
- /* disable fog in the pixel shader=0A=
- * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END =
don't hold fog start s and end e but=0A=
- * -1/(e-s) and e/(e-s) respectively.=0A=
- */=0A=
- glFogf(GL_FOG_START, 0.0f);=0A=
- checkGLcall("glFogf(GL_FOG_START, fogstart)");=0A=
- glFogf(GL_FOG_END, 1.0f);=0A=
- checkGLcall("glFogf(GL_FOG_END, fogend)");=0A=
- }=0A=
return;=0A=
}=0A=
=0A=
@@ -1168,16 +1156,6 @@ static void state_fog(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DCo=0A=
} else {=0A=
glDisable(GL_FOG);=0A=
checkGLcall("glDisable GL_FOG");=0A=
- if( use_ps(stateblock->wineD3DDevice) ) {=0A=
- /* disable fog in the pixel shader=0A=
- * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END =
don't hold fog start s and end e but=0A=
- * -1/(e-s) and e/(e-s) respectively.=0A=
- */=0A=
- glFogf(GL_FOG_START, 0.0f);=0A=
- checkGLcall("glFogf(GL_FOG_START, fogstart)");=0A=
- glFogf(GL_FOG_END, 1.0f);=0A=
- checkGLcall("glFogf(GL_FOG_END, fogend)");=0A=
- }=0A=
}=0A=
}=0A=
=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index f7e617e..9f75939 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -438,6 +438,13 @@ struct stb_const_desc {=0A=
UINT const_num;=0A=
};=0A=
=0A=
+enum fogmode {=0A=
+ FOG_OFF,=0A=
+ FOG_LINEAR,=0A=
+ FOG_EXP,=0A=
+ FOG_EXP2=0A=
+};=0A=
+=0A=
/* Stateblock dependent parameters which have to be hardcoded=0A=
* into the shader code=0A=
*/=0A=
@@ -445,6 +452,7 @@ struct ps_compile_args {=0A=
struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS];=0A=
BOOL srgb_correction;=0A=
enum vertexprocessing_mode vp_mode;=0A=
+ enum fogmode fog;=0A=
/* Projected textures(ps 1.0-1.3) */=0A=
/* Texture types(2D, Cube, 3D) in ps 1.x */=0A=
};=0A=
@@ -973,12 +981,7 @@ struct texture_stage_op=0A=
=0A=
struct ffp_frag_settings {=0A=
struct texture_stage_op op[MAX_TEXTURES];=0A=
- enum {=0A=
- FOG_OFF,=0A=
- FOG_LINEAR,=0A=
- FOG_EXP,=0A=
- FOG_EXP2=0A=
- } fog;=0A=
+ enum fogmode fog;=0A=
/* Use an int instead of a char to get dword alignment */=0A=
unsigned int sRGB_write;=0A=
};=0A=
-- =0A=
1.5.6.4=0A=
=0A=
------=_NextPart_000_0039_01C9613A.B8A7C550--
More information about the wine-patches
mailing list