OpenGL Renderer / SoftRasterizer: Properly handle cases where FogShiftSHR is greater than 10. Related to commit 9f4f3ec
.
This commit is contained in:
parent
9f4f3ecf95
commit
df18eda84f
|
@ -550,19 +550,28 @@ void main()\n\
|
|||
\n\
|
||||
if (polyEnableFog)\n\
|
||||
{\n\
|
||||
float fogMixWeight = 0.0;\n\
|
||||
int inFragDepthi = int( (inFragDepth * 32767.0) + 0.5 );\n\
|
||||
int diffi = inFragDepthi - FOG_OFFSET + (FOG_STEP - 1);\n\
|
||||
\n\
|
||||
float interp = 1.0;\n\
|
||||
if ( (inFragDepth > FOG_DEPTH_COMPARE_0) && (inFragDepth < FOG_DEPTH_COMPARE_31) )\n\
|
||||
if (FOG_STEP == 0)\n\
|
||||
{\n\
|
||||
interp = float( (diffi & FOG_WEIGHT_TRUNCATE_MASK) + FOG_OFFSET - inFragDepthi ) / float(FOG_STEP);\n\
|
||||
fogMixWeight = (inFragDepthi <= FOG_OFFSET) ? state.fogDensity[0].r : state.fogDensity[31].r;\n\
|
||||
}\n\
|
||||
else\n\
|
||||
{\n\
|
||||
int diffi = inFragDepthi - FOG_OFFSET + (FOG_STEP - 1);\n\
|
||||
\n\
|
||||
float interp = 1.0;\n\
|
||||
if ( (inFragDepth > FOG_DEPTH_COMPARE_0) && (inFragDepth < FOG_DEPTH_COMPARE_31) )\n\
|
||||
{\n\
|
||||
interp = float( (diffi & FOG_WEIGHT_TRUNCATE_MASK) + FOG_OFFSET - inFragDepthi ) / float(FOG_STEP);\n\
|
||||
}\n\
|
||||
\n\
|
||||
int idx = (diffi >> FOG_SHIFT_INV) - 1;\n\
|
||||
idx = (idx < 1) ? 0 : (idx > 31) ? 31 : idx;\n\
|
||||
\n\
|
||||
fogMixWeight = mix(state.fogDensity[idx].r, state.fogDensity[idx].g, interp);\n\
|
||||
}\n\
|
||||
\n\
|
||||
int idx = (diffi >> FOG_SHIFT_INV) - 1;\n\
|
||||
idx = (idx < 1) ? 0 : (idx > 31) ? 31 : idx;\n\
|
||||
\n\
|
||||
float fogMixWeight = mix(state.fogDensity[idx].r, state.fogDensity[idx].g, interp);\n\
|
||||
\n\
|
||||
#if USE_DUAL_SOURCE_BLENDING\n\
|
||||
outFogWeight = (state.enableFogAlphaOnly) ? vec4(vec3(0.0), fogMixWeight) : vec4(fogMixWeight);\n\
|
||||
|
@ -1549,8 +1558,8 @@ Render3DError OpenGLRenderer_3_2::CreateFogProgram(const OGLFogProgramKey fogPro
|
|||
|
||||
const u32 fogOffset = fogProgramKey.offset;
|
||||
const u32 fogStep = (0x0400 >> fogProgramKey.shift);
|
||||
const u32 fogShiftInv = 10 - fogProgramKey.shift;
|
||||
const u32 fogWeightTruncateMask = ~(fogStep - 1);
|
||||
const u32 fogShiftInv = 10 - fogProgramKey.shift; // Rolls over if fogStep is 0 (do not use in this case)
|
||||
const u32 fogWeightTruncateMask = ~(fogStep - 1); // Rolls over if fogStep is 0 (do not use in this case)
|
||||
|
||||
const GLfloat fogDepthCompare0 = std::min<GLfloat>((GLfloat)(fogOffset + (fogStep * 1)) / 32767.0f, 1.0f);
|
||||
const GLfloat fogDepthCompare31 = std::min<GLfloat>((GLfloat)(fogOffset + (fogStep * 32)) / 32767.0f, 1.0f);
|
||||
|
|
|
@ -3093,11 +3093,12 @@ void gfx3d_parseCurrentDISP3DCNT()
|
|||
gfx3d.state.enableEdgeMarking = (DISP3DCNT.EnableEdgeMarking != 0);
|
||||
gfx3d.state.enableFogAlphaOnly = (DISP3DCNT.FogOnlyAlpha != 0);
|
||||
gfx3d.state.enableFog = (DISP3DCNT.EnableFog != 0);
|
||||
gfx3d.state.fogShift = (DISP3DCNT.FogShiftSHR <= 10) ? DISP3DCNT.FogShiftSHR : 11; // According to GBATEK, values higher than 10 force FogStep (0x400 >> FogShiftSHR) to become 0. So set FogShiftSHR to 11 in this case.
|
||||
// TODO: Handle divide-by-zero cases of FogShiftSHR in SoftRasterizer and OpenGL.
|
||||
// The fog weight is calculated using FogShiftSHR. However, if FogShiftSHR == 0, then this calculation can become a problem.
|
||||
// We'll need to deal with the zero case at some point in the future.
|
||||
gfx3d.state.enableClearImage = (DISP3DCNT.RearPlaneMode != 0);
|
||||
|
||||
// According to GBATEK, values greater than 10 force FogStep (0x400 >> FogShiftSHR) to become 0.
|
||||
// So set FogShiftSHR to 11 in this case so that calculations using (0x400 >> FogShiftSHR) will
|
||||
// equal 0.
|
||||
gfx3d.state.fogShift = (DISP3DCNT.FogShiftSHR <= 10) ? DISP3DCNT.FogShiftSHR : 11;
|
||||
}
|
||||
|
||||
void ParseReg_DISP3DCNT()
|
||||
|
|
|
@ -2114,9 +2114,25 @@ void SoftRasterizerRenderer::_UpdateEdgeMarkColorTable(const u16 *edgeMarkColorT
|
|||
|
||||
void SoftRasterizerRenderer::_UpdateFogTable(const u8 *fogDensityTable)
|
||||
{
|
||||
const s32 fogStep = 0x400 >> this->currentRenderState->fogShift;
|
||||
const s32 fogShiftInv = 10 - this->currentRenderState->fogShift;
|
||||
const s32 fogOffset = min<s32>( max<s32>((s32)this->currentRenderState->fogOffset, 0), 32768 );
|
||||
const s32 fogStep = 0x400 >> this->currentRenderState->fogShift;
|
||||
|
||||
if (fogStep <= 0)
|
||||
{
|
||||
const s32 iMin = min<s32>( max<s32>(fogOffset, 0), 32768);
|
||||
const s32 iMax = min<s32>( max<s32>(fogOffset + 1, 0), 32768);
|
||||
|
||||
// If the fog factor is 127, then treat it as 128.
|
||||
u8 fogWeight = (fogDensityTable[0] >= 127) ? 128 : fogDensityTable[0];
|
||||
memset(this->_fogTable, fogWeight, iMin);
|
||||
|
||||
fogWeight = (fogDensityTable[31] >= 127) ? 128 : fogDensityTable[31];
|
||||
memset(this->_fogTable+iMax, fogWeight, 32768-iMax);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const s32 fogShiftInv = 10 - this->currentRenderState->fogShift;
|
||||
const s32 iMin = min<s32>( max<s32>((( 1 + 1) << fogShiftInv) + fogOffset + 1 - fogStep, 0), 32768);
|
||||
const s32 iMax = min<s32>( max<s32>(((32 + 1) << fogShiftInv) + fogOffset + 1 - fogStep, 0), 32768);
|
||||
assert(iMin <= iMax);
|
||||
|
|
Loading…
Reference in New Issue