mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-04-24 00:21:06 +00:00
Optimise lights to create separate shaders for different combinations. Code cleanup
This commit is contained in:
parent
d333e46a45
commit
0dca516719
6 changed files with 122 additions and 70 deletions
|
@ -109,7 +109,24 @@ bool FGLRenderState::ApplyShader()
|
|||
}
|
||||
}
|
||||
|
||||
// Need to calc light data now in order to select correct shader
|
||||
float* lightPtr = NULL;
|
||||
int modLights = 0;
|
||||
int subLights = 0;
|
||||
int addLights = 0;
|
||||
|
||||
if (mLightIndex >= 0)
|
||||
{
|
||||
lightPtr = ((float*)screen->mLights->GetBuffer()->Memory());
|
||||
lightPtr += ((int64_t)mLightIndex * 4);
|
||||
//float array[64];
|
||||
//memcpy(array, ptr, 4 * 64);
|
||||
|
||||
// Calculate how much light data there is to upload, this is stored in the first 4 floats
|
||||
modLights = int(lightPtr[1]) / LIGHT_VEC4_NUM;
|
||||
subLights = (int(lightPtr[2]) - int(lightPtr[1])) / LIGHT_VEC4_NUM;
|
||||
addLights = (int(lightPtr[3]) - int(lightPtr[2])) / LIGHT_VEC4_NUM;
|
||||
}
|
||||
|
||||
if (mSpecialEffect > EFF_NONE)
|
||||
{
|
||||
|
@ -119,43 +136,46 @@ bool FGLRenderState::ApplyShader()
|
|||
{
|
||||
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : SHADER_NoTexture, mAlphaThreshold >= 0.f, mPassType);
|
||||
|
||||
int textureMode = (mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
|
||||
ShaderFlavourData flavour;
|
||||
|
||||
flavour.textureMode = (mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
|
||||
|
||||
int texFlags = mTextureModeFlags; if (!mBrightmapEnabled) texFlags &= ~(TEXF_Brightmap | TEXF_Glowmap);
|
||||
texFlags >>= 16; //Move flags to start of word
|
||||
flavour.texFlags = mTextureModeFlags; if (!mBrightmapEnabled) flavour.texFlags &= ~(TEXF_Brightmap | TEXF_Glowmap);
|
||||
flavour.texFlags >>= 16; //Move flags to start of word
|
||||
|
||||
int blendFlags = (int)(mStreamData.uTextureAddColor.a + 0.01);
|
||||
flavour.blendFlags = (int)(mStreamData.uTextureAddColor.a + 0.01);
|
||||
|
||||
bool twoDFog = false;
|
||||
bool fogEnabled = false;
|
||||
bool fogEquationRadial = false;
|
||||
bool colouredFog = false;
|
||||
flavour.twoDFog = false;
|
||||
flavour.fogEnabled = false;
|
||||
flavour.fogEquationRadial = false;
|
||||
flavour.colouredFog = false;
|
||||
|
||||
if (mFogEnabled)
|
||||
{
|
||||
if (mFogEnabled == 2)
|
||||
{
|
||||
twoDFog = true;
|
||||
flavour.twoDFog = true;
|
||||
}
|
||||
else if(gl_fogmode)
|
||||
{
|
||||
fogEnabled = true;
|
||||
flavour.fogEnabled = true;
|
||||
|
||||
if (gl_fogmode == 2)
|
||||
fogEquationRadial = true;
|
||||
flavour.fogEquationRadial = true;
|
||||
|
||||
if ((GetFogColor() & 0xffffff) != 0)
|
||||
colouredFog = true;
|
||||
flavour.colouredFog = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool doDesaturate = false;
|
||||
doDesaturate = mStreamData.uDesaturationFactor != 0;
|
||||
flavour.doDesaturate = mStreamData.uDesaturationFactor != 0;
|
||||
|
||||
bool dynLights = false;
|
||||
dynLights = (mLightIndex >= 0);
|
||||
// Yes create shaders for all combinations of active lights to avoid more branches
|
||||
flavour.dynLightsMod = (modLights > 0);
|
||||
flavour.dynLightsSub = (subLights > 0);
|
||||
flavour.dynLightsAdd = (addLights > 0);
|
||||
|
||||
activeShader->Bind(textureMode, texFlags, blendFlags, twoDFog, fogEnabled, fogEquationRadial, colouredFog, doDesaturate, dynLights);
|
||||
activeShader->Bind(flavour);
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,15 +280,20 @@ bool FGLRenderState::ApplyShader()
|
|||
matrixToGL(identityMatrix, activeShader->cur->normalmodelmatrix_index);
|
||||
}
|
||||
|
||||
// Upload the light data
|
||||
if (mLightIndex >= 0)
|
||||
{
|
||||
int totalLights = modLights + subLights + addLights;
|
||||
|
||||
float* ptr = ((float*)screen->mLights->GetBuffer()->Memory());
|
||||
ptr += ((int64_t)mLightIndex * 4);
|
||||
float array[64];
|
||||
memcpy(array, ptr, 4 * 64);
|
||||
// Calculate the total number of vec4s we need
|
||||
int totalVectors = totalLights * LIGHT_VEC4_NUM + 1;
|
||||
|
||||
// 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;
|
||||
|
||||
glUniform4fv(activeShader->cur->lights_index, 64, ptr);
|
||||
glUniform4fv(activeShader->cur->lights_index, totalVectors, lightPtr);
|
||||
|
||||
activeShader->cur->muLightIndex.Set(0);
|
||||
}
|
||||
|
|
|
@ -247,8 +247,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char *
|
|||
precision mediump int;
|
||||
precision mediump float;
|
||||
|
||||
// This must match the HWViewpointUniforms struct
|
||||
|
||||
// light buffers
|
||||
uniform vec4 lights[MAXIMUM_LIGHT_VECTORS];
|
||||
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 NormalViewMatrix;
|
||||
|
@ -311,9 +312,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char *
|
|||
uniform mat4 NormalModelMatrix;
|
||||
uniform mat4 TextureMatrix;
|
||||
|
||||
// light buffers
|
||||
uniform vec4 lights[128];
|
||||
|
||||
|
||||
|
||||
// textures
|
||||
uniform sampler2D tex;
|
||||
|
@ -646,9 +645,9 @@ FShader::~FShader()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FShader::Bind(int textureMode, int texFlags, int blendFlags, bool twoDFog, bool fogEnabled, bool fogEquationRadial, bool colouredFog, bool doDesaturate, bool dynLights)
|
||||
bool FShader::Bind(ShaderFlavourData& flavour)
|
||||
{
|
||||
uint32_t tag = CreateShaderTag(textureMode, texFlags, blendFlags, twoDFog, fogEnabled, fogEquationRadial, colouredFog, doDesaturate, dynLights);
|
||||
uint32_t tag = CreateShaderTag(flavour);
|
||||
|
||||
|
||||
cur = variants[tag];
|
||||
|
@ -656,16 +655,20 @@ bool FShader::Bind(int textureMode, int texFlags, int blendFlags, bool twoDFog,
|
|||
if (!cur)
|
||||
{
|
||||
FString variantConfig = "\n";
|
||||
variantConfig.AppendFormat("#define DEF_TEXTURE_MODE %d\n", textureMode);
|
||||
variantConfig.AppendFormat("#define DEF_TEXTURE_FLAGS %d\n", texFlags);
|
||||
variantConfig.AppendFormat("#define DEF_BLEND_FLAGS %d\n", blendFlags);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_2D %d\n", twoDFog);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_ENABLED %d\n", fogEnabled);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_RADIAL %d\n", fogEquationRadial);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_COLOURED %d\n", colouredFog);
|
||||
|
||||
variantConfig.AppendFormat("#define MAXIMUM_LIGHT_VECTORS %d\n", gles.numlightvectors);
|
||||
variantConfig.AppendFormat("#define DEF_TEXTURE_MODE %d\n", flavour.textureMode);
|
||||
variantConfig.AppendFormat("#define DEF_TEXTURE_FLAGS %d\n", flavour.texFlags);
|
||||
variantConfig.AppendFormat("#define DEF_BLEND_FLAGS %d\n", flavour.blendFlags);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_2D %d\n", flavour.twoDFog);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_ENABLED %d\n", flavour.fogEnabled);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_RADIAL %d\n", flavour.fogEquationRadial);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_COLOURED %d\n", flavour.colouredFog);
|
||||
|
||||
variantConfig.AppendFormat("#define DEF_DO_DESATURATE %d\n", doDesaturate);
|
||||
variantConfig.AppendFormat("#define DEF_DYNAMIC_LIGHTS %d\n", dynLights);
|
||||
variantConfig.AppendFormat("#define DEF_DO_DESATURATE %d\n", flavour.doDesaturate);
|
||||
variantConfig.AppendFormat("#define DEF_DYNAMIC_LIGHTS_MOD %d\n", flavour.dynLightsMod);
|
||||
variantConfig.AppendFormat("#define DEF_DYNAMIC_LIGHTS_SUB %d\n", flavour.dynLightsSub);
|
||||
variantConfig.AppendFormat("#define DEF_DYNAMIC_LIGHTS_ADD %d\n", flavour.dynLightsAdd);
|
||||
|
||||
Printf("Shader: %s", variantConfig.GetChars());
|
||||
|
||||
|
@ -879,7 +882,8 @@ FShader *FShaderCollection::BindEffect(int effect)
|
|||
{
|
||||
if (effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[effect] != NULL)
|
||||
{
|
||||
mEffectShaders[effect]->Bind(0,0,0,0,0,0,0,0,0);
|
||||
ShaderFlavourData flavour;
|
||||
mEffectShaders[effect]->Bind(flavour);
|
||||
return mEffectShaders[effect];
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -249,6 +249,22 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class ShaderFlavourData
|
||||
{
|
||||
public:
|
||||
int textureMode;
|
||||
int texFlags;
|
||||
int blendFlags;
|
||||
bool twoDFog;
|
||||
bool fogEnabled;
|
||||
bool fogEquationRadial;
|
||||
bool colouredFog;
|
||||
bool doDesaturate;
|
||||
bool dynLightsMod;
|
||||
bool dynLightsSub;
|
||||
bool dynLightsAdd;
|
||||
};
|
||||
|
||||
class FShader
|
||||
{
|
||||
friend class FShaderCollection;
|
||||
|
@ -353,28 +369,33 @@ public:
|
|||
|
||||
void LoadVariant();
|
||||
|
||||
uint32_t CreateShaderTag(int textureMode, int texf, int blendFlags, bool twoDFog, bool fogEnabled, bool fogEquationRadial, bool colouredFog, bool doDesaturate, bool dynLights)
|
||||
|
||||
|
||||
|
||||
uint32_t CreateShaderTag(ShaderFlavourData &flavour)
|
||||
{
|
||||
uint32_t tag = 0;
|
||||
tag |= (textureMode & 0x7);
|
||||
tag |= (flavour.textureMode & 0x7);
|
||||
|
||||
tag |= (texf & 7) << 3;
|
||||
tag |= (flavour.texFlags & 7) << 3;
|
||||
|
||||
tag |= (blendFlags & 7) << 6;
|
||||
tag |= (flavour.blendFlags & 7) << 6;
|
||||
|
||||
tag |= (twoDFog & 1) << 7;
|
||||
tag |= (fogEnabled & 1) << 8;
|
||||
tag |= (fogEquationRadial & 1) << 9;
|
||||
tag |= (colouredFog & 1) << 10;
|
||||
tag |= (flavour.twoDFog & 1) << 7;
|
||||
tag |= (flavour.fogEnabled & 1) << 8;
|
||||
tag |= (flavour.fogEquationRadial & 1) << 9;
|
||||
tag |= (flavour.colouredFog & 1) << 10;
|
||||
|
||||
tag |= (doDesaturate & 1) << 11;
|
||||
tag |= (flavour.doDesaturate & 1) << 11;
|
||||
|
||||
tag |= (dynLights & 1) << 12;
|
||||
tag |= (flavour.dynLightsMod & 1) << 12;
|
||||
tag |= (flavour.dynLightsSub & 1) << 13;
|
||||
tag |= (flavour.dynLightsAdd & 1) << 14;
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
bool Bind(int textureMode, int texFlags, int blendFlags, bool twoDFog, bool fogEnabled, bool fogEquationRadial, bool colouredFog, bool doDesaturate, bool dynLights);
|
||||
bool Bind(ShaderFlavourData& flavour);
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -103,6 +103,8 @@ namespace OpenGLESRenderer
|
|||
gles.max_texturesize = 1024 * 4;
|
||||
gles.modelstring = (char*)"MODEL";
|
||||
gles.vendorstring = (char*)"EMILES";
|
||||
gles.maxlights = 32;
|
||||
gles.numlightvectors = (gles.maxlights * 4) + 1; // maxlights lights, + size vector at the beginning
|
||||
}
|
||||
|
||||
}
|
|
@ -36,6 +36,9 @@
|
|||
#include <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
|
||||
// This is the number of vec4s make up the light data
|
||||
#define LIGHT_VEC4_NUM 4
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
struct RenderContextGLES
|
||||
|
@ -44,6 +47,8 @@ namespace OpenGLESRenderer
|
|||
unsigned int maxuniforms;
|
||||
unsigned int maxuniformblock;
|
||||
unsigned int uniformblockalignment;
|
||||
unsigned int maxlights;
|
||||
unsigned int numlightvectors;
|
||||
float glslversion;
|
||||
int max_texturesize;
|
||||
char* vendorstring;
|
||||
|
|
|
@ -42,29 +42,27 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
|||
vec4 dynlight = uDynLightColor;
|
||||
vec3 normal = material.Normal;
|
||||
|
||||
#if (DEF_DYNAMIC_LIGHTS == 1)
|
||||
|
||||
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
||||
|
||||
//if (lightRange.z > lightRange.x)
|
||||
#if (DEF_DYNAMIC_LIGHTS_MOD == 1)
|
||||
// modulated lights
|
||||
for(int i=lightRange.x; i<lightRange.y; i+=4)
|
||||
{
|
||||
// modulated lights
|
||||
for(int i=lightRange.x; i<lightRange.y; i+=4)
|
||||
{
|
||||
dynlight.rgb += lightContribution(i, normal);
|
||||
}
|
||||
|
||||
// subtractive lights
|
||||
for(int i=lightRange.y; i<lightRange.z; i+=4)
|
||||
{
|
||||
dynlight.rgb -= lightContribution(i, normal);
|
||||
}
|
||||
dynlight.rgb += lightContribution(i, normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (DEF_DYNAMIC_LIGHTS_SUB == 1)
|
||||
// subtractive lights
|
||||
for(int i=lightRange.y; i<lightRange.z; i+=4)
|
||||
{
|
||||
dynlight.rgb -= lightContribution(i, normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||
|
||||
//if (lightRange.w > lightRange.z)
|
||||
{
|
||||
#if (DEF_DYNAMIC_LIGHTS_ADD == 1)
|
||||
vec4 addlight = vec4(0.0,0.0,0.0,0.0);
|
||||
|
||||
// additive lights
|
||||
|
@ -74,10 +72,7 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
|||
}
|
||||
|
||||
frag = clamp(frag + desaturate(addlight).rgb, 0.0, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return frag;
|
||||
#else
|
||||
return material.Base.rgb * clamp(color, 0.0, 1.4);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue