Fix lighting bugs

This commit is contained in:
Luke Benstead 2018-05-19 09:17:24 +01:00
parent cd71de76ee
commit 23e564269b
7 changed files with 115 additions and 87 deletions

View File

@ -35,6 +35,26 @@ void initAttributePointers() {
VERTEX_POINTER.stride = 0;
VERTEX_POINTER.type = GL_FLOAT;
VERTEX_POINTER.size = 4;
DIFFUSE_POINTER.ptr = NULL;
DIFFUSE_POINTER.stride = 0;
DIFFUSE_POINTER.type = GL_FLOAT;
DIFFUSE_POINTER.size = 4;
UV_POINTER.ptr = NULL;
UV_POINTER.stride = 0;
UV_POINTER.type = GL_FLOAT;
UV_POINTER.size = 4;
ST_POINTER.ptr = NULL;
ST_POINTER.stride = 0;
ST_POINTER.type = GL_FLOAT;
ST_POINTER.size = 4;
NORMAL_POINTER.ptr = NULL;
NORMAL_POINTER.stride = 0;
NORMAL_POINTER.type = GL_FLOAT;
NORMAL_POINTER.size = 3;
}
static GLuint byte_size(GLenum type) {
@ -46,6 +66,7 @@ static GLuint byte_size(GLenum type) {
case GL_INT: return sizeof(GLint);
case GL_UNSIGNED_INT: return sizeof(GLuint);
case GL_DOUBLE: return sizeof(GLdouble);
case GL_FLOAT:
default: return sizeof(GLfloat);
}
}
@ -90,7 +111,7 @@ static void _parseColour(uint32* out, const GLubyte* in, GLint size, GLenum type
}
static void _parseFloats(GLfloat* out, const GLubyte* in, GLint size, GLenum type) {
GLubyte i = 0;
GLubyte i;
switch(type) {
case GL_SHORT: {
@ -107,8 +128,10 @@ static void _parseFloats(GLfloat* out, const GLubyte* in, GLint size, GLenum typ
} break;
case GL_FLOAT:
case GL_DOUBLE: /* Double == Float */
default:
for(i = 0; i < size; ++i) out[i] = ((GLfloat*) in)[i];
default: {
const GLfloat* ptr = (const GLfloat*) in;
for(i = 0; i < size; ++i) out[i] = ptr[i];
}
}
}
@ -123,27 +146,52 @@ static void _parseIndex(GLshort* out, const GLubyte* in, GLenum type) {
}
}
/*
inline void mat_trans_float3_nodiv(const GLfloat* mat, GLfloat* v) {
GLfloat x = v[0] * mat[0] + v[1] * mat[4] + v[2] * mat[8] + mat[12];
GLfloat y = v[0] * mat[1] + v[1] * mat[5] + v[2] * mat[9] + mat[13];
GLfloat z = v[0] * mat[2] + v[1] * mat[6] + v[2] * mat[10] + mat[14];
v[0] = x;
v[1] = y;
v[2] = z;
} */
/* There was a bug in this macro that shipped with Kos
* which has now been fixed. But just in case...
*/
#undef mat_trans_single3_nodiv
#define mat_trans_single3_nodiv(x, y, z) { \
register float __x __asm__("fr12") = (x); \
register float __y __asm__("fr13") = (y); \
register float __z __asm__("fr14") = (z); \
__asm__ __volatile__( \
"fldi1 fr15\n" \
"ftrv xmtrx, fv12\n" \
: "=f" (__x), "=f" (__y), "=f" (__z) \
: "0" (__x), "1" (__y), "2" (__z) \
: "fr15"); \
x = __x; y = __y; z = __z; \
}
void transformToEyeSpace(GLfloat* point) {
#undef mat_trans_normal3
#define mat_trans_normal3(x, y, z) { \
register float __x __asm__("fr8") = (x); \
register float __y __asm__("fr9") = (y); \
register float __z __asm__("fr10") = (z); \
__asm__ __volatile__( \
"fldi0 fr11\n" \
"ftrv xmtrx, fv8\n" \
: "=f" (__x), "=f" (__y), "=f" (__z) \
: "0" (__x), "1" (__y), "2" (__z) \
: "fr11"); \
x = __x; y = __y; z = __z; \
}
inline void transformToEyeSpace(GLfloat* point) {
_matrixLoadModelView();
mat_trans_single3_nodiv(point[0], point[1], point[2]);
}
void transformNormalToEyeSpace(GLfloat* normal) {
inline void transformNormalToEyeSpace(GLfloat* normal) {
_matrixLoadNormal();
mat_trans_normal3(normal[0], normal[1], normal[2]);
}
static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) {
static GLfloat normal[3] = {0.0f, 0.0f, -1.0f};
static GLfloat eye_P[3];
@ -242,7 +290,7 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
GLubyte j;
for(j = 0; j < MAX_LIGHTS; ++j) {
if(isLightEnabled(i)) {
if(isLightEnabled(j)) {
calculateLightingContribution(j, eye_P, eye_N, to_add);
contribution[0] += to_add[0];

View File

@ -89,6 +89,14 @@ void APIENTRY glVertex3fv(const GLfloat* v) {
glVertex3f(v[0], v[1], v[2]);
}
void APIENTRY glVertex2f(GLfloat x, GLfloat y) {
glVertex3f(x, y, 0.0f);
}
void APIENTRY glVertex2fv(const GLfloat* v) {
glVertex2f(v[0], v[1]);
}
void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
glVertex3f(x, y, z);
}

View File

@ -21,9 +21,6 @@ void initLights() {
memcpy(MATERIAL.specular, ZERO, sizeof(GLfloat) * 4);
memcpy(MATERIAL.emissive, ZERO, sizeof(GLfloat) * 4);
MATERIAL.exponent = 0.0f;
MATERIAL.ambient_color_index = 0.0f;
MATERIAL.diffuse_color_index = 1.0f;
MATERIAL.specular_color_index = 1.0f;
GLubyte i;
for(i = 0; i < MAX_LIGHTS; ++i) {
@ -231,36 +228,52 @@ static float FPOW(float b, float p) {
void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) {
LightSource* l = &LIGHTS[light];
struct vec3f L, N, V;
struct vec3f L = {
l->position[0] - pos[0],
l->position[1] - pos[1],
l->position[2] - pos[2]
};
L.x = l->position[0] - pos[0];
L.y = l->position[1] - pos[1];
L.z = l->position[2] - pos[2];
struct vec3f N = {
normal[0],
normal[1],
normal[2]
};
N.x = normal[0];
N.y = normal[1];
N.z = normal[2];
struct vec3f V = {
pos[0],
pos[1],
pos[2]
};
V.x = -pos[0];
V.y = -pos[1];
V.z = -pos[2];
GLfloat d;
vec3f_length(V.x, V.y, V.z, d);
vec3f_normalize(L.x, L.y, L.z);
vec3f_normalize(V.x, V.y, V.z);
GLfloat LdotN;
vec3f_dot(L.x, L.y, L.z, N.x, N.y, N.z, LdotN);
GLfloat NdotL;
vec3f_dot(N.x, N.y, N.z, L.x, L.y, L.z, NdotL);
GLfloat f = (LdotN < 0) ? 0 : 1;
GLfloat f = (NdotL < 0) ? 0 : 1;
GLfloat VdotN;
vec3f_dot(V.x, V.y, V.z, N.x, N.y, N.z, VdotN);
GLfloat VdotR = VdotN - LdotN;
GLfloat VdotR = VdotN - NdotL;
GLfloat specularPower = FPOW(VdotR > 0 ? VdotR : 0, MATERIAL.exponent);
colour[0] = l->ambient[0] * MATERIAL.ambient[0] + f * (l->diffuse[0] * MATERIAL.diffuse[0] * LdotN + l->specular[0] * MATERIAL.specular[0] * specularPower);
colour[1] = l->ambient[1] * MATERIAL.ambient[1] + f * (l->diffuse[1] * MATERIAL.diffuse[1] * LdotN + l->specular[1] * MATERIAL.specular[1] * specularPower);
colour[2] = l->ambient[2] * MATERIAL.ambient[2] + f * (l->diffuse[2] * MATERIAL.diffuse[2] * LdotN + l->specular[2] * MATERIAL.specular[2] * specularPower);
GLfloat att = (l->position[3] == 0) ? 1.0f : (
l->constant_attenuation / (1.0f + l->linear_attenuation * d) * (1.0f + l->quadratic_attenuation * d * d)
);
colour[0] = att * l->ambient[0] * MATERIAL.ambient[0] + f * (l->diffuse[0] * MATERIAL.diffuse[0] * NdotL + l->specular[0] * MATERIAL.specular[0] * specularPower);
colour[1] = att * l->ambient[1] * MATERIAL.ambient[1] + f * (l->diffuse[1] * MATERIAL.diffuse[1] * NdotL + l->specular[1] * MATERIAL.specular[1] * specularPower);
colour[2] = att * l->ambient[2] * MATERIAL.ambient[2] + f * (l->diffuse[2] * MATERIAL.diffuse[2] * NdotL + l->specular[2] * MATERIAL.specular[2] * specularPower);
colour[3] = MATERIAL.diffuse[3];
if(colour[0] > 1.0f) colour[0] = 1.0f;
if(colour[1] > 1.0f) colour[1] = 1.0f;
if(colour[2] > 1.0f) colour[2] = 1.0f;
if(colour[3] > 1.0f) colour[3] = 1.0f;
}

View File

@ -85,8 +85,8 @@ static void transpose(GLfloat* m) {
static void recalculateNormalMatrix() {
memcpy(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(matrix_t));
transpose((GLfloat*) NORMAL_MATRIX);
inverse((GLfloat*) NORMAL_MATRIX);
transpose((GLfloat*) NORMAL_MATRIX);
}
void APIENTRY glMatrixMode(GLenum mode) {
@ -271,6 +271,10 @@ void glMultTransposeMatrixf(const GLfloat *m) {
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX));
mat_apply(&ml);
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX));
if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix();
}
}
/* Set the GL viewport */

View File

@ -42,27 +42,24 @@ typedef struct {
} TextureObject;
typedef struct {
GLfloat emissive[4];
GLfloat ambient[4];
GLfloat diffuse[4];
GLfloat specular[4];
GLfloat emissive[4];
GLfloat specular[4];
GLfloat exponent;
GLfloat ambient_color_index;
GLfloat diffuse_color_index;
GLfloat specular_color_index;
} Material;
typedef struct {
GLfloat ambient[4];
GLfloat diffuse[4];
GLfloat specular[4];
GLfloat position[4];
GLfloat spot_direction[3];
GLfloat spot_exponent;
GLfloat spot_cutoff;
GLfloat constant_attenuation;
GLfloat linear_attenuation;
GLfloat quadratic_attenuation;
GLfloat spot_exponent;
GLfloat diffuse[4];
GLfloat specular[4];
GLfloat ambient[4];
} LightSource;

View File

@ -251,14 +251,6 @@ void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
//== Vertex Position Submission Functions ==//
void APIENTRY glVertex2f(GLfloat x, GLfloat y) {
return _glKosVertex3ft(x, y, 0.0f);
}
void APIENTRY glVertex2fv(const GLfloat *xy) {
return _glKosVertex3ft(xy[0], xy[1], 0.0f);
}
void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) {
pvr_vertex_t *v = _glKosVertexBufPointer();
@ -289,36 +281,6 @@ void APIENTRY glRectiv(const GLint *v1, const GLint *v2) {
return glRectfv((const GLfloat *)v1, (const GLfloat *)v2);
}
void APIENTRY glKosVertex2f(GLfloat x, GLfloat y) {
pvr_vertex_t *v = _glKosVertexBufPointer();
v->x = x;
v->y = y;
v->z = 10;
v->u = GL_KOS_VERTEX_UV[0];
v->v = GL_KOS_VERTEX_UV[1];
v->argb = GL_KOS_VERTEX_COLOR;
_glKosVertexBufIncrement();
++GL_KOS_VERTEX_COUNT;
}
void APIENTRY glKosVertex2fv(const GLfloat *xy) {
pvr_vertex_t *v = _glKosVertexBufPointer();
v->x = xy[0];
v->y = xy[1];
v->z = 10;
v->u = GL_KOS_VERTEX_UV[0];
v->v = GL_KOS_VERTEX_UV[1];
v->argb = GL_KOS_VERTEX_COLOR;
_glKosVertexBufIncrement();
++GL_KOS_VERTEX_COUNT;
}
//====================================================================================================//
//== GL Begin / End ==//

View File

@ -436,10 +436,6 @@ GLAPI void APIENTRY glVertex2f(GLfloat x, GLfloat y);
GLAPI void APIENTRY glVertex2fv(const GLfloat *xy);
#define glVertex2iv glVertex2fv
/* Non-Standard KOS Primitive 2D Submission. This will perform no tranformations on the vertices. */
GLAPI void APIENTRY glKosVertex2f(GLfloat x, GLfloat y);
GLAPI void APIENTRY glKosVertex2fv(const GLfloat *xy);
/* Primitive 3D Position Submission */
GLAPI void APIENTRY glVertex3f(GLfloat, GLfloat, GLfloat);
GLAPI void APIENTRY glVertex3fv(const GLfloat *);