Rewritten lighting in OpenGL 2.1 engine
parent
898001e065
commit
32b480b226
|
@ -273,7 +273,11 @@ bool CGL21Device::Create()
|
|||
sprintf(filename, "shaders/vertex_shader_21_pervertex.glsl");
|
||||
|
||||
shaders[0] = LoadShader(GL_VERTEX_SHADER, filename);
|
||||
if (shaders[0] == 0) return false;
|
||||
if (shaders[0] == 0)
|
||||
{
|
||||
m_errorMessage = GetLastShaderError();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_perPixelLighting)
|
||||
sprintf(filename, "shaders/fragment_shader_21_perpixel.glsl");
|
||||
|
@ -281,10 +285,18 @@ bool CGL21Device::Create()
|
|||
sprintf(filename, "shaders/fragment_shader_21_pervertex.glsl");
|
||||
|
||||
shaders[1] = LoadShader(GL_FRAGMENT_SHADER, filename);
|
||||
if (shaders[1] == 0) return false;
|
||||
if (shaders[1] == 0)
|
||||
{
|
||||
m_errorMessage = GetLastShaderError();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_program = LinkProgram(2, shaders);
|
||||
if (m_program == 0) return false;
|
||||
if (m_program == 0)
|
||||
{
|
||||
m_errorMessage = GetLastShaderError();
|
||||
return false;
|
||||
}
|
||||
|
||||
glDeleteShader(shaders[0]);
|
||||
glDeleteShader(shaders[1]);
|
||||
|
@ -318,11 +330,30 @@ bool CGL21Device::Create()
|
|||
uni_ShadowColor = glGetUniformLocation(m_program, "uni_ShadowColor");
|
||||
uni_LightingEnabled = glGetUniformLocation(m_program, "uni_LightingEnabled");
|
||||
|
||||
uni_AmbientColor = glGetUniformLocation(m_program, "uni_AmbientColor");
|
||||
uni_DiffuseColor = glGetUniformLocation(m_program, "uni_DiffuseColor");
|
||||
uni_SpecularColor = glGetUniformLocation(m_program, "uni_SpecularColor");
|
||||
|
||||
GLchar name[64];
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
char name[64];
|
||||
sprintf(name, "uni_LightEnabled[%d]", i);
|
||||
uni_LightEnabled[i] = glGetUniformLocation(m_program, name);
|
||||
sprintf(name, "uni_Light[%d].Enabled", i);
|
||||
uni_Light[i].Enabled = glGetUniformLocation(m_program, name);
|
||||
|
||||
sprintf(name, "uni_Light[%d].Position", i);
|
||||
uni_Light[i].Position = glGetUniformLocation(m_program, name);
|
||||
|
||||
sprintf(name, "uni_Light[%d].Ambient", i);
|
||||
uni_Light[i].Ambient = glGetUniformLocation(m_program, name);
|
||||
|
||||
sprintf(name, "uni_Light[%d].Diffuse", i);
|
||||
uni_Light[i].Diffuse = glGetUniformLocation(m_program, name);
|
||||
|
||||
sprintf(name, "uni_Light[%d].Specular", i);
|
||||
uni_Light[i].Specular = glGetUniformLocation(m_program, name);
|
||||
|
||||
sprintf(name, "uni_Light[%d].Attenuation", i);
|
||||
uni_Light[i].Attenuation = glGetUniformLocation(m_program, name);
|
||||
}
|
||||
|
||||
// Set default uniform values
|
||||
|
@ -355,7 +386,7 @@ bool CGL21Device::Create()
|
|||
|
||||
glUniform1i(uni_LightingEnabled, 0);
|
||||
for (int i = 0; i < 8; i++)
|
||||
glUniform1i(uni_LightEnabled[i], 0);
|
||||
glUniform1i(uni_Light[i].Enabled, 0);
|
||||
|
||||
// create default framebuffer object
|
||||
FramebufferParams framebufferParams;
|
||||
|
@ -485,9 +516,9 @@ void CGL21Device::SetMaterial(const Material &material)
|
|||
{
|
||||
m_material = material;
|
||||
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m_material.ambient.Array());
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m_material.diffuse.Array());
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m_material.specular.Array());
|
||||
glUniform4fv(uni_AmbientColor, 1, m_material.ambient.Array());
|
||||
glUniform4fv(uni_DiffuseColor, 1, m_material.diffuse.Array());
|
||||
glUniform4fv(uni_SpecularColor, 1, m_material.specular.Array());
|
||||
}
|
||||
|
||||
int CGL21Device::GetMaxLightCount()
|
||||
|
@ -502,40 +533,21 @@ void CGL21Device::SetLight(int index, const Light &light)
|
|||
|
||||
m_lights[index] = light;
|
||||
|
||||
// Indexing from GL_LIGHT0 should always work
|
||||
glLightfv(GL_LIGHT0 + index, GL_AMBIENT, const_cast<GLfloat*>(light.ambient.Array()));
|
||||
glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, const_cast<GLfloat*>(light.diffuse.Array()));
|
||||
glLightfv(GL_LIGHT0 + index, GL_SPECULAR, const_cast<GLfloat*>(light.specular.Array()));
|
||||
glUniform4fv(uni_Light[index].Ambient, 1, light.ambient.Array());
|
||||
glUniform4fv(uni_Light[index].Diffuse, 1, light.diffuse.Array());
|
||||
glUniform4fv(uni_Light[index].Specular, 1, light.specular.Array());
|
||||
glUniform3f(uni_Light[index].Attenuation, light.attenuation0, light.attenuation1, light.attenuation2);
|
||||
|
||||
glLightf(GL_LIGHT0 + index, GL_CONSTANT_ATTENUATION, light.attenuation0);
|
||||
glLightf(GL_LIGHT0 + index, GL_LINEAR_ATTENUATION, light.attenuation1);
|
||||
glLightf(GL_LIGHT0 + index, GL_QUADRATIC_ATTENUATION, light.attenuation2);
|
||||
|
||||
if (light.type == LIGHT_SPOT)
|
||||
if (light.type == LIGHT_DIRECTIONAL)
|
||||
{
|
||||
glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, light.spotAngle * Math::RAD_TO_DEG);
|
||||
glLightf(GL_LIGHT0 + index, GL_SPOT_EXPONENT, light.spotIntensity);
|
||||
glUniform4f(uni_Light[index].Position, -light.direction.x, -light.direction.y, -light.direction.z, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f);
|
||||
glUniform4f(uni_Light[index].Position, light.position.x, light.position.y, light.position.z, 1.0f);
|
||||
}
|
||||
|
||||
if (light.type == LIGHT_SPOT)
|
||||
{
|
||||
GLfloat direction[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 1.0f };
|
||||
glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
|
||||
}
|
||||
else if (light.type == LIGHT_DIRECTIONAL)
|
||||
{
|
||||
GLfloat position[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 0.0f };
|
||||
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLfloat position[4] = { light.position.x, light.position.y, light.position.z, 1.0f };
|
||||
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
|
||||
}
|
||||
// TODO: add spotlight params
|
||||
}
|
||||
|
||||
void CGL21Device::SetLightEnabled(int index, bool enabled)
|
||||
|
@ -545,7 +557,7 @@ void CGL21Device::SetLightEnabled(int index, bool enabled)
|
|||
|
||||
m_lightsEnabled[index] = enabled;
|
||||
|
||||
glUniform1i(uni_LightEnabled[index], enabled ? 1 : 0);
|
||||
glUniform1i(uni_Light[index].Enabled, enabled ? 1 : 0);
|
||||
}
|
||||
|
||||
/** If image is invalid, returns invalid texture.
|
||||
|
|
|
@ -299,8 +299,32 @@ private:
|
|||
|
||||
//! true enables lighting
|
||||
GLint uni_LightingEnabled = 0;
|
||||
//! true enables light source
|
||||
GLint uni_LightEnabled[8] = {};
|
||||
//! Ambient color
|
||||
GLint uni_AmbientColor = 0;
|
||||
//! Diffuse color
|
||||
GLint uni_DiffuseColor = 0;
|
||||
//! Specular color
|
||||
GLint uni_SpecularColor = 0;
|
||||
|
||||
struct LightUniforms
|
||||
{
|
||||
//! true enables light
|
||||
GLint Enabled = 0;
|
||||
//! Light type
|
||||
GLint Type = 0;
|
||||
//! Position or direction vector
|
||||
GLint Position = 0;
|
||||
//! Ambient color
|
||||
GLint Ambient = 0;
|
||||
//! Diffuse color
|
||||
GLint Diffuse = 0;
|
||||
//! Specular color
|
||||
GLint Specular = 0;
|
||||
//! Attenuation
|
||||
GLint Attenuation = 0;
|
||||
};
|
||||
|
||||
LightUniforms uni_Light[8];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,8 +34,23 @@ uniform vec4 uni_FogColor;
|
|||
|
||||
uniform float uni_ShadowColor;
|
||||
|
||||
struct LightParams
|
||||
{
|
||||
bool Enabled;
|
||||
vec4 Position;
|
||||
vec4 Ambient;
|
||||
vec4 Diffuse;
|
||||
vec4 Specular;
|
||||
float Shininess;
|
||||
vec3 Attenuation;
|
||||
};
|
||||
|
||||
uniform vec4 uni_AmbientColor;
|
||||
uniform vec4 uni_DiffuseColor;
|
||||
uniform vec4 uni_SpecularColor;
|
||||
|
||||
uniform bool uni_LightingEnabled;
|
||||
uniform bool uni_LightEnabled[8];
|
||||
uniform LightParams uni_Light[8];
|
||||
|
||||
varying vec3 pass_Normal;
|
||||
varying vec3 pass_Position;
|
||||
|
@ -51,46 +66,41 @@ void main()
|
|||
vec4 diffuse = vec4(0.0f);
|
||||
vec4 specular = vec4(0.0f);
|
||||
|
||||
vec3 normal = pass_Normal;
|
||||
vec3 normal = (gl_FrontFacing ? pass_Normal : -pass_Normal);
|
||||
|
||||
for(int i=0; i<8; i++)
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if(uni_LightEnabled[i])
|
||||
if (uni_Light[i].Enabled)
|
||||
{
|
||||
vec3 lightDirection = vec3(0.0f);
|
||||
float atten;
|
||||
vec3 lightDirection = uni_Light[i].Position.xyz;
|
||||
float atten = 1.0f;
|
||||
|
||||
// Directional light
|
||||
if(gl_LightSource[i].position.w == 0.0f)
|
||||
{
|
||||
lightDirection = gl_LightSource[i].position.xyz;
|
||||
atten = 1.0f;
|
||||
}
|
||||
// Point light
|
||||
else
|
||||
if (abs(uni_Light[i].Position.w) > 1e-3f)
|
||||
{
|
||||
vec3 lightDirection = normalize(gl_LightSource[i].position.xyz - pass_Position);
|
||||
float dist = distance(gl_LightSource[i].position.xyz, pass_Position);
|
||||
vec3 lightDirection = normalize(uni_Light[i].Position.xyz - pass_Position.xyz);
|
||||
float dist = distance(uni_Light[i].Position.xyz, pass_Position.xyz);
|
||||
|
||||
atten = 1.0f / (gl_LightSource[i].constantAttenuation
|
||||
+ gl_LightSource[i].linearAttenuation * dist
|
||||
+ gl_LightSource[i].quadraticAttenuation * dist * dist);
|
||||
vec3 lightAtten = uni_Light[i].Attenuation;
|
||||
|
||||
atten = 1.0f / (lightAtten.x
|
||||
+ lightAtten.y * dist
|
||||
+ lightAtten.z * dist * dist);
|
||||
}
|
||||
|
||||
vec3 reflectDirection = -reflect(lightDirection, normal);
|
||||
|
||||
ambient += gl_LightSource[i].ambient;
|
||||
diffuse += atten * clamp(dot(normal, lightDirection), 0.0f, 1.0f) * gl_LightSource[i].diffuse;
|
||||
specular += atten * clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f) * gl_LightSource[i].specular;
|
||||
ambient += uni_Light[i].Ambient;
|
||||
diffuse += atten * clamp(dot(normal, lightDirection), 0.0f, 1.0f) * uni_Light[i].Diffuse;
|
||||
specular += atten * clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f) * uni_Light[i].Specular;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 result = gl_FrontMaterial.ambient * ambient
|
||||
+ gl_FrontMaterial.diffuse * diffuse
|
||||
+ gl_FrontMaterial.specular * specular;
|
||||
vec4 result = uni_AmbientColor * ambient
|
||||
+ uni_DiffuseColor * diffuse
|
||||
+ uni_SpecularColor * specular;
|
||||
|
||||
color.rgb = min(vec3(1.0f), result.rgb);
|
||||
color.a = 1.0f; //min(1.0f, 1.0f);
|
||||
color = vec4(min(vec3(1.0f), result.rgb), 1.0f);
|
||||
}
|
||||
|
||||
if (uni_TextureEnabled[0])
|
||||
|
@ -105,7 +115,8 @@ void main()
|
|||
|
||||
if (uni_TextureEnabled[2])
|
||||
{
|
||||
color = color * mix(uni_ShadowColor, 1.0f, shadow2D(uni_ShadowTexture, gl_TexCoord[2].xyz).x);
|
||||
if (gl_FrontFacing)
|
||||
color.rgb *= mix(uni_ShadowColor, 1.0f, shadow2D(uni_ShadowTexture, gl_TexCoord[2].xyz).x);
|
||||
}
|
||||
|
||||
if (uni_FogEnabled)
|
||||
|
|
|
@ -52,7 +52,10 @@ void main()
|
|||
|
||||
if (uni_TextureEnabled[2])
|
||||
{
|
||||
color = color * mix(uni_ShadowColor, 1.0f, shadow2D(uni_ShadowTexture, gl_TexCoord[2].xyz).x);
|
||||
if (gl_FrontFacing)
|
||||
color.rgb *= mix(uni_ShadowColor, 1.0f, shadow2D(uni_ShadowTexture, gl_TexCoord[2].xyz).x);
|
||||
else
|
||||
color.rgb *= uni_ShadowColor;
|
||||
}
|
||||
|
||||
if (uni_FogEnabled)
|
||||
|
|
|
@ -25,8 +25,23 @@ uniform mat4 uni_ModelMatrix;
|
|||
uniform mat4 uni_ShadowMatrix;
|
||||
uniform mat4 uni_NormalMatrix;
|
||||
|
||||
struct LightParams
|
||||
{
|
||||
bool Enabled;
|
||||
vec4 Position;
|
||||
vec4 Ambient;
|
||||
vec4 Diffuse;
|
||||
vec4 Specular;
|
||||
float Shininess;
|
||||
vec3 Attenuation;
|
||||
};
|
||||
|
||||
uniform vec4 uni_AmbientColor;
|
||||
uniform vec4 uni_DiffuseColor;
|
||||
uniform vec4 uni_SpecularColor;
|
||||
|
||||
uniform bool uni_LightingEnabled;
|
||||
uniform bool uni_LightEnabled[8];
|
||||
uniform LightParams uni_Light[8];
|
||||
|
||||
varying float pass_Distance;
|
||||
|
||||
|
@ -44,53 +59,44 @@ void main()
|
|||
|
||||
if (uni_LightingEnabled)
|
||||
{
|
||||
vec4 color;
|
||||
vec4 ambient = vec4(0.0f);
|
||||
vec4 diffuse = vec4(0.0f);
|
||||
vec4 specular = vec4(0.0f);
|
||||
|
||||
vec3 normal = normalize((uni_NormalMatrix * vec4(gl_Normal, 0.0f)).xyz);
|
||||
|
||||
for(int i=0; i<8; i++)
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if(uni_LightEnabled[i])
|
||||
if (uni_Light[i].Enabled)
|
||||
{
|
||||
vec3 lightDirection = vec3(0.0f);
|
||||
float atten;
|
||||
vec3 lightDirection = uni_Light[i].Position.xyz;
|
||||
float atten = 1.0f;
|
||||
|
||||
// Directional light
|
||||
if(gl_LightSource[i].position.w == 0.0f)
|
||||
{
|
||||
lightDirection = gl_LightSource[i].position.xyz;
|
||||
atten = 1.0f;
|
||||
}
|
||||
// Point light
|
||||
else
|
||||
if (abs(uni_Light[i].Position.w) > 1e-3f)
|
||||
{
|
||||
vec3 lightDirection = normalize(gl_LightSource[i].position.xyz - position.xyz);
|
||||
float dist = distance(gl_LightSource[i].position.xyz, position.xyz);
|
||||
vec3 lightDirection = normalize(uni_Light[i].Position.xyz - position.xyz);
|
||||
float dist = distance(uni_Light[i].Position.xyz, position.xyz);
|
||||
|
||||
atten = 1.0f / (gl_LightSource[i].constantAttenuation
|
||||
+ gl_LightSource[i].linearAttenuation * dist
|
||||
+ gl_LightSource[i].quadraticAttenuation * dist * dist);
|
||||
vec3 lightAtten = uni_Light[i].Attenuation;
|
||||
|
||||
atten = 1.0f / (lightAtten.x
|
||||
+ lightAtten.y * dist
|
||||
+ lightAtten.z * dist * dist);
|
||||
}
|
||||
|
||||
vec3 reflectDirection = -reflect(lightDirection, normal);
|
||||
|
||||
ambient += gl_LightSource[i].ambient;
|
||||
diffuse += atten * clamp(dot(normal, lightDirection), 0.0f, 1.0f) * gl_LightSource[i].diffuse;
|
||||
specular += atten * clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f) * gl_LightSource[i].specular;
|
||||
ambient += uni_Light[i].Ambient;
|
||||
diffuse += atten * clamp(dot(normal, lightDirection), 0.0f, 1.0f) * uni_Light[i].Diffuse;
|
||||
specular += atten * clamp(pow(dot(normal, lightDirection + reflectDirection), 10.0f), 0.0f, 1.0f) * uni_Light[i].Specular;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 result = gl_FrontMaterial.ambient * ambient
|
||||
+ gl_FrontMaterial.diffuse * diffuse
|
||||
+ gl_FrontMaterial.specular * specular;
|
||||
vec4 result = uni_AmbientColor * ambient
|
||||
+ uni_DiffuseColor * diffuse
|
||||
+ uni_SpecularColor * specular;
|
||||
|
||||
color.rgb = min(vec3(1.0f), result.rgb);
|
||||
color.a = 1.0f; //min(1.0f, 1.0f);
|
||||
|
||||
gl_FrontColor = color;
|
||||
gl_FrontColor = vec4(min(vec3(1.0f), result.rgb), 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue