diff --git a/GL/draw.c b/GL/draw.c index 02a4c10..cc9a744 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -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]; diff --git a/GL/immediate.c b/GL/immediate.c index eced866..ab29025 100644 --- a/GL/immediate.c +++ b/GL/immediate.c @@ -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); } diff --git a/GL/lighting.c b/GL/lighting.c index 064b21c..eb95b17 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -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; } diff --git a/GL/matrix.c b/GL/matrix.c index e9e4703..0c36219 100644 --- a/GL/matrix.c +++ b/GL/matrix.c @@ -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 */ diff --git a/GL/private.h b/GL/private.h index 6f081cd..b64c192 100644 --- a/GL/private.h +++ b/GL/private.h @@ -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; diff --git a/gl-api.c b/gl-api.c index 852d42d..a62e717 100644 --- a/gl-api.c +++ b/gl-api.c @@ -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 ==// diff --git a/include/gl.h b/include/gl.h index 38e3caa..eb9dc46 100644 --- a/include/gl.h +++ b/include/gl.h @@ -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 *);