OpenGL Renderer: The fog density table is now sampled as a 1D texture instead of being indexed as a uniform array. Should yield a performance improvement on older GPUs.

- Even if the new fog rendering yields no performance improvement on newer GPUs, at least the new code is MUCH cleaner and simpler.
This commit is contained in:
rogerman 2021-09-10 10:13:11 -07:00
parent df18eda84f
commit 3dabb10145
3 changed files with 87 additions and 295 deletions

View File

@ -631,155 +631,30 @@ varying vec2 texCoord;\n\
uniform sampler2D texInFragColor;\n\
uniform sampler2D texInFragDepth;\n\
uniform sampler2D texInFogAttributes;\n\
uniform sampler1D texFogDensityTable;\n\
uniform bool stateEnableFogAlphaOnly;\n\
uniform vec4 stateFogColor;\n\
uniform vec4 stateFogDensity[32];\n\
\n\
void main()\n\
{\n\
vec4 inFragColor = texture2D(texInFragColor, texCoord);\n\
float inFragDepth = texture2D(texInFragDepth, texCoord).r;\n\
vec4 inFogAttributes = texture2D(texInFogAttributes, texCoord);\n\
bool polyEnableFog = (inFogAttributes.r > 0.999);\n\
vec4 newFoggedColor = inFragColor;\n\
\n\
float fogMixWeight = 0.0;\n\
if (FOG_STEP == 0)\n\
{\n\
fogMixWeight = texture1D( texFogDensityTable, (inFragDepth <= FOG_OFFSETF) ? 0.0 : 1.0 ).r;\n\
}\n\
else\n\
{\n\
fogMixWeight = texture1D( texFogDensityTable, (inFragDepth * (1024.0/float(FOG_STEP))) + (((-float(FOG_OFFSET)/float(FOG_STEP)) - 0.5) / 32.0) ).r;\n\
}\n\
\n\
if (polyEnableFog)\n\
{\n\
float inFragDepth = texture2D(texInFragDepth, texCoord).r;\n\
float fogMixWeight = 0.0;\n\
\n\
if (inFragDepth <= FOG_DEPTH_COMPARE_0)\n\
{\n\
fogMixWeight = stateFogDensity[0].r;\n\
}\n\
else if (inFragDepth >= FOG_DEPTH_COMPARE_31)\n\
{\n\
fogMixWeight = stateFogDensity[31].r;\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_1)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 1].g, stateFogDensity[ 1].r, (inFragDepth - FOG_DEPTH_COMPARE_0) * FOG_DEPTH_INVDIFF_1);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_2)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 2].g, stateFogDensity[ 2].r, (inFragDepth - FOG_DEPTH_COMPARE_1) * FOG_DEPTH_INVDIFF_2);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_3)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 3].g, stateFogDensity[ 3].r, (inFragDepth - FOG_DEPTH_COMPARE_2) * FOG_DEPTH_INVDIFF_3);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_4)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 4].g, stateFogDensity[ 4].r, (inFragDepth - FOG_DEPTH_COMPARE_3) * FOG_DEPTH_INVDIFF_4);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_5)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 5].g, stateFogDensity[ 5].r, (inFragDepth - FOG_DEPTH_COMPARE_4) * FOG_DEPTH_INVDIFF_5);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_6)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 6].g, stateFogDensity[ 6].r, (inFragDepth - FOG_DEPTH_COMPARE_5) * FOG_DEPTH_INVDIFF_6);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_7)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 7].g, stateFogDensity[ 7].r, (inFragDepth - FOG_DEPTH_COMPARE_6) * FOG_DEPTH_INVDIFF_7);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_8)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 8].g, stateFogDensity[ 8].r, (inFragDepth - FOG_DEPTH_COMPARE_7) * FOG_DEPTH_INVDIFF_8);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_9)\n\
{\n\
fogMixWeight = mix(stateFogDensity[ 9].g, stateFogDensity[ 9].r, (inFragDepth - FOG_DEPTH_COMPARE_8) * FOG_DEPTH_INVDIFF_9);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_10)\n\
{\n\
fogMixWeight = mix(stateFogDensity[10].g, stateFogDensity[10].r, (inFragDepth - FOG_DEPTH_COMPARE_9) * FOG_DEPTH_INVDIFF_10);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_11)\n\
{\n\
fogMixWeight = mix(stateFogDensity[11].g, stateFogDensity[11].r, (inFragDepth - FOG_DEPTH_COMPARE_10) * FOG_DEPTH_INVDIFF_11);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_12)\n\
{\n\
fogMixWeight = mix(stateFogDensity[12].g, stateFogDensity[12].r, (inFragDepth - FOG_DEPTH_COMPARE_11) * FOG_DEPTH_INVDIFF_12);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_13)\n\
{\n\
fogMixWeight = mix(stateFogDensity[13].g, stateFogDensity[13].r, (inFragDepth - FOG_DEPTH_COMPARE_12) * FOG_DEPTH_INVDIFF_13);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_14)\n\
{\n\
fogMixWeight = mix(stateFogDensity[14].g, stateFogDensity[14].r, (inFragDepth - FOG_DEPTH_COMPARE_13) * FOG_DEPTH_INVDIFF_14);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_15)\n\
{\n\
fogMixWeight = mix(stateFogDensity[15].g, stateFogDensity[15].r, (inFragDepth - FOG_DEPTH_COMPARE_14) * FOG_DEPTH_INVDIFF_15);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_16)\n\
{\n\
fogMixWeight = mix(stateFogDensity[16].g, stateFogDensity[16].r, (inFragDepth - FOG_DEPTH_COMPARE_15) * FOG_DEPTH_INVDIFF_16);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_17)\n\
{\n\
fogMixWeight = mix(stateFogDensity[17].g, stateFogDensity[17].r, (inFragDepth - FOG_DEPTH_COMPARE_16) * FOG_DEPTH_INVDIFF_17);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_18)\n\
{\n\
fogMixWeight = mix(stateFogDensity[18].g, stateFogDensity[18].r, (inFragDepth - FOG_DEPTH_COMPARE_17) * FOG_DEPTH_INVDIFF_18);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_19)\n\
{\n\
fogMixWeight = mix(stateFogDensity[19].g, stateFogDensity[19].r, (inFragDepth - FOG_DEPTH_COMPARE_18) * FOG_DEPTH_INVDIFF_19);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_20)\n\
{\n\
fogMixWeight = mix(stateFogDensity[20].g, stateFogDensity[20].r, (inFragDepth - FOG_DEPTH_COMPARE_19) * FOG_DEPTH_INVDIFF_20);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_21)\n\
{\n\
fogMixWeight = mix(stateFogDensity[21].g, stateFogDensity[21].r, (inFragDepth - FOG_DEPTH_COMPARE_20) * FOG_DEPTH_INVDIFF_21);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_22)\n\
{\n\
fogMixWeight = mix(stateFogDensity[22].g, stateFogDensity[22].r, (inFragDepth - FOG_DEPTH_COMPARE_21) * FOG_DEPTH_INVDIFF_22);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_23)\n\
{\n\
fogMixWeight = mix(stateFogDensity[23].g, stateFogDensity[23].r, (inFragDepth - FOG_DEPTH_COMPARE_22) * FOG_DEPTH_INVDIFF_23);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_24)\n\
{\n\
fogMixWeight = mix(stateFogDensity[24].g, stateFogDensity[24].r, (inFragDepth - FOG_DEPTH_COMPARE_23) * FOG_DEPTH_INVDIFF_24);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_25)\n\
{\n\
fogMixWeight = mix(stateFogDensity[25].g, stateFogDensity[25].r, (inFragDepth - FOG_DEPTH_COMPARE_24) * FOG_DEPTH_INVDIFF_25);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_26)\n\
{\n\
fogMixWeight = mix(stateFogDensity[26].g, stateFogDensity[26].r, (inFragDepth - FOG_DEPTH_COMPARE_25) * FOG_DEPTH_INVDIFF_26);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_27)\n\
{\n\
fogMixWeight = mix(stateFogDensity[27].g, stateFogDensity[27].r, (inFragDepth - FOG_DEPTH_COMPARE_26) * FOG_DEPTH_INVDIFF_27);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_28)\n\
{\n\
fogMixWeight = mix(stateFogDensity[28].g, stateFogDensity[28].r, (inFragDepth - FOG_DEPTH_COMPARE_27) * FOG_DEPTH_INVDIFF_28);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_29)\n\
{\n\
fogMixWeight = mix(stateFogDensity[29].g, stateFogDensity[29].r, (inFragDepth - FOG_DEPTH_COMPARE_28) * FOG_DEPTH_INVDIFF_29);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_30)\n\
{\n\
fogMixWeight = mix(stateFogDensity[30].g, stateFogDensity[30].r, (inFragDepth - FOG_DEPTH_COMPARE_29) * FOG_DEPTH_INVDIFF_30);\n\
}\n\
else if (inFragDepth <= FOG_DEPTH_COMPARE_31)\n\
{\n\
fogMixWeight = mix(stateFogDensity[31].g, stateFogDensity[31].r, (inFragDepth - FOG_DEPTH_COMPARE_30) * FOG_DEPTH_INVDIFF_31);\n\
}\n\
\n\
newFoggedColor = mix(inFragColor, (stateEnableFogAlphaOnly) ? vec4(inFragColor.rgb, stateFogColor.a) : stateFogColor, fogMixWeight);\n\
}\n\
\n\
@ -3130,6 +3005,16 @@ Render3DError OpenGLRenderer_1_2::CreateGeometryPrograms()
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
glGenTextures(1, &OGLRef.texFogDensityTableID);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogDensityTable);
glBindTexture(GL_TEXTURE_1D, OGLRef.texFogDensityTableID);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage1D(GL_TEXTURE_1D, 0, GL_INTENSITY, 32, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glActiveTexture(GL_TEXTURE0);
OGLGeometryFlags programFlags;
programFlags.value = 0;
@ -3254,6 +3139,9 @@ void OpenGLRenderer_1_2::DestroyGeometryPrograms()
glDeleteShader(OGLRef.vertexGeometryShaderID);
OGLRef.vertexGeometryShaderID = 0;
glDeleteTextures(1, &ref->texFogDensityTableID);
OGLRef.texFogDensityTableID = 0;
}
Render3DError OpenGLRenderer_1_2::CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString)
@ -3416,110 +3304,14 @@ Render3DError OpenGLRenderer_1_2::CreateFogProgram(const OGLFogProgramKey fogPro
return error;
}
const u16 fogOffset = fogProgramKey.offset;
const u16 fogShift = (0x0400 >> fogProgramKey.shift);
const GLfloat fogDepthCompare[32] = {
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 1)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 2)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 3)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 4)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 5)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 6)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 7)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 8)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 9)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 10)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 11)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 12)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 13)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 14)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 15)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 16)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 17)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 18)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 19)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 20)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 21)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 22)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 23)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 24)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 25)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 26)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 27)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 28)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 29)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 30)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 31)) / 32767.0f, 1.0f),
std::min<GLfloat>((GLfloat)(fogOffset + (fogShift * 32)) / 32767.0f, 1.0f)
};
const s32 fogOffset = fogProgramKey.offset;
const GLfloat fogOffsetf = (GLfloat)fogOffset / 32767.0f;
const s32 fogStep = 0x0400 >> fogProgramKey.shift;
std::stringstream fragDepthConstants;
fragDepthConstants << "#define FOG_DEPTH_COMPARE_0 " << fogDepthCompare[ 0] << (((fogDepthCompare[ 0] == 0.0f) || (fogDepthCompare[ 0] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_1 " << fogDepthCompare[ 1] << (((fogDepthCompare[ 1] == 0.0f) || (fogDepthCompare[ 1] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_2 " << fogDepthCompare[ 2] << (((fogDepthCompare[ 2] == 0.0f) || (fogDepthCompare[ 2] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_3 " << fogDepthCompare[ 3] << (((fogDepthCompare[ 3] == 0.0f) || (fogDepthCompare[ 3] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_4 " << fogDepthCompare[ 4] << (((fogDepthCompare[ 4] == 0.0f) || (fogDepthCompare[ 4] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_5 " << fogDepthCompare[ 5] << (((fogDepthCompare[ 5] == 0.0f) || (fogDepthCompare[ 5] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_6 " << fogDepthCompare[ 6] << (((fogDepthCompare[ 6] == 0.0f) || (fogDepthCompare[ 6] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_7 " << fogDepthCompare[ 7] << (((fogDepthCompare[ 7] == 0.0f) || (fogDepthCompare[ 7] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_8 " << fogDepthCompare[ 8] << (((fogDepthCompare[ 8] == 0.0f) || (fogDepthCompare[ 8] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_9 " << fogDepthCompare[ 9] << (((fogDepthCompare[ 9] == 0.0f) || (fogDepthCompare[ 9] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_10 " << fogDepthCompare[10] << (((fogDepthCompare[10] == 0.0f) || (fogDepthCompare[10] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_11 " << fogDepthCompare[11] << (((fogDepthCompare[11] == 0.0f) || (fogDepthCompare[11] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_12 " << fogDepthCompare[12] << (((fogDepthCompare[12] == 0.0f) || (fogDepthCompare[12] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_13 " << fogDepthCompare[13] << (((fogDepthCompare[13] == 0.0f) || (fogDepthCompare[13] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_14 " << fogDepthCompare[14] << (((fogDepthCompare[14] == 0.0f) || (fogDepthCompare[14] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_15 " << fogDepthCompare[15] << (((fogDepthCompare[15] == 0.0f) || (fogDepthCompare[15] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_16 " << fogDepthCompare[16] << (((fogDepthCompare[16] == 0.0f) || (fogDepthCompare[16] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_17 " << fogDepthCompare[17] << (((fogDepthCompare[17] == 0.0f) || (fogDepthCompare[17] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_18 " << fogDepthCompare[18] << (((fogDepthCompare[18] == 0.0f) || (fogDepthCompare[18] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_19 " << fogDepthCompare[19] << (((fogDepthCompare[19] == 0.0f) || (fogDepthCompare[19] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_20 " << fogDepthCompare[20] << (((fogDepthCompare[20] == 0.0f) || (fogDepthCompare[20] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_21 " << fogDepthCompare[21] << (((fogDepthCompare[21] == 0.0f) || (fogDepthCompare[21] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_22 " << fogDepthCompare[22] << (((fogDepthCompare[22] == 0.0f) || (fogDepthCompare[22] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_23 " << fogDepthCompare[23] << (((fogDepthCompare[23] == 0.0f) || (fogDepthCompare[23] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_24 " << fogDepthCompare[24] << (((fogDepthCompare[24] == 0.0f) || (fogDepthCompare[24] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_25 " << fogDepthCompare[25] << (((fogDepthCompare[25] == 0.0f) || (fogDepthCompare[25] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_26 " << fogDepthCompare[26] << (((fogDepthCompare[26] == 0.0f) || (fogDepthCompare[26] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_27 " << fogDepthCompare[27] << (((fogDepthCompare[27] == 0.0f) || (fogDepthCompare[27] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_28 " << fogDepthCompare[28] << (((fogDepthCompare[28] == 0.0f) || (fogDepthCompare[28] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_29 " << fogDepthCompare[29] << (((fogDepthCompare[29] == 0.0f) || (fogDepthCompare[29] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_30 " << fogDepthCompare[30] << (((fogDepthCompare[30] == 0.0f) || (fogDepthCompare[30] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_31 " << fogDepthCompare[31] << (((fogDepthCompare[31] == 0.0f) || (fogDepthCompare[31] == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_0 0.0\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_1 (1.0 / (FOG_DEPTH_COMPARE_1 - FOG_DEPTH_COMPARE_0))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_2 (1.0 / (FOG_DEPTH_COMPARE_2 - FOG_DEPTH_COMPARE_1))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_3 (1.0 / (FOG_DEPTH_COMPARE_3 - FOG_DEPTH_COMPARE_2))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_4 (1.0 / (FOG_DEPTH_COMPARE_4 - FOG_DEPTH_COMPARE_3))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_5 (1.0 / (FOG_DEPTH_COMPARE_5 - FOG_DEPTH_COMPARE_4))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_6 (1.0 / (FOG_DEPTH_COMPARE_6 - FOG_DEPTH_COMPARE_5))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_7 (1.0 / (FOG_DEPTH_COMPARE_7 - FOG_DEPTH_COMPARE_6))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_8 (1.0 / (FOG_DEPTH_COMPARE_8 - FOG_DEPTH_COMPARE_7))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_9 (1.0 / (FOG_DEPTH_COMPARE_9 - FOG_DEPTH_COMPARE_8))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_10 (1.0 / (FOG_DEPTH_COMPARE_10 - FOG_DEPTH_COMPARE_9))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_11 (1.0 / (FOG_DEPTH_COMPARE_11 - FOG_DEPTH_COMPARE_10))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_12 (1.0 / (FOG_DEPTH_COMPARE_12 - FOG_DEPTH_COMPARE_11))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_13 (1.0 / (FOG_DEPTH_COMPARE_13 - FOG_DEPTH_COMPARE_12))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_14 (1.0 / (FOG_DEPTH_COMPARE_14 - FOG_DEPTH_COMPARE_13))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_15 (1.0 / (FOG_DEPTH_COMPARE_15 - FOG_DEPTH_COMPARE_14))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_16 (1.0 / (FOG_DEPTH_COMPARE_16 - FOG_DEPTH_COMPARE_15))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_17 (1.0 / (FOG_DEPTH_COMPARE_17 - FOG_DEPTH_COMPARE_16))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_18 (1.0 / (FOG_DEPTH_COMPARE_18 - FOG_DEPTH_COMPARE_17))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_19 (1.0 / (FOG_DEPTH_COMPARE_19 - FOG_DEPTH_COMPARE_18))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_20 (1.0 / (FOG_DEPTH_COMPARE_20 - FOG_DEPTH_COMPARE_19))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_21 (1.0 / (FOG_DEPTH_COMPARE_21 - FOG_DEPTH_COMPARE_20))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_22 (1.0 / (FOG_DEPTH_COMPARE_22 - FOG_DEPTH_COMPARE_21))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_23 (1.0 / (FOG_DEPTH_COMPARE_23 - FOG_DEPTH_COMPARE_22))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_24 (1.0 / (FOG_DEPTH_COMPARE_24 - FOG_DEPTH_COMPARE_23))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_25 (1.0 / (FOG_DEPTH_COMPARE_25 - FOG_DEPTH_COMPARE_24))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_26 (1.0 / (FOG_DEPTH_COMPARE_26 - FOG_DEPTH_COMPARE_25))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_27 (1.0 / (FOG_DEPTH_COMPARE_27 - FOG_DEPTH_COMPARE_26))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_28 (1.0 / (FOG_DEPTH_COMPARE_28 - FOG_DEPTH_COMPARE_27))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_29 (1.0 / (FOG_DEPTH_COMPARE_29 - FOG_DEPTH_COMPARE_28))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_30 (1.0 / (FOG_DEPTH_COMPARE_30 - FOG_DEPTH_COMPARE_29))\n";
fragDepthConstants << "#define FOG_DEPTH_INVDIFF_31 (1.0 / (FOG_DEPTH_COMPARE_31 - FOG_DEPTH_COMPARE_30))\n";
fragDepthConstants << "#define FOG_OFFSET " << fogOffset << "\n";
fragDepthConstants << "#define FOG_OFFSETF " << fogOffsetf << (((fogOffsetf == 0.0f) || (fogOffsetf == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_STEP " << fogStep << "\n";
fragDepthConstants << "\n";
std::string fragShaderCode = fragDepthConstants.str() + std::string(fragShaderCString);
@ -3559,16 +3351,17 @@ Render3DError OpenGLRenderer_1_2::CreateFogProgram(const OGLFogProgramKey fogPro
glValidateProgram(shaderID.program);
glUseProgram(shaderID.program);
const GLint uniformTexGColor = glGetUniformLocation(shaderID.program, "texInFragColor");
const GLint uniformTexGDepth = glGetUniformLocation(shaderID.program, "texInFragDepth");
const GLint uniformTexGFog = glGetUniformLocation(shaderID.program, "texInFogAttributes");
const GLint uniformTexGColor = glGetUniformLocation(shaderID.program, "texInFragColor");
const GLint uniformTexGDepth = glGetUniformLocation(shaderID.program, "texInFragDepth");
const GLint uniformTexGFog = glGetUniformLocation(shaderID.program, "texInFogAttributes");
const GLint uniformTexFogDensityTable = glGetUniformLocation(shaderID.program, "texFogDensityTable");
glUniform1i(uniformTexGColor, OGLTextureUnitID_GColor);
glUniform1i(uniformTexGDepth, OGLTextureUnitID_DepthStencil);
glUniform1i(uniformTexGFog, OGLTextureUnitID_FogAttr);
glUniform1i(uniformTexFogDensityTable, OGLTextureUnitID_FogDensityTable);
OGLRef.uniformStateEnableFogAlphaOnly = glGetUniformLocation(shaderID.program, "stateEnableFogAlphaOnly");
OGLRef.uniformStateFogColor = glGetUniformLocation(shaderID.program, "stateFogColor");
OGLRef.uniformStateFogDensity = glGetUniformLocation(shaderID.program, "stateFogDensity");
OGLRef.uniformStateEnableFogAlphaOnly = glGetUniformLocation(shaderID.program, "stateEnableFogAlphaOnly");
OGLRef.uniformStateFogColor = glGetUniformLocation(shaderID.program, "stateFogColor");
return OGLERROR_NOERR;
}
@ -4507,11 +4300,14 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
this->_pendingRenderStates.fogOffset = (GLfloat)(engine.renderState.fogOffset & 0x7FFF) / 32767.0f;
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> engine.renderState.fogShift) / 32767.0f;
u8 fogDensityTable[32];
for (size_t i = 0; i < 32; i++)
{
this->_pendingRenderStates.fogDensity[i].r = (engine.renderState.fogDensityTable[i] == 127) ? 1.0f : (GLfloat)engine.renderState.fogDensityTable[i] / 128.0f; // Current table value is stored in r
this->_pendingRenderStates.fogDensity[i].g = (i == 0) ? this->_pendingRenderStates.fogDensity[0].r : this->_pendingRenderStates.fogDensity[i-1].r; // Previous table value is stored in g
fogDensityTable[i] = (engine.renderState.fogDensityTable[i] == 127) ? 255 : engine.renderState.fogDensityTable[i] << 1;
}
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogDensityTable);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RED, GL_UNSIGNED_BYTE, fogDensityTable);
}
if (this->_deviceInfo.isEdgeMarkSupported && this->_enableEdgeMark)
@ -4755,7 +4551,6 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
glUseProgram(shaderID.program);
glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, this->_pendingRenderStates.enableFogAlphaOnly);
glUniform4fv(OGLRef.uniformStateFogColor, 1, (const GLfloat *)&this->_pendingRenderStates.fogColor);
glUniform4fv(OGLRef.uniformStateFogDensity, 32, (const GLfloat *)this->_pendingRenderStates.fogDensity);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
@ -5733,11 +5528,14 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
this->_pendingRenderStates.fogOffset = (GLfloat)(engine.renderState.fogOffset & 0x7FFF) / 32767.0f;
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> engine.renderState.fogShift) / 32767.0f;
u8 fogDensityTable[32];
for (size_t i = 0; i < 32; i++)
{
this->_pendingRenderStates.fogDensity[i].r = (engine.renderState.fogDensityTable[i] == 127) ? 1.0f : (GLfloat)engine.renderState.fogDensityTable[i] / 128.0f; // Current table value is stored in r
this->_pendingRenderStates.fogDensity[i].g = (i == 0) ? this->_pendingRenderStates.fogDensity[0].r : this->_pendingRenderStates.fogDensity[i-1].r; // Previous table value is stored in g
fogDensityTable[i] = (engine.renderState.fogDensityTable[i] == 127) ? 255 : engine.renderState.fogDensityTable[i] << 1;
}
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogDensityTable);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RED, GL_UNSIGNED_BYTE, fogDensityTable);
}
if (this->_deviceInfo.isEdgeMarkSupported && this->_enableEdgeMark)

View File

@ -323,7 +323,8 @@ enum OGLTextureUnitID
OGLTextureUnitID_DepthStencil,
OGLTextureUnitID_GPolyID,
OGLTextureUnitID_FogAttr,
OGLTextureUnitID_PolyStates
OGLTextureUnitID_PolyStates,
OGLTextureUnitID_FogDensityTable
};
enum OGLBindingPointID
@ -397,10 +398,9 @@ struct OGLRenderStates
GLuint clearPolyID;
GLfloat clearDepth;
GLfloat alphaTestRef;
GLfloat fogOffset;
GLfloat fogStep;
GLfloat fogOffset; // Currently unused, kept to preserve alignment
GLfloat fogStep; // Currently unused, kept to preserve alignment
GLfloat pad_0; // This needs to be here to preserve alignment
GLvec4 fogDensity[32];
GLvec4 fogColor;
GLvec4 edgeColor[8];
GLvec4 toonColor[32];
@ -522,6 +522,7 @@ struct OGLRenderRef
GLuint texGPolyID;
GLuint texGDepthStencilID;
GLuint texFinalColorID;
GLuint texFogDensityTableID;
GLuint texMSGColorID;
GLuint texMSGWorkingID;
@ -565,7 +566,6 @@ struct OGLRenderRef
GLint uniformStateClearDepth;
GLint uniformStateEdgeColor;
GLint uniformStateFogColor;
GLint uniformStateFogDensity;
GLint uniformStateAlphaTestRef[256];
GLint uniformStateToonColor[256];

View File

@ -200,7 +200,6 @@ layout (std140) uniform RenderStates\n\
float fogOffset;\n\
float fogStep;\n\
float pad_0;\n\
vec4 fogDensity[32];\n\
vec4 fogColor;\n\
vec4 edgeColor[8];\n\
vec4 toonColor[32];\n\
@ -400,7 +399,6 @@ layout (std140) uniform RenderStates\n\
float fogOffset;\n\
float fogStep;\n\
float pad_0;\n\
vec4 fogDensity[32];\n\
vec4 fogColor;\n\
vec4 edgeColor[8];\n\
vec4 toonColor[32];\n\
@ -518,7 +516,6 @@ layout (std140) uniform RenderStates\n\
float fogOffset;\n\
float fogStep;\n\
float pad_0;\n\
vec4 fogDensity[32];\n\
vec4 fogColor;\n\
vec4 edgeColor[8];\n\
vec4 toonColor[32];\n\
@ -526,6 +523,7 @@ layout (std140) uniform RenderStates\n\
\n\
uniform sampler2D texInFragDepth;\n\
uniform sampler2D texInFogAttributes;\n\
uniform sampler1D texFogDensityTable;\n\
\n\
#if USE_DUAL_SOURCE_BLENDING\n\
out vec4 outFogColor;\n\
@ -548,30 +546,18 @@ void main()\n\
vec4 inFogAttributes = texelFetch(texInFogAttributes, ivec2(gl_FragCoord.xy), 0);\n\
bool polyEnableFog = (inFogAttributes.r > 0.999);\n\
\n\
float fogMixWeight = 0.0;\n\
if (FOG_STEP == 0)\n\
{\n\
fogMixWeight = texture( texFogDensityTable, (inFragDepth <= FOG_OFFSETF) ? 0.0 : 1.0 ).r;\n\
}\n\
else\n\
{\n\
fogMixWeight = texture( texFogDensityTable, (inFragDepth * (1024.0/float(FOG_STEP))) + (((-float(FOG_OFFSET)/float(FOG_STEP)) - 0.5) / 32.0) ).r;\n\
}\n\
\n\
if (polyEnableFog)\n\
{\n\
float fogMixWeight = 0.0;\n\
int inFragDepthi = int( (inFragDepth * 32767.0) + 0.5 );\n\
\n\
if (FOG_STEP == 0)\n\
{\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\
#if USE_DUAL_SOURCE_BLENDING\n\
outFogWeight = (state.enableFogAlphaOnly) ? vec4(vec3(0.0), fogMixWeight) : vec4(fogMixWeight);\n\
@ -1200,6 +1186,16 @@ Render3DError OpenGLRenderer_3_2::CreateGeometryPrograms()
}
}
glGenTextures(1, &OGLRef.texFogDensityTableID);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogDensityTable);
glBindTexture(GL_TEXTURE_1D, OGLRef.texFogDensityTableID);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage1D(GL_TEXTURE_1D, 0, GL_R8, 32, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glActiveTexture(GL_TEXTURE0);
OGLGeometryFlags programFlags;
programFlags.value = 0;
@ -1556,13 +1552,9 @@ Render3DError OpenGLRenderer_3_2::CreateFogProgram(const OGLFogProgramKey fogPro
return error;
}
const u32 fogOffset = fogProgramKey.offset;
const u32 fogStep = (0x0400 >> fogProgramKey.shift);
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);
const s32 fogOffset = fogProgramKey.offset;
const GLfloat fogOffsetf = (GLfloat)fogOffset / 32767.0f;
const s32 fogStep = 0x0400 >> fogProgramKey.shift;
std::stringstream shaderHeader;
shaderHeader << "#version 150\n";
@ -1570,12 +1562,9 @@ Render3DError OpenGLRenderer_3_2::CreateFogProgram(const OGLFogProgramKey fogPro
shaderHeader << "\n";
std::stringstream fragDepthConstants;
fragDepthConstants << "#define FOG_DEPTH_COMPARE_0 " << fogDepthCompare0 << (((fogDepthCompare0 == 0.0f) || (fogDepthCompare0 == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_DEPTH_COMPARE_31 " << fogDepthCompare31 << (((fogDepthCompare31 == 0.0f) || (fogDepthCompare31 == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_OFFSET " << fogOffset << "\n";
fragDepthConstants << "#define FOG_OFFSETF " << fogOffsetf << (((fogOffsetf == 0.0f) || (fogOffsetf == 1.0f)) ? ".0" : "") << "\n";
fragDepthConstants << "#define FOG_STEP " << fogStep << "\n";
fragDepthConstants << "#define FOG_SHIFT_INV " << fogShiftInv << "\n";
fragDepthConstants << "#define FOG_WEIGHT_TRUNCATE_MASK " << fogWeightTruncateMask << "\n";
fragDepthConstants << "\n";
std::string vtxShaderCode = shaderHeader.str() + std::string(vtxShaderCString);
@ -1628,10 +1617,12 @@ Render3DError OpenGLRenderer_3_2::CreateFogProgram(const OGLFogProgramKey fogPro
const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(shaderID.program, "RenderStates");
glUniformBlockBinding(shaderID.program, uniformBlockRenderStates, OGLBindingPointID_RenderStates);
const GLint uniformTexGDepth = glGetUniformLocation(shaderID.program, "texInFragDepth");
const GLint uniformTexGFog = glGetUniformLocation(shaderID.program, "texInFogAttributes");
const GLint uniformTexGDepth = glGetUniformLocation(shaderID.program, "texInFragDepth");
const GLint uniformTexGFog = glGetUniformLocation(shaderID.program, "texInFogAttributes");
const GLint uniformTexFogDensityTable = glGetUniformLocation(shaderID.program, "texFogDensityTable");
glUniform1i(uniformTexGDepth, OGLTextureUnitID_DepthStencil);
glUniform1i(uniformTexGFog, OGLTextureUnitID_FogAttr);
glUniform1i(uniformTexFogDensityTable, OGLTextureUnitID_FogDensityTable);
if (!this->_isDualSourceBlendingSupported)
{
@ -2114,11 +2105,14 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
this->_pendingRenderStates.fogOffset = (GLfloat)(engine.renderState.fogOffset & 0x7FFF) / 32767.0f;
this->_pendingRenderStates.fogStep = (GLfloat)(0x0400 >> engine.renderState.fogShift) / 32767.0f;
u8 fogDensityTable[32];
for (size_t i = 0; i < 32; i++)
{
this->_pendingRenderStates.fogDensity[i].r = (engine.renderState.fogDensityTable[i] == 127) ? 1.0f : (GLfloat)engine.renderState.fogDensityTable[i] / 128.0f; // Current table value is stored in r
this->_pendingRenderStates.fogDensity[i].g = (i == 0) ? this->_pendingRenderStates.fogDensity[0].r : this->_pendingRenderStates.fogDensity[i-1].r; // Previous table value is stored in g
fogDensityTable[i] = (engine.renderState.fogDensityTable[i] == 127) ? 255 : engine.renderState.fogDensityTable[i] << 1;
}
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogDensityTable);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RED, GL_UNSIGNED_BYTE, fogDensityTable);
}
if (this->_enableEdgeMark)