Commit 50109aa9 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Get rid of last_was_foggy_shader & friends.

The fog settings do not depend on wether the shader writes to oFog or not, instead they depend on the FOGVERTEXMODE and FOGTABLEMODE settings, and if a vertex shader is bound at all. It works the same way as with the fixed function, and having a vertex shader is the same as using pretransformed vertices, just that the fog coord comes from the shader instead of the specular color: FOGTABLEMODE != NONE: The Z coord is used, oFog is ignored FOGTABLEMODE == NONE, with VS: oFog is used FOGTABLEMODE == NONE, no VS, XYZ: Z is used FOGTABLEMODE == NONE, no VS, XYZRHW: diffuse color is used
parent 3c3272dc
...@@ -1536,9 +1536,15 @@ static void fog_with_shader_test(IDirect3DDevice9 *device) ...@@ -1536,9 +1536,15 @@ static void fog_with_shader_test(IDirect3DDevice9 *device)
/* As the red and green component are the result of blending use 5% tolerance on the expected value */ /* As the red and green component are the result of blending use 5% tolerance on the expected value */
color = getPixelColor(device, 128, 240); color = getPixelColor(device, 128, 240);
ok(color_match(color, test_data[i].color[j], 13), if(test_data[i].vshader == 1 && test_data[i].tfog == 0 && color != test_data[i].color[j]) {
"fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n", todo_wine ok(color_match(color, test_data[i].color[j], 13),
test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]); "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%(todo)\n",
test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
} else {
ok(color_match(color, test_data[i].color[j], 13),
"fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
}
} }
} }
......
...@@ -3052,22 +3052,17 @@ static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, Win ...@@ -3052,22 +3052,17 @@ static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return; if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
if(use_vs(stateblock) if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
&& ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) { if(use_vs(stateblock)) {
if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) { new_source = FOGSOURCE_VS;
FIXME("vertex shader with table fog used\n");
}
context->last_was_foggy_shader = TRUE;
new_source = FOGSOURCE_VS;
} else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
context->last_was_foggy_shader = FALSE;
if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) {
new_source = FOGSOURCE_COORD;
} else { } else {
new_source = FOGSOURCE_FFP; if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) {
new_source = FOGSOURCE_COORD;
} else {
new_source = FOGSOURCE_FFP;
}
} }
} else { } else {
context->last_was_foggy_shader = FALSE;
new_source = FOGSOURCE_FFP; new_source = FOGSOURCE_FFP;
} }
if(new_source != context->fog_source) { if(new_source != context->fog_source) {
......
...@@ -1019,75 +1019,72 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D ...@@ -1019,75 +1019,72 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
* and 2) disables the fog computation (in either the fixed function or programmable * and 2) disables the fog computation (in either the fixed function or programmable
* rasterizer) if using a vertex program. * rasterizer) if using a vertex program.
* *
* D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
* D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
* fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
* the specular color, a vertex shader counts as pretransformed geometry in this case.
* There are some GL differences between specular fog coords and vertex shaders though.
*
* With table fog the vertex shader fog coordinate is ignored.
* *
* If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
* without shaders). * without shaders).
*/ */
if (use_vs(stateblock) && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) {
if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) {
FIXME("vertex shader with table fog used\n");
} else {
/* Set fog computation in the rasterizer to pass through the value (just blend it) */
glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
}
context->last_was_foggy_shader = TRUE;
new_source = FOGSOURCE_VS;
}
/* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes, /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
* the system will apply only pixel(=table) fog effects." * the system will apply only pixel(=table) fog effects."
*/ */
else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
context->last_was_foggy_shader = FALSE; if(use_vs(stateblock)) {
glFogi(GL_FOG_MODE, GL_LINEAR);
switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) { checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
/* If processed vertices are used, fall through to the NONE case */ new_source = FOGSOURCE_VS;
case WINED3DFOG_EXP: } else {
if(!context->last_was_rhw) { switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
glFogi(GL_FOG_MODE, GL_EXP); /* If processed vertices are used, fall through to the NONE case */
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)"); case WINED3DFOG_EXP:
new_source = FOGSOURCE_FFP; if(!context->last_was_rhw) {
break; glFogi(GL_FOG_MODE, GL_EXP);
} checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
/* drop through */ new_source = FOGSOURCE_FFP;
break;
case WINED3DFOG_EXP2: }
if(!context->last_was_rhw) { /* drop through */
glFogi(GL_FOG_MODE, GL_EXP2);
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)"); case WINED3DFOG_EXP2:
new_source = FOGSOURCE_FFP; if(!context->last_was_rhw) {
break; glFogi(GL_FOG_MODE, GL_EXP2);
} checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
/* drop through */ new_source = FOGSOURCE_FFP;
break;
}
/* drop through */
case WINED3DFOG_LINEAR:
if(!context->last_was_rhw) {
glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
new_source = FOGSOURCE_FFP;
break;
}
/* drop through */
case WINED3DFOG_LINEAR: case WINED3DFOG_NONE:
if(!context->last_was_rhw) { /* Both are none? According to msdn the alpha channel of the specular
* color contains a fog factor. Set it in drawStridedSlow.
* Same happens with Vertexfog on transformed vertices
*/
new_source = FOGSOURCE_COORD;
glFogi(GL_FOG_MODE, GL_LINEAR); glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
new_source = FOGSOURCE_FFP;
break; break;
}
/* drop through */
case WINED3DFOG_NONE:
/* Both are none? According to msdn the alpha channel of the specular
* color contains a fog factor. Set it in drawStridedSlow.
* Same happens with Vertexfog on transformed vertices
*/
new_source = FOGSOURCE_COORD;
glFogi(GL_FOG_MODE, GL_LINEAR);
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
break;
default: default:
FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]); FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
new_source = FOGSOURCE_FFP; /* Make the compiler happy */ new_source = FOGSOURCE_FFP; /* Make the compiler happy */
}
} }
} else { } else {
glHint(GL_FOG_HINT, GL_NICEST);
checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
context->last_was_foggy_shader = FALSE;
new_source = FOGSOURCE_FFP; new_source = FOGSOURCE_FFP;
switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) { switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
...@@ -4331,15 +4328,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W ...@@ -4331,15 +4328,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
BOOL wasrhw = context->last_was_rhw; BOOL wasrhw = context->last_was_rhw;
if (useVertexShaderFunction)
{
if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) {
updateFog = TRUE;
}
} else if(context->last_was_foggy_shader) {
updateFog = TRUE;
}
transformed = device->strided_streams.position_transformed; transformed = device->strided_streams.position_transformed;
if(transformed != context->last_was_rhw && !useVertexShaderFunction) { if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
updateFog = TRUE; updateFog = TRUE;
...@@ -4405,8 +4393,11 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W ...@@ -4405,8 +4393,11 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context); state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
} }
if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) { if(context->last_was_vshader) {
state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context); updateFog = TRUE;
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
}
} }
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) { if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context); state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
...@@ -4440,6 +4431,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W ...@@ -4440,6 +4431,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context); transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
} }
} }
updateFog = TRUE;
} }
} }
......
...@@ -2096,17 +2096,21 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting ...@@ -2096,17 +2096,21 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) { if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
settings->fog = FOG_OFF; settings->fog = FOG_OFF;
} else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) { if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
case WINED3DFOG_NONE: settings->fog = FOG_LINEAR;
case WINED3DFOG_LINEAR: } else {
settings->fog = FOG_LINEAR; switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
break; case WINED3DFOG_NONE:
case WINED3DFOG_EXP: case WINED3DFOG_LINEAR:
settings->fog = FOG_EXP; settings->fog = FOG_LINEAR;
break; break;
case WINED3DFOG_EXP2: case WINED3DFOG_EXP:
settings->fog = FOG_EXP2; settings->fog = FOG_EXP;
break; break;
case WINED3DFOG_EXP2:
settings->fog = FOG_EXP2;
break;
}
} }
} else { } else {
switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) { switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
......
...@@ -802,7 +802,6 @@ struct WineD3DContext { ...@@ -802,7 +802,6 @@ struct WineD3DContext {
WORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */ WORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */
WORD last_was_pshader : 1; WORD last_was_pshader : 1;
WORD last_was_vshader : 1; WORD last_was_vshader : 1;
WORD last_was_foggy_shader : 1;
WORD namedArraysLoaded : 1; WORD namedArraysLoaded : 1;
WORD numberedArraysLoaded : 1; WORD numberedArraysLoaded : 1;
WORD last_was_blit : 1; WORD last_was_blit : 1;
...@@ -811,7 +810,7 @@ struct WineD3DContext { ...@@ -811,7 +810,7 @@ struct WineD3DContext {
WORD isPBuffer : 1; WORD isPBuffer : 1;
WORD fog_enabled : 1; WORD fog_enabled : 1;
WORD num_untracked_materials : 2; /* Max value 2 */ WORD num_untracked_materials : 2; /* Max value 2 */
WORD padding : 2; WORD padding : 3;
BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */ BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */ BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
DWORD numbered_array_mask; DWORD numbered_array_mask;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment