Optimizations and changes in OpenGL 2.1 device.
* Limited number of lights to 4 * Only directional lights * Per-pixel lighting * Improved dynamic shadows a bitdev-buzzingcars
parent
7b3b257580
commit
9bdd83771e
|
@ -242,7 +242,7 @@ bool CGL21Device::Create()
|
||||||
glViewport(0, 0, m_config.size.x, m_config.size.y);
|
glViewport(0, 0, m_config.size.x, m_config.size.y);
|
||||||
|
|
||||||
// this is set in shader
|
// this is set in shader
|
||||||
int numLights = 8;
|
int numLights = 4;
|
||||||
|
|
||||||
m_lights = std::vector<Light>(numLights, Light());
|
m_lights = std::vector<Light>(numLights, Light());
|
||||||
m_lightsEnabled = std::vector<bool> (numLights, false);
|
m_lightsEnabled = std::vector<bool> (numLights, false);
|
||||||
|
@ -408,7 +408,7 @@ bool CGL21Device::Create()
|
||||||
uni.fogColor = glGetUniformLocation(m_normalProgram, "uni_FogColor");
|
uni.fogColor = glGetUniformLocation(m_normalProgram, "uni_FogColor");
|
||||||
|
|
||||||
uni.shadowColor = glGetUniformLocation(m_normalProgram, "uni_ShadowColor");
|
uni.shadowColor = glGetUniformLocation(m_normalProgram, "uni_ShadowColor");
|
||||||
uni.lightingEnabled = glGetUniformLocation(m_normalProgram, "uni_LightingEnabled");
|
uni.lightCount = glGetUniformLocation(m_normalProgram, "uni_LightCount");
|
||||||
|
|
||||||
uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_Material.ambient");
|
uni.ambientColor = glGetUniformLocation(m_normalProgram, "uni_Material.ambient");
|
||||||
uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_Material.diffuse");
|
uni.diffuseColor = glGetUniformLocation(m_normalProgram, "uni_Material.diffuse");
|
||||||
|
@ -417,12 +417,6 @@ bool CGL21Device::Create()
|
||||||
GLchar name[64];
|
GLchar name[64];
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
sprintf(name, "uni_Light[%d].Enabled", i);
|
|
||||||
uni.lights[i].enabled = glGetUniformLocation(m_normalProgram, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Type", i);
|
|
||||||
uni.lights[i].type = glGetUniformLocation(m_normalProgram, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Position", i);
|
sprintf(name, "uni_Light[%d].Position", i);
|
||||||
uni.lights[i].position = glGetUniformLocation(m_normalProgram, name);
|
uni.lights[i].position = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
|
||||||
|
@ -434,18 +428,6 @@ bool CGL21Device::Create()
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Specular", i);
|
sprintf(name, "uni_Light[%d].Specular", i);
|
||||||
uni.lights[i].specular = glGetUniformLocation(m_normalProgram, name);
|
uni.lights[i].specular = glGetUniformLocation(m_normalProgram, name);
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Attenuation", i);
|
|
||||||
uni.lights[i].attenuation = glGetUniformLocation(m_normalProgram, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].SpotDirection", i);
|
|
||||||
uni.lights[i].spotDirection = glGetUniformLocation(m_normalProgram, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].Exponent", i);
|
|
||||||
uni.lights[i].spotExponent = glGetUniformLocation(m_normalProgram, name);
|
|
||||||
|
|
||||||
sprintf(name, "uni_Light[%d].SpotCutoff", i);
|
|
||||||
uni.lights[i].spotCutoff = glGetUniformLocation(m_normalProgram, name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default uniform values
|
// Set default uniform values
|
||||||
|
@ -476,10 +458,7 @@ bool CGL21Device::Create()
|
||||||
|
|
||||||
glUniform1f(uni.shadowColor, 0.5f);
|
glUniform1f(uni.shadowColor, 0.5f);
|
||||||
|
|
||||||
glUniform1i(uni.lightingEnabled, 0);
|
glUniform1i(uni.lightCount, 0);
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
glUniform1i(uni.lights[i].enabled, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain uniform locations from interface rendering program and initialize them
|
// Obtain uniform locations from interface rendering program and initialize them
|
||||||
|
@ -594,6 +573,7 @@ void CGL21Device::ConfigChanged(const DeviceConfig& newConfig)
|
||||||
|
|
||||||
// Reset state
|
// Reset state
|
||||||
m_lighting = false;
|
m_lighting = false;
|
||||||
|
m_updateLights = true;
|
||||||
|
|
||||||
glViewport(0, 0, m_config.size.x, m_config.size.y);
|
glViewport(0, 0, m_config.size.x, m_config.size.y);
|
||||||
|
|
||||||
|
@ -721,36 +701,7 @@ void CGL21Device::SetLight(int index, const Light &light)
|
||||||
|
|
||||||
m_lights[index] = light;
|
m_lights[index] = light;
|
||||||
|
|
||||||
LightLocations &loc = m_uniforms[m_mode].lights[index];
|
m_updateLights = true;
|
||||||
|
|
||||||
glUniform4fv(loc.ambient, 1, light.ambient.Array());
|
|
||||||
glUniform4fv(loc.diffuse, 1, light.diffuse.Array());
|
|
||||||
glUniform4fv(loc.specular, 1, light.specular.Array());
|
|
||||||
glUniform3f(loc.attenuation, light.attenuation0, light.attenuation1, light.attenuation2);
|
|
||||||
|
|
||||||
if (light.type == LIGHT_DIRECTIONAL)
|
|
||||||
{
|
|
||||||
glUniform1i(loc.type, 1);
|
|
||||||
glUniform4f(loc.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
|
|
||||||
}
|
|
||||||
else if (light.type == LIGHT_POINT)
|
|
||||||
{
|
|
||||||
glUniform1i(loc.type, 2);
|
|
||||||
glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f);
|
|
||||||
|
|
||||||
glUniform3f(loc.spotDirection, 0.0f, 1.0f, 0.0f);
|
|
||||||
glUniform1f(loc.spotCutoff, -1.0f);
|
|
||||||
glUniform1f(loc.spotExponent, 1.0f);
|
|
||||||
}
|
|
||||||
else if (light.type == LIGHT_SPOT)
|
|
||||||
{
|
|
||||||
glUniform1i(loc.type, 3);
|
|
||||||
glUniform4f(loc.position, light.position.x, light.position.y, light.position.z, 1.0f);
|
|
||||||
|
|
||||||
glUniform3f(loc.spotDirection, -light.direction.x, -light.direction.y, -light.direction.z);
|
|
||||||
glUniform1f(loc.spotCutoff, std::cos(light.spotAngle));
|
|
||||||
glUniform1f(loc.spotExponent, light.spotIntensity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL21Device::SetLightEnabled(int index, bool enabled)
|
void CGL21Device::SetLightEnabled(int index, bool enabled)
|
||||||
|
@ -760,7 +711,7 @@ void CGL21Device::SetLightEnabled(int index, bool enabled)
|
||||||
|
|
||||||
m_lightsEnabled[index] = enabled;
|
m_lightsEnabled[index] = enabled;
|
||||||
|
|
||||||
glUniform1i(m_uniforms[m_mode].lights[index].enabled, enabled ? 1 : 0);
|
m_updateLights = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If image is invalid, returns invalid texture.
|
/** If image is invalid, returns invalid texture.
|
||||||
|
@ -798,12 +749,13 @@ Texture CGL21Device::CreateTexture(ImageData *data, const TextureCreateParams &p
|
||||||
|
|
||||||
result.originalSize = result.size;
|
result.originalSize = result.size;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
glGenTextures(1, &result.id);
|
glGenTextures(1, &result.id);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, result.id);
|
glBindTexture(GL_TEXTURE_2D, result.id);
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
// Set texture parameters
|
// Set texture parameters
|
||||||
GLint minF = GL_NEAREST, magF = GL_NEAREST;
|
GLint minF = GL_NEAREST, magF = GL_NEAREST;
|
||||||
int mipmapLevel = 1;
|
int mipmapLevel = 1;
|
||||||
|
@ -991,7 +943,7 @@ void CGL21Device::SetTexture(int index, const Texture &texture)
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||||
|
|
||||||
// Params need to be updated for the new bound texture
|
// Params need to be updated for the new bound texture
|
||||||
UpdateTextureStatus();
|
UpdateTextureState(index);
|
||||||
UpdateTextureParams(index);
|
UpdateTextureParams(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,7 +961,7 @@ void CGL21Device::SetTexture(int index, unsigned int textureId)
|
||||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||||
|
|
||||||
// Params need to be updated for the new bound texture
|
// Params need to be updated for the new bound texture
|
||||||
UpdateTextureStatus();
|
UpdateTextureState(index);
|
||||||
UpdateTextureParams(index);
|
UpdateTextureParams(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,15 +976,54 @@ void CGL21Device::SetTextureEnabled(int index, bool enabled)
|
||||||
if (same)
|
if (same)
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
|
|
||||||
UpdateTextureStatus();
|
UpdateTextureState(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGL21Device::UpdateTextureStatus()
|
void CGL21Device::UpdateTextureState(int index)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
bool enabled = m_texturesEnabled[index] && (m_currentTextures[index].id != 0);
|
||||||
|
glUniform1i(m_uniforms[m_mode].textureEnabled[index], enabled ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGL21Device::UpdateLights()
|
||||||
|
{
|
||||||
|
m_updateLights = false;
|
||||||
|
|
||||||
|
// If not in normal rendering mode, return immediately
|
||||||
|
if (m_mode != 0) return;
|
||||||
|
|
||||||
|
// Lighting enabled
|
||||||
|
if (m_lighting)
|
||||||
{
|
{
|
||||||
bool enabled = m_texturesEnabled[i] && (m_currentTextures[i].id != 0);
|
int index = 0;
|
||||||
glUniform1i(m_uniforms[m_mode].textureEnabled[i], enabled ? 1 : 0);
|
|
||||||
|
// Iterate all lights
|
||||||
|
for (unsigned int i = 0; i < m_lights.size(); i++)
|
||||||
|
{
|
||||||
|
// If disabled, ignore and continue
|
||||||
|
if (!m_lightsEnabled[i]) continue;
|
||||||
|
|
||||||
|
// If not directional, ignore and continue
|
||||||
|
if (m_lights[i].type != LIGHT_DIRECTIONAL) continue;
|
||||||
|
|
||||||
|
Light &light = m_lights[i];
|
||||||
|
LightLocations &uni = m_uniforms[m_mode].lights[index];
|
||||||
|
|
||||||
|
glUniform4fv(uni.ambient, 1, light.ambient.Array());
|
||||||
|
glUniform4fv(uni.diffuse, 1, light.diffuse.Array());
|
||||||
|
glUniform4fv(uni.specular, 1, light.specular.Array());
|
||||||
|
|
||||||
|
glUniform4f(uni.position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
glUniform1i(m_uniforms[m_mode].lightCount, index);
|
||||||
|
}
|
||||||
|
// Lighting disabled
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glUniform1i(m_uniforms[m_mode].lightCount, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1044,6 +1035,12 @@ inline void CGL21Device::BindVBO(GLuint vbo)
|
||||||
m_currentVBO = vbo;
|
m_currentVBO = vbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void CGL21Device::BindTexture(int index, GLuint texture)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + index);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the texture parameters for the given texture stage.
|
Sets the texture parameters for the given texture stage.
|
||||||
If the given texture was not set (bound) yet, nothing happens.
|
If the given texture was not set (bound) yet, nothing happens.
|
||||||
|
@ -1121,6 +1118,8 @@ void CGL21Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode
|
||||||
void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount,
|
void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount,
|
||||||
Color color)
|
Color color)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO(0);
|
BindVBO(0);
|
||||||
|
|
||||||
Vertex* vs = const_cast<Vertex*>(vertices);
|
Vertex* vs = const_cast<Vertex*>(vertices);
|
||||||
|
@ -1148,6 +1147,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int
|
||||||
void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
|
void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
|
||||||
Color color)
|
Color color)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO(0);
|
BindVBO(0);
|
||||||
|
|
||||||
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
|
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
|
||||||
|
@ -1180,6 +1181,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices,
|
||||||
|
|
||||||
void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
|
void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO(0);
|
BindVBO(0);
|
||||||
|
|
||||||
VertexCol* vs = const_cast<VertexCol*>(vertices);
|
VertexCol* vs = const_cast<VertexCol*>(vertices);
|
||||||
|
@ -1199,6 +1202,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
|
||||||
void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices,
|
void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices,
|
||||||
int size, const VertexFormat &format, int vertexCount)
|
int size, const VertexFormat &format, int vertexCount)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO(0);
|
BindVBO(0);
|
||||||
|
|
||||||
const char *ptr = reinterpret_cast<const char*>(vertices);
|
const char *ptr = reinterpret_cast<const char*>(vertices);
|
||||||
|
@ -1277,6 +1282,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices,
|
||||||
void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices,
|
void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices,
|
||||||
int size, const VertexFormat &format, int first[], int count[], int drawCount)
|
int size, const VertexFormat &format, int first[], int count[], int drawCount)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO(0);
|
BindVBO(0);
|
||||||
|
|
||||||
const char *ptr = reinterpret_cast<const char*>(vertices);
|
const char *ptr = reinterpret_cast<const char*>(vertices);
|
||||||
|
@ -1355,6 +1362,8 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices,
|
||||||
void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
|
void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
|
||||||
int first[], int count[], int drawCount, Color color)
|
int first[], int count[], int drawCount, Color color)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO(0);
|
BindVBO(0);
|
||||||
|
|
||||||
Vertex* vs = const_cast<Vertex*>(vertices);
|
Vertex* vs = const_cast<Vertex*>(vertices);
|
||||||
|
@ -1381,6 +1390,8 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
|
||||||
void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
|
void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
|
||||||
int first[], int count[], int drawCount, Color color)
|
int first[], int count[], int drawCount, Color color)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO(0);
|
BindVBO(0);
|
||||||
|
|
||||||
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
|
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
|
||||||
|
@ -1414,6 +1425,8 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
|
||||||
void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
|
void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
|
||||||
int first[], int count[], int drawCount)
|
int first[], int count[], int drawCount)
|
||||||
{
|
{
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO(0);
|
BindVBO(0);
|
||||||
|
|
||||||
VertexCol* vs = const_cast<VertexCol*>(vertices);
|
VertexCol* vs = const_cast<VertexCol*>(vertices);
|
||||||
|
@ -1574,6 +1587,8 @@ void CGL21Device::DrawStaticBuffer(unsigned int bufferId)
|
||||||
if (it == m_vboObjects.end())
|
if (it == m_vboObjects.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (m_updateLights) UpdateLights();
|
||||||
|
|
||||||
BindVBO((*it).second.bufferId);
|
BindVBO((*it).second.bufferId);
|
||||||
|
|
||||||
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
|
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
|
||||||
|
@ -1741,9 +1756,11 @@ void CGL21Device::SetRenderState(RenderState state, bool enabled)
|
||||||
}
|
}
|
||||||
else if (state == RENDER_STATE_LIGHTING)
|
else if (state == RENDER_STATE_LIGHTING)
|
||||||
{
|
{
|
||||||
|
if (m_lighting == enabled) return;
|
||||||
|
|
||||||
m_lighting = enabled;
|
m_lighting = enabled;
|
||||||
|
|
||||||
glUniform1i(m_uniforms[m_mode].lightingEnabled, enabled ? 1 : 0);
|
m_updateLights = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,10 +183,14 @@ public:
|
||||||
private:
|
private:
|
||||||
//! Updates the texture params for given texture stage
|
//! Updates the texture params for given texture stage
|
||||||
void UpdateTextureParams(int index);
|
void UpdateTextureParams(int index);
|
||||||
//! Updates texture status
|
//! Updates texture state
|
||||||
void UpdateTextureStatus();
|
void UpdateTextureState(int index);
|
||||||
|
//! Update light parameters
|
||||||
|
void UpdateLights();
|
||||||
//! Binds VBO
|
//! Binds VBO
|
||||||
inline void BindVBO(GLuint vbo);
|
inline void BindVBO(GLuint vbo);
|
||||||
|
//! Binds texture
|
||||||
|
inline void BindTexture(int index, GLuint texture);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Current config
|
//! Current config
|
||||||
|
@ -208,6 +212,8 @@ private:
|
||||||
|
|
||||||
//! Whether lighting is enabled
|
//! Whether lighting is enabled
|
||||||
bool m_lighting = false;
|
bool m_lighting = false;
|
||||||
|
//! true means that lights need to be updated
|
||||||
|
bool m_updateLights = false;
|
||||||
//! Current lights
|
//! Current lights
|
||||||
std::vector<Light> m_lights;
|
std::vector<Light> m_lights;
|
||||||
//! Current lights enable status
|
//! Current lights enable status
|
||||||
|
|
|
@ -194,8 +194,6 @@ struct UniformLocations
|
||||||
//! Shadow color
|
//! Shadow color
|
||||||
GLint shadowColor = -1;
|
GLint shadowColor = -1;
|
||||||
|
|
||||||
//! true enables lighting
|
|
||||||
GLint lightingEnabled = -1;
|
|
||||||
// Number of enabled lights
|
// Number of enabled lights
|
||||||
GLint lightCount = -1;
|
GLint lightCount = -1;
|
||||||
//! Ambient color
|
//! Ambient color
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
// FRAGMENT SHADER - NORMAL MODE
|
// FRAGMENT SHADER - NORMAL MODE
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
|
#define CONFIG_QUALITY_SHADOWS 1
|
||||||
|
|
||||||
uniform sampler2D uni_PrimaryTexture;
|
uniform sampler2D uni_PrimaryTexture;
|
||||||
uniform sampler2D uni_SecondaryTexture;
|
uniform sampler2D uni_SecondaryTexture;
|
||||||
uniform sampler2DShadow uni_ShadowTexture;
|
uniform sampler2DShadow uni_ShadowTexture;
|
||||||
|
@ -34,6 +36,26 @@ uniform vec4 uni_FogColor;
|
||||||
|
|
||||||
uniform float uni_ShadowColor;
|
uniform float uni_ShadowColor;
|
||||||
|
|
||||||
|
struct LightParams
|
||||||
|
{
|
||||||
|
vec4 Position;
|
||||||
|
vec4 Ambient;
|
||||||
|
vec4 Diffuse;
|
||||||
|
vec4 Specular;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Material
|
||||||
|
{
|
||||||
|
vec4 ambient;
|
||||||
|
vec4 diffuse;
|
||||||
|
vec4 specular;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform Material uni_Material;
|
||||||
|
|
||||||
|
uniform int uni_LightCount;
|
||||||
|
uniform LightParams uni_Light[4];
|
||||||
|
|
||||||
varying float pass_Distance;
|
varying float pass_Distance;
|
||||||
varying vec4 pass_Color;
|
varying vec4 pass_Color;
|
||||||
varying vec3 pass_Normal;
|
varying vec3 pass_Normal;
|
||||||
|
@ -47,6 +69,55 @@ void main()
|
||||||
{
|
{
|
||||||
vec4 color = pass_Color;
|
vec4 color = pass_Color;
|
||||||
|
|
||||||
|
if (uni_LightCount > 0)
|
||||||
|
{
|
||||||
|
vec4 ambient = vec4(0.0f);
|
||||||
|
vec4 diffuse = vec4(0.0f);
|
||||||
|
vec4 specular = vec4(0.0f);
|
||||||
|
|
||||||
|
vec3 normal = normalize(pass_Normal);
|
||||||
|
|
||||||
|
for (int i = 0; i < uni_LightCount; i++)
|
||||||
|
{
|
||||||
|
LightParams light = uni_Light[i];
|
||||||
|
|
||||||
|
vec3 lightDirection = light.Position.xyz;
|
||||||
|
vec3 reflectDirection = -reflect(lightDirection, normal);
|
||||||
|
|
||||||
|
float diffuseComponent = clamp(dot(normal, lightDirection), 0.0f, 1.0f);
|
||||||
|
float specularComponent = clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f);
|
||||||
|
|
||||||
|
ambient += light.Ambient;
|
||||||
|
diffuse += diffuseComponent * light.Diffuse;
|
||||||
|
specular += specularComponent * light.Specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
float shadow = 1.0f;
|
||||||
|
|
||||||
|
if (uni_TextureEnabled[2])
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_QUALITY_SHADOWS
|
||||||
|
float offset = 0.00025f;
|
||||||
|
|
||||||
|
float value = (1.0f / 5.0f) * (shadow2D(uni_ShadowTexture, pass_TexCoord2).x
|
||||||
|
+ shadow2D(uni_ShadowTexture, pass_TexCoord2 + vec3( offset, 0.0f, 0.0f)).x
|
||||||
|
+ shadow2D(uni_ShadowTexture, pass_TexCoord2 + vec3(-offset, 0.0f, 0.0f)).x
|
||||||
|
+ shadow2D(uni_ShadowTexture, pass_TexCoord2 + vec3( 0.0f, offset, 0.0f)).x
|
||||||
|
+ shadow2D(uni_ShadowTexture, pass_TexCoord2 + vec3( 0.0f, -offset, 0.0f)).x);
|
||||||
|
|
||||||
|
shadow = mix(uni_ShadowColor, 1.0f, value);
|
||||||
|
#else
|
||||||
|
shadow = mix(uni_ShadowColor, 1.0f, shadow2D(uni_ShadowTexture, pass_TexCoord2).x);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 result = ambient * uni_Material.ambient
|
||||||
|
+ diffuse * uni_Material.diffuse * shadow
|
||||||
|
+ specular * uni_Material.specular * shadow;
|
||||||
|
|
||||||
|
color = clamp(vec4(result.rgb, 1.0f), 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (uni_TextureEnabled[0])
|
if (uni_TextureEnabled[0])
|
||||||
{
|
{
|
||||||
color = color * texture2D(uni_PrimaryTexture, pass_TexCoord0);
|
color = color * texture2D(uni_PrimaryTexture, pass_TexCoord0);
|
||||||
|
@ -57,16 +128,6 @@ void main()
|
||||||
color = color * texture2D(uni_SecondaryTexture, pass_TexCoord1);
|
color = color * texture2D(uni_SecondaryTexture, pass_TexCoord1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uni_TextureEnabled[2])
|
|
||||||
{
|
|
||||||
vec3 normal = pass_Normal * (2.0f * gl_Color.x - 1.0f);
|
|
||||||
|
|
||||||
if (dot(normal, const_LightDirection) < 0.0f)
|
|
||||||
color.rgb *= uni_ShadowColor;
|
|
||||||
else
|
|
||||||
color.rgb *= mix(uni_ShadowColor, 1.0f, shadow2D(uni_ShadowTexture, pass_TexCoord2).x);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uni_FogEnabled)
|
if (uni_FogEnabled)
|
||||||
{
|
{
|
||||||
float interpolate = (pass_Distance - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x);
|
float interpolate = (pass_Distance - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x);
|
||||||
|
|
|
@ -25,33 +25,6 @@ uniform mat4 uni_ModelMatrix;
|
||||||
uniform mat4 uni_ShadowMatrix;
|
uniform mat4 uni_ShadowMatrix;
|
||||||
uniform mat4 uni_NormalMatrix;
|
uniform mat4 uni_NormalMatrix;
|
||||||
|
|
||||||
struct LightParams
|
|
||||||
{
|
|
||||||
bool Enabled;
|
|
||||||
int Type;
|
|
||||||
vec4 Position;
|
|
||||||
vec4 Ambient;
|
|
||||||
vec4 Diffuse;
|
|
||||||
vec4 Specular;
|
|
||||||
float Shininess;
|
|
||||||
vec3 Attenuation;
|
|
||||||
vec3 SpotDirection;
|
|
||||||
float SpotCutoff;
|
|
||||||
float SpotExponent;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Material
|
|
||||||
{
|
|
||||||
vec4 ambient;
|
|
||||||
vec4 diffuse;
|
|
||||||
vec4 specular;
|
|
||||||
};
|
|
||||||
|
|
||||||
uniform Material uni_Material;
|
|
||||||
|
|
||||||
uniform bool uni_LightingEnabled;
|
|
||||||
uniform LightParams uni_Light[8];
|
|
||||||
|
|
||||||
varying float pass_Distance;
|
varying float pass_Distance;
|
||||||
varying vec4 pass_Color;
|
varying vec4 pass_Color;
|
||||||
varying vec3 pass_Normal;
|
varying vec3 pass_Normal;
|
||||||
|
@ -65,75 +38,11 @@ void main()
|
||||||
vec4 eyeSpace = uni_ViewMatrix * position;
|
vec4 eyeSpace = uni_ViewMatrix * position;
|
||||||
vec4 shadowCoord = uni_ShadowMatrix * position;
|
vec4 shadowCoord = uni_ShadowMatrix * position;
|
||||||
|
|
||||||
vec4 color = gl_Color;
|
|
||||||
|
|
||||||
vec3 normal = normalize((uni_NormalMatrix * vec4(gl_Normal, 0.0f)).xyz);
|
|
||||||
|
|
||||||
if (uni_LightingEnabled)
|
|
||||||
{
|
|
||||||
vec4 ambient = vec4(0.0f);
|
|
||||||
vec4 diffuse = vec4(0.0f);
|
|
||||||
vec4 specular = vec4(0.0f);
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if (uni_Light[i].Enabled)
|
|
||||||
{
|
|
||||||
LightParams light = uni_Light[i];
|
|
||||||
|
|
||||||
vec3 lightDirection = light.Position.xyz;
|
|
||||||
float atten = 1.0f;
|
|
||||||
|
|
||||||
if (light.Position.w > 0.5f)
|
|
||||||
{
|
|
||||||
float dist = distance(light.Position.xyz, position.xyz);
|
|
||||||
|
|
||||||
float atten = 1.0f / dot(light.Attenuation,
|
|
||||||
vec3(1.0f, dist, dist * dist));
|
|
||||||
|
|
||||||
lightDirection = normalize(light.Position.xyz - position.xyz);
|
|
||||||
}
|
|
||||||
|
|
||||||
float spot = 1.0f;
|
|
||||||
|
|
||||||
if (light.SpotCutoff > 0.0f)
|
|
||||||
{
|
|
||||||
float cone = dot(light.SpotDirection, lightDirection);
|
|
||||||
|
|
||||||
if (cone > light.SpotCutoff)
|
|
||||||
{
|
|
||||||
spot = pow(cone, light.SpotExponent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 reflectDirection = -reflect(lightDirection, normal);
|
|
||||||
|
|
||||||
float component = atten * spot;
|
|
||||||
float diffuseComponent = clamp(dot(normal, lightDirection), 0.0f, 1.0f);
|
|
||||||
float specularComponent = clamp(pow(dot(normal, lightDirection + reflectDirection), light.Shininess), 0.0f, 1.0f);
|
|
||||||
|
|
||||||
ambient += component * light.Ambient * uni_Material.ambient;
|
|
||||||
diffuse += component * diffuseComponent * light.Diffuse * uni_Material.diffuse;
|
|
||||||
specular += component * specularComponent * light.Specular * uni_Material.specular;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 result = ambient + diffuse + specular;
|
|
||||||
|
|
||||||
color = clamp(vec4(result.rgb, uni_Material.diffuse), 0.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
gl_Position = uni_ProjectionMatrix * eyeSpace;
|
gl_Position = uni_ProjectionMatrix * eyeSpace;
|
||||||
gl_FrontColor = vec4(1.0f);
|
|
||||||
gl_BackColor = vec4(0.0f);
|
|
||||||
|
|
||||||
|
pass_Color = gl_Color;
|
||||||
|
pass_Normal = normalize((uni_NormalMatrix * vec4(gl_Normal, 0.0f)).xyz);
|
||||||
pass_Distance = abs(eyeSpace.z / eyeSpace.w);
|
pass_Distance = abs(eyeSpace.z / eyeSpace.w);
|
||||||
pass_Color = color;
|
|
||||||
pass_Normal = normal;
|
|
||||||
pass_TexCoord0 = gl_MultiTexCoord0.st;
|
pass_TexCoord0 = gl_MultiTexCoord0.st;
|
||||||
pass_TexCoord1 = gl_MultiTexCoord1.st;
|
pass_TexCoord1 = gl_MultiTexCoord1.st;
|
||||||
pass_TexCoord2 = shadowCoord.xyz / shadowCoord.w;
|
pass_TexCoord2 = shadowCoord.xyz / shadowCoord.w;
|
||||||
|
|
Loading…
Reference in New Issue