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
This commit is contained in:
parent
3c3272dc41
commit
50109aa969
|
@ -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 */
|
||||
color = getPixelColor(device, 128, 240);
|
||||
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]);
|
||||
if(test_data[i].vshader == 1 && test_data[i].tfog == 0 && color != test_data[i].color[j]) {
|
||||
todo_wine 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%%(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
|
|||
|
||||
if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
|
||||
|
||||
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");
|
||||
}
|
||||
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;
|
||||
if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
||||
if(use_vs(stateblock)) {
|
||||
new_source = FOGSOURCE_VS;
|
||||
} 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 {
|
||||
context->last_was_foggy_shader = FALSE;
|
||||
new_source = FOGSOURCE_FFP;
|
||||
}
|
||||
if(new_source != context->fog_source) {
|
||||
|
|
|
@ -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
|
||||
* 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
|
||||
* 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,
|
||||
* the system will apply only pixel(=table) fog effects."
|
||||
*/
|
||||
else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
||||
context->last_was_foggy_shader = FALSE;
|
||||
if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
||||
if(use_vs(stateblock)) {
|
||||
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
|
||||
new_source = FOGSOURCE_VS;
|
||||
} else {
|
||||
switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
|
||||
/* If processed vertices are used, fall through to the NONE case */
|
||||
case WINED3DFOG_EXP:
|
||||
if(!context->last_was_rhw) {
|
||||
glFogi(GL_FOG_MODE, GL_EXP);
|
||||
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
|
||||
new_source = FOGSOURCE_FFP;
|
||||
break;
|
||||
}
|
||||
/* drop through */
|
||||
|
||||
switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
|
||||
/* If processed vertices are used, fall through to the NONE case */
|
||||
case WINED3DFOG_EXP:
|
||||
if(!context->last_was_rhw) {
|
||||
glFogi(GL_FOG_MODE, GL_EXP);
|
||||
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
|
||||
new_source = FOGSOURCE_FFP;
|
||||
break;
|
||||
}
|
||||
/* drop through */
|
||||
case WINED3DFOG_EXP2:
|
||||
if(!context->last_was_rhw) {
|
||||
glFogi(GL_FOG_MODE, GL_EXP2);
|
||||
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
|
||||
new_source = FOGSOURCE_FFP;
|
||||
break;
|
||||
}
|
||||
/* drop through */
|
||||
|
||||
case WINED3DFOG_EXP2:
|
||||
if(!context->last_was_rhw) {
|
||||
glFogi(GL_FOG_MODE, GL_EXP2);
|
||||
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
|
||||
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:
|
||||
if(!context->last_was_rhw) {
|
||||
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)");
|
||||
new_source = FOGSOURCE_FFP;
|
||||
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:
|
||||
FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
|
||||
new_source = FOGSOURCE_FFP; /* Make the compiler happy */
|
||||
default:
|
||||
FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
|
||||
new_source = FOGSOURCE_FFP; /* Make the compiler happy */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
glHint(GL_FOG_HINT, GL_NICEST);
|
||||
checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
|
||||
context->last_was_foggy_shader = FALSE;
|
||||
new_source = FOGSOURCE_FFP;
|
||||
|
||||
switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
|
||||
|
@ -4331,15 +4328,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||
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;
|
||||
if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
|
||||
updateFog = TRUE;
|
||||
|
@ -4405,8 +4393,11 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||
state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
|
||||
}
|
||||
|
||||
if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
|
||||
state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
|
||||
if(context->last_was_vshader) {
|
||||
updateFog = TRUE;
|
||||
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
|
||||
state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
|
||||
}
|
||||
}
|
||||
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
|
||||
state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
|
||||
|
@ -4440,6 +4431,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||
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
|
|||
if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
|
||||
settings->fog = FOG_OFF;
|
||||
} else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
||||
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
|
||||
case WINED3DFOG_NONE:
|
||||
case WINED3DFOG_LINEAR:
|
||||
settings->fog = FOG_LINEAR;
|
||||
break;
|
||||
case WINED3DFOG_EXP:
|
||||
settings->fog = FOG_EXP;
|
||||
break;
|
||||
case WINED3DFOG_EXP2:
|
||||
settings->fog = FOG_EXP2;
|
||||
break;
|
||||
if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
|
||||
settings->fog = FOG_LINEAR;
|
||||
} else {
|
||||
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
|
||||
case WINED3DFOG_NONE:
|
||||
case WINED3DFOG_LINEAR:
|
||||
settings->fog = FOG_LINEAR;
|
||||
break;
|
||||
case WINED3DFOG_EXP:
|
||||
settings->fog = FOG_EXP;
|
||||
break;
|
||||
case WINED3DFOG_EXP2:
|
||||
settings->fog = FOG_EXP2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
|
||||
|
|
|
@ -802,7 +802,6 @@ struct WineD3DContext {
|
|||
WORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */
|
||||
WORD last_was_pshader : 1;
|
||||
WORD last_was_vshader : 1;
|
||||
WORD last_was_foggy_shader : 1;
|
||||
WORD namedArraysLoaded : 1;
|
||||
WORD numberedArraysLoaded : 1;
|
||||
WORD last_was_blit : 1;
|
||||
|
@ -811,7 +810,7 @@ struct WineD3DContext {
|
|||
WORD isPBuffer : 1;
|
||||
WORD fog_enabled : 1;
|
||||
WORD num_untracked_materials : 2; /* Max value 2 */
|
||||
WORD padding : 2;
|
||||
WORD padding : 3;
|
||||
BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
|
||||
BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
|
||||
DWORD numbered_array_mask;
|
||||
|
|
Loading…
Reference in New Issue