Fixed so spot lights work again on GLES

This commit is contained in:
Emile Belanger 2021-08-24 21:40:13 +01:00
parent 981fe9d1eb
commit 327ade4819
4 changed files with 36 additions and 19 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)
{
@ -119,13 +124,23 @@ 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;
}
ShaderFlavourData flavour;
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;
}
}
}
flavour.textureMode = (mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
@ -198,14 +213,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);
@ -317,13 +328,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

@ -714,14 +714,13 @@ bool FShader::Bind(ShaderFlavourData& flavour)
variantConfig.AppendFormat("#define DEF_NPOT_EMULATION %d\n", flavour.npotEmulation);
#endif
// Printf("Shader: %s, %08x %s", mFragProg2.GetChars(), tag, variantConfig.GetChars());
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

@ -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