/* "esclight.c" */ #ifndef __ESCLIGHTSOURCE #define __ESCLIGHTSOURCE #include"../headers/esclight.h" #include #include /*************** Function Definitions ***************/ void InitFlatLights() { int i; for(i=0;i<3;i++) { worldFlatLights.active[i] = 0; } }/* InitFlatLights */ void InitAmbientLight() { worldAmbientLight.red = ONE; worldAmbientLight.green = ONE; worldAmbientLight.blue = ONE; GsSetAmbient(ONE, ONE, ONE); }/* InitAmbientLight */ void SetFlatLight(int id, long int vx, long int vy, long int vz, unsigned char r, unsigned char g, unsigned char b) { worldFlatLights.flatLight[id].vx = vx; worldFlatLights.flatLight[id].vy = vy; worldFlatLights.flatLight[id].vz = vz; worldFlatLights.invDirection[id].x = -1*vx; worldFlatLights.invDirection[id].y = -1*vy; worldFlatLights.invDirection[id].z = -1*vz; NormaliseLongVector(&worldFlatLights.invDirection[id]); worldFlatLights.flatLight[id].r = r; worldFlatLights.flatLight[id].g = g; worldFlatLights.flatLight[id].b = b; GsSetFlatLight(id, &worldFlatLights.flatLight[id]); worldFlatLights.active[id] = 1; }/* SetFlatLight */ void SetAmbientLight(short int red, short int green, short int blue) { worldAmbientLight.red = red; worldAmbientLight.green = green; worldAmbientLight.blue = blue; GsSetAmbient(ONE, ONE, ONE); }/* SetAmbientLight */ void NormaliseLongVector(long_vector* vector) { long length = (long)sqrt(((vector->x)*(vector->x)) + ((vector->y)*(vector->y)) + ((vector->z)*(vector->z))); vector->x = (vector->x*ONE)/length; vector->y = (vector->y*ONE)/length; vector->z = (vector->z*ONE)/length; vector->length = ONE; }/* NormaliseLongVector */ long CalculateDotProduct(long_vector* vector1, long_vector* vector2) { long result; // Assumes Unit vectors result = (vector1->x)*(vector2->x) + (vector1->y)*(vector2->y) + (vector1->z)*(vector2->z); return result; }/* CalculateDotProduct */ light_influence_vector* CalculateLightInfluence(long_vector* vector) { int i; light_influence_vector* lightInf = (light_influence_vector*) malloc(sizeof(light_influence_vector)); for(i=0;i<3;i++) { lightInf->influence[i] = 0; // If the light is on calculate dot product and put into PSX units - Scaling for dot product error if(worldFlatLights.active[i]) lightInf->influence[i] = (CalculateDotProduct(&worldFlatLights.invDirection[i], vector) / ONE); // If dot product is -ve then normal is facing away from light if(lightInf->influence[i] < 0) lightInf->influence[i] = 0; } return lightInf; }/* CalculateLightInfluence */ colour_vector* CalculateInfluenceColour(light_influence_vector* influence) { colour_vector* infColour = (colour_vector*) malloc(sizeof(colour_vector)); infColour->r = ((influence->influence[0] * worldFlatLights.flatLight[0].r) + (influence->influence[1] * worldFlatLights.flatLight[1].r) + (influence->influence[2] * worldFlatLights.flatLight[2].r)) / 128; infColour->g = ((influence->influence[0] * worldFlatLights.flatLight[0].g) + (influence->influence[1] * worldFlatLights.flatLight[1].g) + (influence->influence[2] * worldFlatLights.flatLight[2].g)) / 128; infColour->b = ((influence->influence[0] * worldFlatLights.flatLight[0].b) + (influence->influence[1] * worldFlatLights.flatLight[1].b) + (influence->influence[2] * worldFlatLights.flatLight[2].b)) / 128; return infColour; }/* CalculateInfluenceColour */ void AddAmbientLightToColourVector(colour_vector* vector) { vector->r += worldAmbientLight.red; vector->g += worldAmbientLight.green; vector->b += worldAmbientLight.blue; }/* AddAmbientLightToColourVector */ colour_vector* CalculateScreenColours(gouraud_vertex* vertex, colour_vector* influenceColour) { long int maxColour = 255 * ONE; colour_vector* screenColour = (colour_vector*) malloc(sizeof(colour_vector)); screenColour->r = (influenceColour->r * vertex->inherentRed); screenColour->g = (influenceColour->g * vertex->inherentGreen); screenColour->b = (influenceColour->b * vertex->inherentBlue); if(screenColour->r > maxColour) screenColour->r = 255; else screenColour->r >>= 12; if(screenColour->g > maxColour) screenColour->g = 255; else screenColour->g >>= 12; if(screenColour->b > maxColour) screenColour->b = 255; else screenColour->b >>= 12; return screenColour; }/* CalculateScreenColour */ void DoLightCalculation(gouraud_vertex* vertex) { light_influence_vector* infVector; colour_vector* infColour; colour_vector* screenColours; infVector = CalculateLightInfluence(&vertex->normal); infColour = CalculateInfluenceColour(infVector); AddAmbientLightToColourVector(infColour); screenColours = CalculateScreenColours(vertex, infColour); // Assign final screen colours vertex->screenRed = screenColours->r ; vertex->screenGreen = screenColours->g; vertex->screenBlue = screenColours->b; free((void*)infVector); free((void*)infColour); free((void*)screenColours); }/* DoLightCalculation */ /************ End of Function Definitions **********/ #endif