Fix spot lights for GLES

This commit is contained in:
Emile Belanger 2021-09-20 20:51:56 +01:00 committed by Rachael Alexanderson
parent e361ff1a9c
commit 76875f0a3c
5 changed files with 50 additions and 30 deletions

View file

@ -92,11 +92,16 @@ bool FGLRenderState::ApplyShader()
{
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
ShaderFlavourData flavour;
// Need to calc light data now in order to select correct shader
float* lightPtr = NULL;
int modLights = 0;
int subLights = 0;
int addLights = 0;
int totalLights = 0;
flavour.hasSpotLight = false;
if (mLightIndex >= 0)
{
@ -120,12 +125,24 @@ bool FGLRenderState::ApplyShader()
if (modLights + subLights + addLights > gles.maxlights)
addLights = gles.maxlights - modLights - subLights;
totalLights = modLights + subLights + addLights;
// Skip passed the first 4 floats so the upload below only contains light data
lightPtr += 4;
float* findSpotsPtr = lightPtr + 11; // The 11th float contains '1' if the light is a spot light, see hw_dynlightdata.cpp
for (int n = 0; n < totalLights; n++)
{
if (*findSpotsPtr > 0) // This is a spot light
{
flavour.hasSpotLight = true;
break;
}
findSpotsPtr += LIGHT_VEC4_NUM * 4;
}
}
ShaderFlavourData flavour;
flavour.textureMode = (mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode) & 0xff;
if (mTextureClamp && flavour.textureMode == TM_NORMAL) flavour.textureMode = 5; // fixme. Clamp can now be combined with all modes.
@ -199,14 +216,10 @@ bool FGLRenderState::ApplyShader()
if (mHwUniforms)
{
//matrixToGL(mHwUniforms->mProjectionMatrix, activeShader->cur->ProjectionMatrix_index);
activeShader->cur->muProjectionMatrix.Set(&mHwUniforms->mProjectionMatrix);
activeShader->cur->muViewMatrix.Set(&mHwUniforms->mViewMatrix);
activeShader->cur->muNormalViewMatrix.Set(&mHwUniforms->mNormalViewMatrix);
//matrixToGL(mHwUniforms->mViewMatrix, activeShader->cur->ViewMatrix_index);
//matrixToGL(mHwUniforms->mNormalViewMatrix, activeShader->cur->NormalViewMatrix_index);
activeShader->cur->muCameraPos.Set(&mHwUniforms->mCameraPos.X);
activeShader->cur->muClipLine.Set(&mHwUniforms->mClipLine.X);
@ -318,13 +331,9 @@ bool FGLRenderState::ApplyShader()
// Upload the light data
if (mLightIndex >= 0)
{
int totalLights = modLights + subLights + addLights;
// Calculate the total number of vec4s we need
int totalVectors = totalLights * LIGHT_VEC4_NUM;
// TODO!!! If there are too many lights we need to remove some of the lights and modify the data
// At the moment the shader will just try to read off the end of the array...
if (totalVectors > gles.numlightvectors)
totalVectors = gles.numlightvectors;

View file

@ -633,11 +633,11 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char *
char stringbuf[20];
mysnprintf(stringbuf, 20, "texture%d", i);
int tempindex = glGetUniformLocation(shaderData->hShader, stringbuf);
if (tempindex > 0) glUniform1i(tempindex, i - 1);
if (tempindex >= 0) glUniform1i(tempindex, i - 1);
}
int shadowmapindex = glGetUniformLocation(shaderData->hShader, "ShadowMap");
if (shadowmapindex > 0) glUniform1i(shadowmapindex, 16);
if (shadowmapindex >= 0) glUniform1i(shadowmapindex, 16);
glUseProgram(0);
@ -654,13 +654,17 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char *
FShader::~FShader()
{
/*
glDeleteProgram(hShader);
if (hVertProg != 0)
glDeleteShader(hVertProg);
if (hFragProg != 0)
glDeleteShader(hFragProg);
*/
std::map<uint32_t, ShaderVariantData*>::iterator it = variants.begin();
while (it != variants.end())
{
glDeleteProgram(it->second->hShader);
if (it->second->hVertProg != 0)
glDeleteShader(it->second->hVertProg);
if (it->second->hFragProg != 0)
glDeleteShader(it->second->hFragProg);
it++;
}
}
@ -710,14 +714,13 @@ bool FShader::Bind(ShaderFlavourData& flavour)
variantConfig.AppendFormat("#define DEF_NPOT_EMULATION %d\n", flavour.npotEmulation);
#endif
variantConfig.AppendFormat("#define DEF_HAS_SPOTLIGHT %d\n", flavour.hasSpotLight);
//Printf("Shader: %s, %08x %s", mFragProg2.GetChars(), tag, variantConfig.GetChars());
Load(mName.GetChars(), mVertProg, mFragProg, mFragProg2, mLightProg, mDefinesBase + variantConfig);
if (variants.insert(std::make_pair(tag, cur)).second == false)
{
Printf("ERROR INSERTING");
}
variants.insert(std::make_pair(tag, cur));
}
else
{

View file

@ -275,6 +275,8 @@ public:
#ifdef NPOT_EMULATION
bool npotEmulation;
#endif
bool hasSpotLight;
};
class FShader
@ -417,6 +419,9 @@ public:
#ifdef NPOT_EMULATION
tag |= (flavour.npotEmulation & 1) << 22;
#endif
tag |= (flavour.hasSpotLight & 1) << 23;
return tag;
}

View file

@ -127,8 +127,5 @@ void main()
ClipDistanceA = vec4(ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3);
ClipDistanceB = vec4(ClipDistance4, 0.0, 0.0, 0.0);
//gl_PointSize = 1.0;
gl_Position = ProjectionMatrix * eyeCoordPos;
}

View file

@ -19,7 +19,13 @@ vec3 lightContribution(int i, vec3 normal)
float attenuation = clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0);
// NOTE, all spot light stuff gone
#if (DEF_HAS_SPOTLIGHT == 1) // Only perform test below if there are ANY spot lights on this surface.
if (lightspot1.w == 1.0)
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
#endif
return lightcolor.rgb * attenuation;
/*
@ -55,7 +61,7 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
// modulated lights
// Some very old GLES2 hardward does not allow non-constants in a for-loop expression because it can not unroll it.
// However they do allow 'break' and use stupid hack
// However they do allow 'break', so use stupid hack
#if (USE_GLSL_V100 == 1)
for(int i = 0; i < 8; i++) // Max 8 lights