My attempt at lighting math
Anyone who has seen any of my other threads, knows that 3D math isn't exactly my strong point. However, i'm trying to do a static lighting system based on the OpenGL lighting model.
At this point, my light is dynamic (was easier to do this for testing purposes). The faces light up as they should, but I think Iv'e done somthing wrong with the vertex normals, as a normal that faces the opposite direction of the light is still fully lit.
Here is my StaticLight.cpp, then StaticLight.h, and then a snippit from the rendering code where the light is applied.
Code:
/*static lighting code. Still needs alot of work. Currently only supports diffuse lighting*/
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <math.h>
#include "StaticLight.h"
bool pe_lightenabled;
pe_staticLight pe_sL;
//may remove the setupLighting function
GLvoid staticLight::setupLighting(GLfloat glbAmbient[3], GLfloat pos[3], GLfloat norm[3])
{
pe_sL.glbAmb = glbAmbient[3];
pe_sL.vPos3f[3] = pos[3];
pe_sL.vNormal3f = norm[3];
}
GLvoid staticLight::CalculateLighting(int ID, UINT lArray[],
float x, float y, float z,
float r, float g, float b,
float ca, float la, float qa)
{
//while (pe_lightenabled)
//{
//Setup:
//assign ID to the light
int id = lArray[ID];
//light positioning:
pe_sL.x = x;
pe_sL.y = y;
pe_sL.z = z;
//light coloring (diffuse):
pe_sL.r = r;
pe_sL.g = g;
pe_sL.b = b;
//light attenuation:
/*pe_sL.constant_attenuation = ca;
pe_sL.linear_attenuation = la;
pe_sL.quadratic_attenuation = qa;*/
//Render:
float L = sqrt( (pe_sL.vPos3f[0]-pe_sL.x)*(pe_sL.vPos3f[0]-pe_sL.x)+ \
(pe_sL.vPos3f[1]-pe_sL.y)*(pe_sL.vPos3f[1]-pe_sL.y)+ \
(pe_sL.vPos3f[2]-pe_sL.z)*(pe_sL.vPos3f[2]-pe_sL.z) );
float N = pe_sL.vNormal3f;
//calculate diffuse color:
float diffuser = pe_sL.r * (L*N);
float diffuseg = pe_sL.g * (L*N);
float diffuseb = pe_sL.b * (L*N);
if (pe_sL.r > 1.0)
pe_sL.r == 1.0;
if (pe_sL.g > 1.0)
pe_sL.g == 1.0;
if (pe_sL.b > 1.0)
pe_sL.b == 1.0;
pe_sL.finalColor3f[1] = diffuser; pe_sL.finalColor3f[2] = diffuseg; pe_sL.finalColor3f[3] = diffuseb;
//}
}
//this function, once/if finished, will tell a vertex to illuminate only when within the lights radius.
GLvoid staticLight::Vertex_In_Radius(float x, float y, float z)
{
/*some pseudo(spelling?) code for calculating the x:
diameter = total_attenuation/2 - lightposx;
if ( x < diameter | x > -diameter) then
light_the_vertex();*/
}
GLvoid staticLight::enableLighting(int type)
{
if (type == 1)
glDisable(GL_LIGHTING);
pe_lightenabled = TRUE;
if (type == 2)
glEnable(GL_LIGHTING);
pe_lightenabled = TRUE;
if (type == 3)//default
glEnable(GL_LIGHTING);
pe_lightenabled = FALSE;
if (type == 4)
glDisable(GL_LIGHTING);
pe_lightenabled = FALSE;
}
Code:
//hold information about our light
struct pe_staticLight
{
public:
GLfloat x, y, z;
GLfloat r, g, b, a;
GLfloat vPos3f[3];
GLfloat vNormal3f;
GLfloat finalColor3f[3], finalColor4f[4];
GLfloat glbAmb;
GLfloat constant_attenuation, linear_attenuation, quadratic_attenuation;
};
//static light class
class staticLight
{
private:
staticLight();
virtual ~staticLight();
public:
GLvoid setupLighting(GLfloat glbAmbient[3], GLfloat pos[3], GLfloat norm[3]);
//GLvoid drawLight();
GLvoid CalculateLighting(int ID, UINT lArray[], float x, float y, float z, float r, float g, float b, float ca, float la, float qa);
GLvoid Vertex_In_Radius(float x, float y, float z);
GLvoid enableLighting(int type);
};
Code:
glBegin(GL_QUADS);
//-------front-------//
glNormal3f(0.0, 0.0, 1.0);
for (i=0; i<4; i++) {
c[0]=SolidCubeData[5*i+2];
c[1]=SolidCubeData[5*i+3];
c[2]=SolidCubeData[5*i+4];
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,SolidCubeData[5*i] , SolidCubeData[5*i+1]);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,SolidCubeData[5*i], SolidCubeData[5*i+1]);
//_peStaticLight->enableLighting(4);
GLfloat global_ambient[3] = {0.75, 0.75, 0.75};
GLfloat vert_position[3] = {5*i+2, 5*i+3, 5*i+4};
GLfloat vert_normal[3] = {0.0, 0.0, 1.0};
_peStaticLight->setupLighting(global_ambient, vert_position, vert_normal);
_peStaticLight->CalculateLighting(0, lightID, 10, 10, 10, 1, 1, 1, 0, 1.5, 0);
glColor3f(pe_sL.finalColor3f[1], pe_sL.finalColor3f[2], pe_sL.finalColor3f[3]);
glVertex3f(SolidCubeData[5*i+2], SolidCubeData[5*i+3], SolidCubeData[5*i+4]);
}
glEnd();
glBegin(GL_QUADS);
//-------back-------//
glColor3f(1.0, 1.0, 1.0);
glNormal3f(0.0, 0.0, -1.0);
for (i=4; i<8; i++) {
c[0]=SolidCubeData[5*i+2];
c[1]=SolidCubeData[5*i+3];
c[2]=SolidCubeData[5*i+4];
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,SolidCubeData[5*i] , SolidCubeData[5*i+1]);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,SolidCubeData[5*i], SolidCubeData[5*i+1]);
GLfloat global_ambient[3] = {0.75, 0.75, 0.75};
GLfloat vert_position[3] = {5*i+2, 5*i+3, 5*i+4};
GLfloat vert_normal[3] = {0.0, 0.0, -1.0};
_peStaticLight->setupLighting(global_ambient, vert_position, vert_normal);
_peStaticLight->CalculateLighting(0, lightID, 10, 10, 10, 1, 1, 1, 0, 1.5, 0);
glColor3f(pe_sL.finalColor3f[1], pe_sL.finalColor3f[2], pe_sL.finalColor3f[3]);
glVertex3f(SolidCubeData[5*i+2], SolidCubeData[5*i+3], SolidCubeData[5*i+4]);
}
glEnd();
I'm still pretty shakey on this, so please bear with me :)
thanx,
-psychopath