With apparent acts of crime against the crown, my last inn was closed down, so here goes again, and I will try my outmost to not anger her Majesty this time ;)
I wrote a couple of shaders that should light my scene with diffuse and specular lighting after the initial ambient pass where only ambient lighting is used. But, as can be seen below in the screenshot, the lighting is quite off the chart.
Here are my shaders:
Vertex
varying vec3 normal;
varying vec3 lightDir;
uniform vec4 LightPosition;
void main()
{
normal = gl_NormalMatrix * gl_Normal;
vec4 eyePos = gl_ModelViewMatrix * gl_Vertex;
lightDir = normalize(vec3(LightPosition - eyePos));
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
}
Fragment
uniform sampler2D TexMap1;
uniform vec4 LightDiffuse;
uniform vec4 LightSpecular;
varying vec3 normal;
varying vec3 lightDir;
void main()
{
vec4 diffuse = LightDiffuse * gl_FrontMaterial.diffuse;
vec4 specular = LightSpecular * gl_FrontMaterial.specular;
vec4 texel = texture2D(TexMap1, gl_TexCoord[0].st);
vec4 color = diffuse * texel * max(dot(normal, lightDir), 0.0) + specular;
gl_FragColor = color;
}
The rendering loop looks like this:
void CRenderer::Render3D()
{
// Render ambient pass.
glDisable(GL_BLEND);
iActiveLight = -1;
iAmbientPass = true;
float col[4] = {0, 0, 0, 1};
glLightfv(GL_LIGHT1, GL_DIFFUSE, col);
glLightfv(GL_LIGHT1, GL_SPECULAR, col);
float amb[4] = {0.1f, 0.1f, 0.1f, 1};
glLightfv(GL_LIGHT1, GL_AMBIENT, amb);
for (unsigned int i = 0; i < i3DObjects.size(); i++)
{
i3DObjects->Draw();
}
// Render light passes.
iAmbientPass = false;
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
//for (unsigned int i = 0; i < i3DObjects.size(); i++)
{
for (int j = 0; j < 4; j++)
{
CLight* L = CScenegraph::Instance()->GetLight(j);
if (L != NULL)
{
iActiveLight = j;
glLightfv(GL_LIGHT1, GL_POSITION, L->pos);
glLightfv(GL_LIGHT1, GL_DIFFUSE, L->diff);
glLightfv(GL_LIGHT1, GL_AMBIENT, col);
glLightfv(GL_LIGHT1, GL_SPECULAR, L->spec);
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, L->att[0]);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, L->att[1]);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, L->att[2]);
for (unsigned int i = 0; i < i3DObjects.size(); i++)
{
i3DObjects->Draw();
}
}
}
}
glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
glDepthFunc(GL_LESS);
}
The rendering of objects looks like this:
void CMesh::Draw()
{
for (unsigned int i = 0; i < iMeshObj.size(); i++)
{
float zero[4] = {0, 0, 0, 1};
if (CRenderer::Instance()->IsInAmbientPass() == true)
{
glMaterialfv(GL_FRONT, GL_DIFFUSE, zero);
glMaterialfv(GL_FRONT, GL_AMBIENT, iMeshObj->iAmbient);
glMaterialfv(GL_FRONT, GL_SPECULAR, zero);
}
else
{
glMaterialfv(GL_FRONT, GL_DIFFUSE, iMeshObj->iDiffuse);
glMaterialfv(GL_FRONT, GL_AMBIENT, zero);
glMaterialfv(GL_FRONT, GL_SPECULAR, iMeshObj->iSpecular);
glMaterialf(GL_FRONT, GL_SHININESS, iMeshObj->iShininess);
}
// Check for frustum containment on the object bounding box.
if (CFrustum::Instance()->CubeIsInFrustum(iMeshObj->iBBox.GetCenter(),
iMeshObj->iBBox.GetExtents().GetX()) == true)
{
// Check for and enable possible shader and/or multi-texture.
if (iMeshObj->iMultiTexturing == true)
{
CRenderer::Instance()->EnableMultiTexturing(iMeshObj->iMaterial, iMeshObj->iMultiMaterial);
}
else
{
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, CRenderer::Instance()->GetMaterial(iMeshObj->iMaterial));
}
if (CRenderer::Instance()->IsInAmbientPass() == false)
{
CShaderManager::Instance()->UseShader(iMeshObj->iShader);
}
else
{
CShaderManager::Instance()->UseShader("Ambient");
}
CShaderManager::Instance()->SetShaderParams(iMeshObj);
// Check for frustum containment on the partition nodes.
for (unsigned int j = 0; j < iMeshObj->iPartition.iNodes.size(); j++)
{
if (CFrustum::Instance()->CubeIsInFrustum(iMeshObj->iPartition.iNodes[j]->iBBox.GetCenter(),
iMeshObj->iPartition.iNodes[j]->iBBox.GetExtents().GetX()) == true)
{
glCallList(iMeshObj->iPartition.iNodes[j]->iDisplayList);
}
}
CShaderManager::Instance()->NoShader();
if (iMeshObj->iMultiTexturing == true)
{
CRenderer::Instance()->DisableMultiTexturing();
}
}
}
}
And now, ladies and gentlemen, the scene...
Notice the "+" the lights seem to be causing with the brightest part in the middle? Also, the lighting looks very much like some form of per-vertex lighting, which I find peculiar enough.
I am not over-using any of the light's properties nor any of the material properties, as to cause some form of over-brightening effect, which can be seen in the screenshot. However, I am not reluctant to point out that the multiplication is probably off somehow, causing a sort of over-exposure effect.
I am begging for help. I cannot figure out why the lighting would be cracking up like this. Rendering only 1 light pass works, but as soon as I go into more light passes, it starts to look like something out of this world :)