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 */
|
/* 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
|
||||||
|
|
||||||
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
|
||||||
* 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);
|
||||||
|
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]) {
|
case WINED3DFOG_EXP2:
|
||||||
/* If processed vertices are used, fall through to the NONE case */
|
if(!context->last_was_rhw) {
|
||||||
case WINED3DFOG_EXP:
|
glFogi(GL_FOG_MODE, GL_EXP2);
|
||||||
if(!context->last_was_rhw) {
|
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
|
||||||
glFogi(GL_FOG_MODE, GL_EXP);
|
new_source = FOGSOURCE_FFP;
|
||||||
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
|
break;
|
||||||
new_source = FOGSOURCE_FFP;
|
}
|
||||||
break;
|
/* drop through */
|
||||||
}
|
|
||||||
/* drop through */
|
|
||||||
|
|
||||||
case WINED3DFOG_EXP2:
|
case WINED3DFOG_LINEAR:
|
||||||
if(!context->last_was_rhw) {
|
if(!context->last_was_rhw) {
|
||||||
glFogi(GL_FOG_MODE, GL_EXP2);
|
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||||
checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
|
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
|
||||||
new_source = FOGSOURCE_FFP;
|
new_source = FOGSOURCE_FFP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* drop through */
|
/* 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:
|
default:
|
||||||
/* Both are none? According to msdn the alpha channel of the specular
|
FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
|
||||||
* color contains a fog factor. Set it in drawStridedSlow.
|
new_source = FOGSOURCE_FFP; /* Make the compiler happy */
|
||||||
* 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 */
|
|
||||||
}
|
}
|
||||||
} 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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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 {
|
||||||
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 {
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue