Lighting optimisations
This commit is contained in:
parent
0a14db39a8
commit
814f228db9
234
GL/lighting.c
234
GL/lighting.c
|
@ -18,9 +18,19 @@ static GLenum COLOR_CONTROL = GL_SINGLE_COLOR;
|
||||||
|
|
||||||
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
|
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
|
||||||
|
|
||||||
|
#define AMBIENT_MASK 1
|
||||||
|
#define DIFFUSE_MASK 2
|
||||||
|
#define EMISSION_MASK 4
|
||||||
|
#define SPECULAR_MASK 8
|
||||||
|
#define SCENE_AMBIENT_MASK 16
|
||||||
|
|
||||||
|
static GLenum COLOR_MATERIAL_MASK = AMBIENT_MASK | DIFFUSE_MASK;
|
||||||
|
|
||||||
static LightSource LIGHTS[MAX_LIGHTS];
|
static LightSource LIGHTS[MAX_LIGHTS];
|
||||||
static Material MATERIAL;
|
static Material MATERIAL;
|
||||||
|
|
||||||
|
GL_FORCE_INLINE void _glPrecalcLightingValues(GLuint mask);
|
||||||
|
|
||||||
void _glInitLights() {
|
void _glInitLights() {
|
||||||
static GLfloat ONE [] = {1.0f, 1.0f, 1.0f, 1.0f};
|
static GLfloat ONE [] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
static GLfloat ZERO [] = {0.0f, 0.0f, 0.0f, 1.0f};
|
static GLfloat ZERO [] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
@ -46,6 +56,7 @@ void _glInitLights() {
|
||||||
|
|
||||||
LIGHTS[i].position[0] = LIGHTS[i].position[1] = LIGHTS[i].position[3] = 0.0f;
|
LIGHTS[i].position[0] = LIGHTS[i].position[1] = LIGHTS[i].position[3] = 0.0f;
|
||||||
LIGHTS[i].position[2] = 1.0f;
|
LIGHTS[i].position[2] = 1.0f;
|
||||||
|
LIGHTS[i].isDirectional = GL_TRUE;
|
||||||
|
|
||||||
LIGHTS[i].spot_direction[0] = LIGHTS[i].spot_direction[1] = 0.0f;
|
LIGHTS[i].spot_direction[0] = LIGHTS[i].spot_direction[1] = 0.0f;
|
||||||
LIGHTS[i].spot_direction[2] = -1.0f;
|
LIGHTS[i].spot_direction[2] = -1.0f;
|
||||||
|
@ -57,6 +68,43 @@ void _glInitLights() {
|
||||||
LIGHTS[i].linear_attenuation = 0.0f;
|
LIGHTS[i].linear_attenuation = 0.0f;
|
||||||
LIGHTS[i].quadratic_attenuation = 0.0f;
|
LIGHTS[i].quadratic_attenuation = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glPrecalcLightingValues(~0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL_FORCE_INLINE void _glPrecalcLightingValues(GLuint mask) {
|
||||||
|
float baseColour[4];
|
||||||
|
|
||||||
|
/* Pre-calculate lighting values */
|
||||||
|
GLubyte i, j;
|
||||||
|
|
||||||
|
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||||
|
/* Go through rgba */
|
||||||
|
for(j = 0; j < 4; ++j) {
|
||||||
|
if(mask & AMBIENT_MASK)
|
||||||
|
LIGHTS[i].ambientMaterial[j] = LIGHTS[i].ambient[j] * MATERIAL.ambient[j];
|
||||||
|
|
||||||
|
if(mask & DIFFUSE_MASK)
|
||||||
|
LIGHTS[i].diffuseMaterial[j] = LIGHTS[i].diffuse[j] * MATERIAL.diffuse[j];
|
||||||
|
|
||||||
|
if(mask & SPECULAR_MASK)
|
||||||
|
LIGHTS[i].specularMaterial[j] = LIGHTS[i].specular[j] * MATERIAL.specular[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If ambient or emission are updated, we need to update
|
||||||
|
* the base colour. */
|
||||||
|
if((mask & AMBIENT_MASK) || (mask & EMISSION_MASK) || (mask & SCENE_AMBIENT_MASK)) {
|
||||||
|
baseColour[0] = MATH_fmac(SCENE_AMBIENT[0], MATERIAL.ambient[0], MATERIAL.emissive[0]);
|
||||||
|
baseColour[1] = MATH_fmac(SCENE_AMBIENT[1], MATERIAL.ambient[1], MATERIAL.emissive[1]);
|
||||||
|
baseColour[2] = MATH_fmac(SCENE_AMBIENT[2], MATERIAL.ambient[2], MATERIAL.emissive[2]);
|
||||||
|
baseColour[3] = MATH_fmac(SCENE_AMBIENT[3], MATERIAL.ambient[3], MATERIAL.emissive[3]);
|
||||||
|
|
||||||
|
MATERIAL.baseColour[R8IDX] = (uint8_t)(_MIN(baseColour[0] * 255.0f, 255.0f));
|
||||||
|
MATERIAL.baseColour[G8IDX] = (uint8_t)(_MIN(baseColour[1] * 255.0f, 255.0f));
|
||||||
|
MATERIAL.baseColour[B8IDX] = (uint8_t)(_MIN(baseColour[2] * 255.0f, 255.0f));
|
||||||
|
MATERIAL.baseColour[A8IDX] = (uint8_t)(_MIN(baseColour[3] * 255.0f, 255.0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glLightModelf(GLenum pname, const GLfloat param) {
|
void APIENTRY glLightModelf(GLenum pname, const GLfloat param) {
|
||||||
|
@ -69,9 +117,10 @@ void APIENTRY glLightModeli(GLenum pname, const GLint param) {
|
||||||
|
|
||||||
void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params) {
|
void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params) {
|
||||||
switch(pname) {
|
switch(pname) {
|
||||||
case GL_LIGHT_MODEL_AMBIENT:
|
case GL_LIGHT_MODEL_AMBIENT: {
|
||||||
memcpy(SCENE_AMBIENT, params, sizeof(GLfloat) * 4);
|
memcpy(SCENE_AMBIENT, params, sizeof(GLfloat) * 4);
|
||||||
break;
|
_glPrecalcLightingValues(SCENE_AMBIENT_MASK);
|
||||||
|
} break;
|
||||||
case GL_LIGHT_MODEL_LOCAL_VIEWER:
|
case GL_LIGHT_MODEL_LOCAL_VIEWER:
|
||||||
VIEWER_IN_EYE_COORDINATES = (*params) ? GL_TRUE : GL_FALSE;
|
VIEWER_IN_EYE_COORDINATES = (*params) ? GL_TRUE : GL_FALSE;
|
||||||
break;
|
break;
|
||||||
|
@ -104,6 +153,10 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint mask = (pname == GL_AMBIENT) ? AMBIENT_MASK :
|
||||||
|
(pname == GL_DIFFUSE) ? DIFFUSE_MASK :
|
||||||
|
(pname == GL_SPECULAR) ? SPECULAR_MASK : 0;
|
||||||
|
|
||||||
switch(pname) {
|
switch(pname) {
|
||||||
case GL_AMBIENT:
|
case GL_AMBIENT:
|
||||||
memcpy(LIGHTS[idx].ambient, params, sizeof(GLfloat) * 4);
|
memcpy(LIGHTS[idx].ambient, params, sizeof(GLfloat) * 4);
|
||||||
|
@ -118,7 +171,9 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
|
||||||
_glMatrixLoadModelView();
|
_glMatrixLoadModelView();
|
||||||
memcpy(LIGHTS[idx].position, params, sizeof(GLfloat) * 4);
|
memcpy(LIGHTS[idx].position, params, sizeof(GLfloat) * 4);
|
||||||
|
|
||||||
if(params[3] == 0.0f) {
|
LIGHTS[idx].isDirectional = params[3] == 0.0f;
|
||||||
|
|
||||||
|
if(LIGHTS[idx].isDirectional) {
|
||||||
//FIXME: Do we need to rotate directional lights?
|
//FIXME: Do we need to rotate directional lights?
|
||||||
} else {
|
} else {
|
||||||
mat_trans_single4(
|
mat_trans_single4(
|
||||||
|
@ -146,6 +201,8 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
|
||||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||||
_glKosPrintError();
|
_glKosPrintError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glPrecalcLightingValues(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) {
|
void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) {
|
||||||
|
@ -192,11 +249,6 @@ void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
||||||
if(pname == GL_SHININESS) {
|
|
||||||
glMaterialf(face, pname, *params);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(face == GL_BACK) {
|
if(face == GL_BACK) {
|
||||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||||
_glKosPrintError();
|
_glKosPrintError();
|
||||||
|
@ -204,6 +256,9 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(pname) {
|
switch(pname) {
|
||||||
|
case GL_SHININESS:
|
||||||
|
glMaterialf(face, pname, *params);
|
||||||
|
break;
|
||||||
case GL_AMBIENT:
|
case GL_AMBIENT:
|
||||||
memcpy(MATERIAL.ambient, params, sizeof(GLfloat) * 4);
|
memcpy(MATERIAL.ambient, params, sizeof(GLfloat) * 4);
|
||||||
break;
|
break;
|
||||||
|
@ -217,8 +272,8 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
||||||
memcpy(MATERIAL.emissive, params, sizeof(GLfloat) * 4);
|
memcpy(MATERIAL.emissive, params, sizeof(GLfloat) * 4);
|
||||||
break;
|
break;
|
||||||
case GL_AMBIENT_AND_DIFFUSE: {
|
case GL_AMBIENT_AND_DIFFUSE: {
|
||||||
glMaterialfv(face, GL_AMBIENT, params);
|
memcpy(MATERIAL.ambient, params, sizeof(GLfloat) * 4);
|
||||||
glMaterialfv(face, GL_DIFFUSE, params);
|
memcpy(MATERIAL.diffuse, params, sizeof(GLfloat) * 4);
|
||||||
} break;
|
} break;
|
||||||
case GL_COLOR_INDEXES:
|
case GL_COLOR_INDEXES:
|
||||||
default: {
|
default: {
|
||||||
|
@ -226,6 +281,14 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
||||||
_glKosPrintError();
|
_glKosPrintError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint updateMask = (pname == GL_AMBIENT) ? AMBIENT_MASK:
|
||||||
|
(pname == GL_DIFFUSE) ? DIFFUSE_MASK:
|
||||||
|
(pname == GL_SPECULAR) ? SPECULAR_MASK:
|
||||||
|
(pname == GL_EMISSION) ? EMISSION_MASK:
|
||||||
|
(pname == GL_AMBIENT_AND_DIFFUSE) ? AMBIENT_MASK | DIFFUSE_MASK : 0;
|
||||||
|
|
||||||
|
_glPrecalcLightingValues(updateMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glColorMaterial(GLenum face, GLenum mode) {
|
void APIENTRY glColorMaterial(GLenum face, GLenum mode) {
|
||||||
|
@ -241,9 +304,34 @@ void APIENTRY glColorMaterial(GLenum face, GLenum mode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COLOR_MATERIAL_MASK = (mode == GL_AMBIENT) ? AMBIENT_MASK:
|
||||||
|
(mode == GL_DIFFUSE) ? DIFFUSE_MASK:
|
||||||
|
(mode == GL_AMBIENT_AND_DIFFUSE) ? AMBIENT_MASK | DIFFUSE_MASK:
|
||||||
|
(mode == GL_EMISSION) ? EMISSION_MASK : SPECULAR_MASK;
|
||||||
|
|
||||||
COLOR_MATERIAL_MODE = mode;
|
COLOR_MATERIAL_MODE = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glUpdateColourMaterial(GLfloat* colour) {
|
||||||
|
if(!_glIsColorMaterialEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(COLOR_MATERIAL_MODE == GL_AMBIENT || COLOR_MATERIAL_MODE == GL_AMBIENT_AND_DIFFUSE) {
|
||||||
|
memcpy4(MATERIAL.ambient, colour, sizeof(GLfloat) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(COLOR_MATERIAL_MODE == GL_DIFFUSE || COLOR_MATERIAL_MODE == GL_AMBIENT_AND_DIFFUSE) {
|
||||||
|
memcpy4(MATERIAL.diffuse, colour, sizeof(GLfloat) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(COLOR_MATERIAL_MODE == GL_EMISSION) {
|
||||||
|
memcpy4(MATERIAL.emissive, colour, sizeof(GLfloat) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glPrecalcLightingValues(COLOR_MATERIAL_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
GL_FORCE_INLINE GLboolean isDiffuseColorMaterial() {
|
GL_FORCE_INLINE GLboolean isDiffuseColorMaterial() {
|
||||||
return (COLOR_MATERIAL_MODE == GL_DIFFUSE || COLOR_MATERIAL_MODE == GL_AMBIENT_AND_DIFFUSE);
|
return (COLOR_MATERIAL_MODE == GL_DIFFUSE || COLOR_MATERIAL_MODE == GL_AMBIENT_AND_DIFFUSE);
|
||||||
}
|
}
|
||||||
|
@ -288,31 +376,20 @@ GL_FORCE_INLINE float faster_pow(const float x, const float p) {
|
||||||
return faster_pow2(p * faster_log2(x));
|
return faster_pow2(p * faster_log2(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_FORCE_INLINE float vec3_dot_limited(
|
|
||||||
const float* x1, const float* y1, const float* z1,
|
|
||||||
const float* x2, const float* y2, const float* z2) {
|
|
||||||
|
|
||||||
float ret;
|
|
||||||
vec3f_dot(*x1, *y1, *z1, *x2, *y2, *z2, ret);
|
|
||||||
return (ret < 0) ? 0 : ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
GL_FORCE_INLINE void _glLightVertexDirectional(
|
GL_FORCE_INLINE void _glLightVertexDirectional(
|
||||||
uint8_t* final, int8_t lid,
|
uint8_t* final, uint8_t lid,
|
||||||
float LdotN, float NdotH,
|
float LdotN, float NdotH) {
|
||||||
const float* ambient, const float* diffuse, const float* specular) {
|
|
||||||
|
|
||||||
float F;
|
float FI = (MATERIAL.exponent) ?
|
||||||
uint8_t FO;
|
faster_pow((LdotN != 0.0f) * NdotH, MATERIAL.exponent) : 1.0f;
|
||||||
float FI = (LdotN != 0.0f);
|
|
||||||
FI = (MATERIAL.exponent) ? faster_pow(FI * NdotH, MATERIAL.exponent) : 1.0f;
|
|
||||||
|
|
||||||
#define _PROCESS_COMPONENT(T, X) \
|
#define _PROCESS_COMPONENT(T, X) \
|
||||||
F = (ambient[X] * LIGHTS[lid].ambient[X]); \
|
do { \
|
||||||
F += (LdotN * diffuse[X] * LIGHTS[lid].diffuse[X]); \
|
float F = MATH_fmac(LdotN, LIGHTS[lid].diffuseMaterial[X], LIGHTS[lid].ambientMaterial[X]); \
|
||||||
F += FI * specular[X] * LIGHTS[lid].specular[X]; \
|
F += (FI * LIGHTS[lid].specularMaterial[X]); \
|
||||||
FO = (uint8_t) (_MIN(F * 255.0f, 255.0f)); \
|
uint8_t FO = (uint8_t) (_MIN(F * 255.0f, 255.0f)); \
|
||||||
final[T] += _MIN(FO, 255 - final[T]);
|
final[T] += _MIN(FO, 255 - final[T]); \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
_PROCESS_COMPONENT(R8IDX, 0);
|
_PROCESS_COMPONENT(R8IDX, 0);
|
||||||
_PROCESS_COMPONENT(G8IDX, 1);
|
_PROCESS_COMPONENT(G8IDX, 1);
|
||||||
|
@ -322,22 +399,19 @@ GL_FORCE_INLINE void _glLightVertexDirectional(
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_FORCE_INLINE void _glLightVertexPoint(
|
GL_FORCE_INLINE void _glLightVertexPoint(
|
||||||
uint8_t* final, int8_t lid,
|
uint8_t* final, uint8_t lid,
|
||||||
float LdotN, float NdotH, float att,
|
float LdotN, float NdotH, float att) {
|
||||||
const float* ambient, const float* diffuse, const float* specular) {
|
|
||||||
|
|
||||||
float F;
|
float FI = (MATERIAL.exponent) ?
|
||||||
uint8_t FO;
|
faster_pow((LdotN != 0.0f) * NdotH, MATERIAL.exponent) : 1.0f;
|
||||||
float FI = (LdotN != 0.0f);
|
|
||||||
FI = (MATERIAL.exponent) ? faster_pow(FI * NdotH, MATERIAL.exponent) : 1.0f;
|
|
||||||
|
|
||||||
#define _PROCESS_COMPONENT(T, X) \
|
#define _PROCESS_COMPONENT(T, X) \
|
||||||
F = (ambient[X] * LIGHTS[lid].ambient[X]); \
|
do { \
|
||||||
F += (LdotN * diffuse[X] * LIGHTS[lid].diffuse[X]); \
|
float F = MATH_fmac(LdotN, LIGHTS[lid].diffuseMaterial[X], LIGHTS[lid].ambientMaterial[X]); \
|
||||||
F += FI * specular[X] * LIGHTS[lid].specular[X]; \
|
F += (FI * LIGHTS[lid].specularMaterial[X]); \
|
||||||
FO = (uint8_t) (_MIN(F * att * 255.0f, 255.0f)); \
|
uint8_t FO = (uint8_t) (_MIN(F * att * 255.0f, 255.0f)); \
|
||||||
\
|
final[T] += _MIN(FO, 255 - final[T]); \
|
||||||
final[T] += _MIN(FO, 255 - final[T]); \
|
} while(0); \
|
||||||
|
|
||||||
_PROCESS_COMPONENT(R8IDX, 0);
|
_PROCESS_COMPONENT(R8IDX, 0);
|
||||||
_PROCESS_COMPONENT(G8IDX, 1);
|
_PROCESS_COMPONENT(G8IDX, 1);
|
||||||
|
@ -356,40 +430,26 @@ GL_FORCE_INLINE void bgra_to_float(const uint8_t* input, GLfloat* output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glPerformLighting(Vertex* vertices, const EyeSpaceData* es, const int32_t count) {
|
void _glPerformLighting(Vertex* vertices, const EyeSpaceData* es, const int32_t count) {
|
||||||
int8_t i;
|
uint8_t i;
|
||||||
int32_t j;
|
int32_t j;
|
||||||
|
|
||||||
Vertex* vertex = vertices;
|
Vertex* vertex = vertices;
|
||||||
const EyeSpaceData* data = es;
|
const EyeSpaceData* data = es;
|
||||||
float base;
|
|
||||||
|
|
||||||
/* This is the original vertex colour, before we replace it. It's
|
/* This is the original vertex colour, before we replace it. It's
|
||||||
* used for colour material */
|
* used for colour material */
|
||||||
float vdiffuse[4];
|
float vdiffuse[4];
|
||||||
|
|
||||||
unsigned char isCM = _glIsColorMaterialEnabled();
|
|
||||||
|
|
||||||
/* Update pointers as necessary depending on color material */
|
|
||||||
GLfloat* ambient = (isCM && isAmbientColorMaterial()) ? vdiffuse : MATERIAL.ambient;
|
|
||||||
GLfloat* diffuse = (isCM && isDiffuseColorMaterial()) ? vdiffuse : MATERIAL.diffuse;
|
|
||||||
GLfloat* specular = (isCM && isSpecularColorMaterial()) ? vdiffuse : MATERIAL.specular;
|
|
||||||
|
|
||||||
for(j = 0; j < count; ++j, ++vertex, ++data) {
|
for(j = 0; j < count; ++j, ++vertex, ++data) {
|
||||||
|
__builtin_prefetch(vertex + 1, 1, 1);
|
||||||
|
__builtin_prefetch(data + 1, 0, 1);
|
||||||
|
|
||||||
/* Unpack the colour for use in glColorMaterial */
|
/* Unpack the colour for use in glColorMaterial */
|
||||||
if(isCM) {
|
bgra_to_float(vertex->bgra, vdiffuse);
|
||||||
bgra_to_float(vertex->bgra, vdiffuse);
|
_glUpdateColourMaterial(vdiffuse);
|
||||||
}
|
|
||||||
|
|
||||||
/* Initial, non-light related values */
|
/* Copy the base colour across */
|
||||||
base = (SCENE_AMBIENT[0] * ambient[0]) + MATERIAL.emissive[0];
|
memcpy4(vertex->bgra, MATERIAL.baseColour, sizeof(GLubyte) * 4);
|
||||||
vertex->bgra[R8IDX] = (uint8_t)(_MIN(base * 255.0f, 255.0f));
|
|
||||||
|
|
||||||
base = (SCENE_AMBIENT[1] * ambient[1]) + MATERIAL.emissive[1];
|
|
||||||
vertex->bgra[G8IDX] = (uint8_t)(_MIN(base * 255.0f, 255.0f));
|
|
||||||
|
|
||||||
base = (SCENE_AMBIENT[2] * ambient[2]) + MATERIAL.emissive[2];
|
|
||||||
vertex->bgra[B8IDX] = (uint8_t)(_MIN(base * 255.0f, 255.0f));
|
|
||||||
vertex->bgra[A8IDX] = (uint8_t)(_MIN(MATERIAL.diffuse[3] * 255.0f, 255.0f));
|
|
||||||
|
|
||||||
/* Direction to vertex in eye space */
|
/* Direction to vertex in eye space */
|
||||||
float Vx = -data->xyz[0];
|
float Vx = -data->xyz[0];
|
||||||
|
@ -402,9 +462,11 @@ void _glPerformLighting(Vertex* vertices, const EyeSpaceData* es, const int32_t
|
||||||
const float Nz = data->n[2];
|
const float Nz = data->n[2];
|
||||||
|
|
||||||
for(i = 0; i < MAX_LIGHTS; ++i) {
|
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||||
|
__builtin_prefetch(LIGHTS + i + 1, 0, 1);
|
||||||
|
|
||||||
if(!_glIsLightEnabled(i)) continue;
|
if(!_glIsLightEnabled(i)) continue;
|
||||||
|
|
||||||
if(LIGHTS[i].position[3] == 0.0f) {
|
if(LIGHTS[i].isDirectional) {
|
||||||
float Lx = LIGHTS[i].position[0] - data->xyz[0];
|
float Lx = LIGHTS[i].position[0] - data->xyz[0];
|
||||||
float Ly = LIGHTS[i].position[1] - data->xyz[1];
|
float Ly = LIGHTS[i].position[1] - data->xyz[1];
|
||||||
float Lz = LIGHTS[i].position[2] - data->xyz[2];
|
float Lz = LIGHTS[i].position[2] - data->xyz[2];
|
||||||
|
@ -416,20 +478,22 @@ void _glPerformLighting(Vertex* vertices, const EyeSpaceData* es, const int32_t
|
||||||
vec3f_normalize(Lx, Ly, Lz);
|
vec3f_normalize(Lx, Ly, Lz);
|
||||||
vec3f_normalize(Hx, Hy, Hz);
|
vec3f_normalize(Hx, Hy, Hz);
|
||||||
|
|
||||||
const float LdotN = vec3_dot_limited(
|
float LdotN = MATH_fipr(
|
||||||
&Nx, &Ny, &Nz,
|
Nx, Ny, Nz, 1.0f,
|
||||||
&Lx, &Ly, &Lz
|
Lx, Ly, Lz, 1.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
const float NdotH = vec3_dot_limited(
|
float NdotH = MATH_fipr(
|
||||||
&Nx, &Ny, &Nz,
|
Nx, Ny, Nz, 1.0f,
|
||||||
&Hx, &Hy, &Hz
|
Hx, Hy, Hz, 1.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(LdotN < 0.0f) LdotN = 0.0f;
|
||||||
|
if(NdotH < 0.0f) NdotH = 0.0f;
|
||||||
|
|
||||||
_glLightVertexDirectional(
|
_glLightVertexDirectional(
|
||||||
vertex->bgra,
|
vertex->bgra,
|
||||||
i, LdotN, NdotH,
|
i, LdotN, NdotH
|
||||||
ambient, diffuse, specular
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
float Lx = LIGHTS[i].position[0] - data->xyz[0];
|
float Lx = LIGHTS[i].position[0] - data->xyz[0];
|
||||||
|
@ -445,7 +509,7 @@ void _glPerformLighting(Vertex* vertices, const EyeSpaceData* es, const int32_t
|
||||||
) + (LIGHTS[i].quadratic_attenuation * D * D)
|
) + (LIGHTS[i].quadratic_attenuation * D * D)
|
||||||
);
|
);
|
||||||
|
|
||||||
att = MATH_fsrra(att * att);
|
att = MATH_Fast_Invert(att);
|
||||||
|
|
||||||
if(att >= ATTENUATION_THRESHOLD) {
|
if(att >= ATTENUATION_THRESHOLD) {
|
||||||
float Hx = (Lx + Vx);
|
float Hx = (Lx + Vx);
|
||||||
|
@ -455,20 +519,22 @@ void _glPerformLighting(Vertex* vertices, const EyeSpaceData* es, const int32_t
|
||||||
vec3f_normalize(Lx, Ly, Lz);
|
vec3f_normalize(Lx, Ly, Lz);
|
||||||
vec3f_normalize(Hx, Hy, Hz);
|
vec3f_normalize(Hx, Hy, Hz);
|
||||||
|
|
||||||
const float LdotN = vec3_dot_limited(
|
float LdotN = MATH_fipr(
|
||||||
&Nx, &Ny, &Nz,
|
Nx, Ny, Nz, 1.0f,
|
||||||
&Lx, &Ly, &Lz
|
Lx, Ly, Lz, 1.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
const float NdotH = vec3_dot_limited(
|
float NdotH = MATH_fipr(
|
||||||
&Nx, &Ny, &Nz,
|
Nx, Ny, Nz, 1.0f,
|
||||||
&Hx, &Hy, &Hz
|
Hx, Hy, Hz, 1.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(LdotN < 0.0f) LdotN = 0.0f;
|
||||||
|
if(NdotH < 0.0f) NdotH = 0.0f;
|
||||||
|
|
||||||
_glLightVertexPoint(
|
_glLightVertexPoint(
|
||||||
vertex->bgra,
|
vertex->bgra,
|
||||||
i, LdotN, NdotH, att,
|
i, LdotN, NdotH, att
|
||||||
ambient, diffuse, specular
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
GL/private.h
15
GL/private.h
|
@ -163,6 +163,10 @@ typedef struct {
|
||||||
|
|
||||||
/* Valid values are 0-128 */
|
/* Valid values are 0-128 */
|
||||||
GLfloat exponent;
|
GLfloat exponent;
|
||||||
|
|
||||||
|
/* Base ambient + emission colour for
|
||||||
|
* the current material + light */
|
||||||
|
GLubyte baseColour[4];
|
||||||
} Material;
|
} Material;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -176,6 +180,15 @@ typedef struct {
|
||||||
GLfloat diffuse[4];
|
GLfloat diffuse[4];
|
||||||
GLfloat specular[4];
|
GLfloat specular[4];
|
||||||
GLfloat ambient[4];
|
GLfloat ambient[4];
|
||||||
|
|
||||||
|
GLboolean isDirectional;
|
||||||
|
|
||||||
|
/* We set these when the material changes
|
||||||
|
* so we don't calculate them per-vertex. They are
|
||||||
|
* light_value * materia_value */
|
||||||
|
GLfloat ambientMaterial[4];
|
||||||
|
GLfloat diffuseMaterial[4];
|
||||||
|
GLfloat specularMaterial[4];
|
||||||
} LightSource;
|
} LightSource;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -331,7 +344,7 @@ GLubyte _glKosHasError();
|
||||||
|
|
||||||
#define PVR_VERTEX_BUF_SIZE 2560 * 256
|
#define PVR_VERTEX_BUF_SIZE 2560 * 256
|
||||||
#define MAX_TEXTURE_UNITS 2
|
#define MAX_TEXTURE_UNITS 2
|
||||||
#define MAX_LIGHTS 8
|
#define MAX_LIGHTS 4
|
||||||
|
|
||||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
|
|
@ -286,7 +286,7 @@ int main(int argc, char **argv)
|
||||||
GLdcConfig config;
|
GLdcConfig config;
|
||||||
|
|
||||||
glKosInitConfig(&config);
|
glKosInitConfig(&config);
|
||||||
config.fsaa_enabled = GL_TRUE;
|
config.fsaa_enabled = GL_FALSE;
|
||||||
|
|
||||||
glKosInitEx(&config);
|
glKosInitEx(&config);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user