wined3d: Make pixelshaders disable fog properly.
This is a first step towards cleaning up the fog mess. The fog parameter is added to the pixelshader compile args structure. That way multiple pshaders are compiled for different fog settings, and the pixel shader can remove the fog line if fog is not enabled. That way we don't need special fog start and end settings, and this allows us to implement EXP and EXP2 fog in the future too.
This commit is contained in:
parent
7d92b54a97
commit
690cbe76ac
|
@ -1905,27 +1905,43 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
|
|||
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
|
||||
|
||||
/* We need two variables for fog blending */
|
||||
shader_addline(buffer, "TEMP TMP_FOG;\n");
|
||||
if(args->fog != FOG_OFF) shader_addline(buffer, "TEMP TMP_FOG;\n");
|
||||
if (shader_version >= WINED3DPS_VERSION(2,0)) shader_addline(buffer, "TEMP TMP_COLOR;\n");
|
||||
|
||||
/* Base Shader Body */
|
||||
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
|
||||
|
||||
/* calculate fog and blend it
|
||||
* NOTE: state.fog.params.y and state.fog.params.z don't hold fog start s and end e but
|
||||
* -1/(e-s) and e/(e-s) respectively.
|
||||
*/
|
||||
shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n");
|
||||
|
||||
fragcolor = (shader_version < WINED3DPS_VERSION(2,0)) ? "R0" : "TMP_COLOR";
|
||||
|
||||
if (shader_version < WINED3DPS_VERSION(2,0)) {
|
||||
fragcolor = "R0";
|
||||
} else {
|
||||
fragcolor = "TMP_COLOR";
|
||||
}
|
||||
if(args->srgb_correction) {
|
||||
arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
|
||||
}
|
||||
if (shader_version < WINED3DPS_VERSION(3,0))
|
||||
{
|
||||
shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, state.fog.color;\n", fragcolor);
|
||||
shader_addline(buffer, "MOV result.color.a, %s.a;\n", fragcolor);
|
||||
if (shader_version < WINED3DPS_VERSION(3,0)) {
|
||||
/* calculate fog and blend it
|
||||
* NOTE: state.fog.params.y and state.fog.params.z don't hold fog start s and end e but
|
||||
* -1/(e-s) and e/(e-s) respectively.
|
||||
*/
|
||||
switch(args->fog) {
|
||||
case FOG_OFF:
|
||||
shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
|
||||
break;
|
||||
case FOG_LINEAR:
|
||||
shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n");
|
||||
shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, state.fog.color;\n", fragcolor);
|
||||
shader_addline(buffer, "MOV result.color.a, %s.a;\n", fragcolor);
|
||||
break;
|
||||
case FOG_EXP:
|
||||
FIXME("Implement EXP fog in ARB\n");
|
||||
shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
|
||||
break;
|
||||
case FOG_EXP2:
|
||||
FIXME("Implement EXP2 fog in ARB\n");
|
||||
shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
shader_addline(buffer, "END\n");
|
||||
|
|
|
@ -3675,10 +3675,20 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
|
|||
* NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
|
||||
* -1/(e-s) and e/(e-s) respectively.
|
||||
*/
|
||||
if (reg_maps->shader_version < WINED3DPS_VERSION(3,0))
|
||||
{
|
||||
shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");
|
||||
shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
|
||||
if(reg_maps->shader_version < WINED3DPS_VERSION(3,0)) {
|
||||
switch(args->fog) {
|
||||
case FOG_OFF: break;
|
||||
case FOG_LINEAR:
|
||||
shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");
|
||||
shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
|
||||
break;
|
||||
case FOG_EXP:
|
||||
FIXME("Implement EXP fog in glsl\n");
|
||||
break;
|
||||
case FOG_EXP2:
|
||||
FIXME("Implement EXP2 fog in glsl\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
shader_addline(buffer, "}\n");
|
||||
|
|
|
@ -463,9 +463,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
|
|||
UINT i, sampler;
|
||||
IWineD3DBaseTextureImpl *tex;
|
||||
|
||||
memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set */
|
||||
args->srgb_correction = stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;
|
||||
|
||||
memset(args->color_fixup, 0, sizeof(args->color_fixup));
|
||||
for(i = 0; i < shader->baseShader.num_sampled_samplers; i++) {
|
||||
sampler = shader->baseShader.sampled_samplers[i];
|
||||
tex = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
|
||||
|
@ -484,8 +484,32 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
|
|||
} else {
|
||||
args->vp_mode = fixedfunction;
|
||||
}
|
||||
args->fog = FOG_OFF;
|
||||
} else {
|
||||
args->vp_mode = vertexshader;
|
||||
if(stateblock->renderState[WINED3DRS_FOGENABLE]) {
|
||||
switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
|
||||
case WINED3DFOG_NONE:
|
||||
if(((IWineD3DDeviceImpl *) shader->baseShader.device)->strided_streams.u.s.position_transformed ||
|
||||
use_vs((IWineD3DDeviceImpl *) shader->baseShader.device)) {
|
||||
args->fog = FOG_LINEAR;
|
||||
break;
|
||||
}
|
||||
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
|
||||
case WINED3DFOG_NONE: /* Drop through */
|
||||
case WINED3DFOG_LINEAR: args->fog = FOG_LINEAR; break;
|
||||
case WINED3DFOG_EXP: args->fog = FOG_EXP; break;
|
||||
case WINED3DFOG_EXP2: args->fog = FOG_EXP2; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WINED3DFOG_LINEAR: args->fog = FOG_LINEAR; break;
|
||||
case WINED3DFOG_EXP: args->fog = FOG_EXP; break;
|
||||
case WINED3DFOG_EXP2: args->fog = FOG_EXP2; break;
|
||||
}
|
||||
} else {
|
||||
args->fog = FOG_OFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -911,18 +911,6 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
|
|||
/* No fog? Disable it, and we're done :-) */
|
||||
glDisable(GL_FOG);
|
||||
checkGLcall("glDisable GL_FOG");
|
||||
if (use_ps(stateblock->wineD3DDevice)
|
||||
&& ps_impl->baseShader.reg_maps.shader_version < WINED3DPS_VERSION(3,0))
|
||||
{
|
||||
/* disable fog in the pixel shader
|
||||
* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
|
||||
* -1/(e-s) and e/(e-s) respectively.
|
||||
*/
|
||||
glFogf(GL_FOG_START, 0.0f);
|
||||
checkGLcall("glFogf(GL_FOG_START, fogstart)");
|
||||
glFogf(GL_FOG_END, 1.0f);
|
||||
checkGLcall("glFogf(GL_FOG_END, fogend)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1168,16 +1156,6 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
|
|||
} else {
|
||||
glDisable(GL_FOG);
|
||||
checkGLcall("glDisable GL_FOG");
|
||||
if( use_ps(stateblock->wineD3DDevice) ) {
|
||||
/* disable fog in the pixel shader
|
||||
* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
|
||||
* -1/(e-s) and e/(e-s) respectively.
|
||||
*/
|
||||
glFogf(GL_FOG_START, 0.0f);
|
||||
checkGLcall("glFogf(GL_FOG_START, fogstart)");
|
||||
glFogf(GL_FOG_END, 1.0f);
|
||||
checkGLcall("glFogf(GL_FOG_END, fogend)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -438,6 +438,13 @@ struct stb_const_desc {
|
|||
UINT const_num;
|
||||
};
|
||||
|
||||
enum fogmode {
|
||||
FOG_OFF,
|
||||
FOG_LINEAR,
|
||||
FOG_EXP,
|
||||
FOG_EXP2
|
||||
};
|
||||
|
||||
/* Stateblock dependent parameters which have to be hardcoded
|
||||
* into the shader code
|
||||
*/
|
||||
|
@ -445,6 +452,7 @@ struct ps_compile_args {
|
|||
struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS];
|
||||
BOOL srgb_correction;
|
||||
enum vertexprocessing_mode vp_mode;
|
||||
enum fogmode fog;
|
||||
/* Projected textures(ps 1.0-1.3) */
|
||||
/* Texture types(2D, Cube, 3D) in ps 1.x */
|
||||
};
|
||||
|
@ -974,12 +982,7 @@ struct texture_stage_op
|
|||
|
||||
struct ffp_frag_settings {
|
||||
struct texture_stage_op op[MAX_TEXTURES];
|
||||
enum {
|
||||
FOG_OFF,
|
||||
FOG_LINEAR,
|
||||
FOG_EXP,
|
||||
FOG_EXP2
|
||||
} fog;
|
||||
enum fogmode fog;
|
||||
/* Use an int instead of a char to get dword alignment */
|
||||
unsigned int sRGB_write;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue