diff --git a/GL/clip.c b/GL/clip.c index c140c01..772386f 100644 --- a/GL/clip.c +++ b/GL/clip.c @@ -26,7 +26,7 @@ void _glEnableClipping(unsigned char v) { void _glClipLineToNearZ(const Vertex* v1, const Vertex* v2, Vertex* vout, float* t) __attribute__((optimize("fast-math"))); void _glClipLineToNearZ(const Vertex* v1, const Vertex* v2, Vertex* vout, float* t) { - const float NEAR_PLANE = 0.2; // FIXME: this needs to be read from the projection matrix.. somehow + const float NEAR_PLANE = NEAR_PLANE_DISTANCE + 0.0001f; *t = (NEAR_PLANE - v1->w) / (v2->w - v1->w); @@ -182,6 +182,13 @@ void _glClipTriangle(const Triangle* triangle, const uint8_t visible, Submission static inline void markDead(Vertex* vert) { vert->flags = VERTEX_CMD_EOL; + + // If we're debugging, wipe out the xyz +#ifndef NDEBUG + *((uint32_t*) &vert->xyz[0]) = 0xDEADBEEF; + *((uint32_t*) &vert->xyz[1]) = 0xDEADBEEF; + *((uint32_t*) &vert->xyz[2]) = 0xDEADBEEF; +#endif } #define B000 0 diff --git a/GL/draw.c b/GL/draw.c index b7a76ec..81d50f4 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -811,6 +811,7 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei genTriangleStrip(_glSubmissionTargetStart(target), count); break; default: + fprintf(stderr, "Unhandled mode %d\n", (int) mode); assert(0 && "Not Implemented"); } @@ -878,7 +879,7 @@ static void transform(SubmissionTarget* target) { register float __x __asm__("fr12") = (vertex->xyz[0]); register float __y __asm__("fr13") = (vertex->xyz[1]); register float __z __asm__("fr14") = (vertex->xyz[2]); - register float __w __asm__("fr15"); + register float __w __asm__("fr15") = (vertex->w); __asm__ __volatile__( "fldi1 fr15\n" @@ -977,14 +978,15 @@ static void divide(SubmissionTarget* target) { Vertex* vertex = _glSubmissionTargetStart(target); ITERATE(target->count) { - vertex->xyz[2] = 1.0f / vertex->w; - vertex->xyz[0] *= vertex->xyz[2]; - vertex->xyz[1] *= vertex->xyz[2]; + float f = 1.0f / vertex->w; + vertex->xyz[0] *= f; + vertex->xyz[1] *= f; + vertex->xyz[2] = 1.0 - ((DEPTH_RANGE_MULTIPLIER_L * vertex->xyz[2] * f) + DEPTH_RANGE_MULTIPLIER_H); ++vertex; } } -static void push(PVRHeader* header, Vertex* output, const GLuint count, PolyList* activePolyList, GLshort textureUnit) { +static void push(PVRHeader* header, GLboolean multiTextureHeader, PolyList* activePolyList, GLshort textureUnit) { TRACE(); // Compile the header @@ -993,6 +995,16 @@ static void push(PVRHeader* header, Vertex* output, const GLuint count, PolyList _glUpdatePVRTextureContext(&cxt, textureUnit); + if(multiTextureHeader) { + assert(cxt.list_type == PVR_LIST_TR_POLY); + + cxt.gen.alpha = PVR_ALPHA_ENABLE; + cxt.txr.alpha = PVR_TXRALPHA_ENABLE; + cxt.blend.src = PVR_BLEND_ZERO; + cxt.blend.dst = PVR_BLEND_DESTCOLOR; + cxt.depth.comparison = PVR_DEPTHCMP_EQUAL; + } + pvr_poly_compile(&header->hdr, &cxt); /* Post-process the vertex list */ @@ -1143,7 +1155,7 @@ static void submitVertices(GLenum mode, GLsizei first, GLuint count, GLenum type profiler_checkpoint("divide"); - push(_glSubmissionTargetHeader(target), _glSubmissionTargetStart(target), target->count, target->output, 0); + push(_glSubmissionTargetHeader(target), GL_FALSE, target->output, 0); profiler_checkpoint("push"); /* @@ -1179,7 +1191,6 @@ static void submitVertices(GLenum mode, GLsizei first, GLuint count, GLenum type assert(vertex); PVRHeader* mtHeader = (PVRHeader*) vertex++; - Vertex* mtStart = vertex; /* Replace the UV coordinates with the ST ones */ VertexExtra* ve = aligned_vector_at(target->extras, 0); @@ -1190,29 +1201,8 @@ static void submitVertices(GLenum mode, GLsizei first, GLuint count, GLenum type ++ve; } - /* Store state, as we're about to mess around with it */ - GLint depthFunc, blendSrc, blendDst; - glGetIntegerv(GL_DEPTH_FUNC, &depthFunc); - glGetIntegerv(GL_BLEND_SRC, &blendSrc); - glGetIntegerv(GL_BLEND_DST, &blendDst); - - GLboolean blendEnabled = glIsEnabled(GL_BLEND); - GLboolean depthEnabled = glIsEnabled(GL_DEPTH_TEST); - - glDepthFunc(GL_EQUAL); - glEnable(GL_BLEND); - - /* This is modulation, we need to switch depending on the texture env mode! */ - glBlendFunc(GL_DST_COLOR, GL_ZERO); - /* Send the buffer again to the transparent list */ - push(mtHeader, mtStart, target->count, _glTransparentPolyList(), 1); - - /* Reset state */ - glDepthFunc(depthFunc); - glBlendFunc(blendSrc, blendDst); - (blendEnabled) ? glEnable(GL_BLEND) : glDisable(GL_BLEND); - (depthEnabled) ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); + push(mtHeader, GL_TRUE, _glTransparentPolyList(), 1); profiler_pop(); } diff --git a/GL/glu.c b/GL/glu.c index ae9a590..0888207 100644 --- a/GL/glu.c +++ b/GL/glu.c @@ -4,14 +4,12 @@ /* Set the Perspective */ void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect, GLfloat znear, GLfloat zfar) { - GLfloat xmin, xmax, ymin, ymax; + GLdouble fW, fH; - ymax = znear * tanf(angle * F_PI / 360.0f); - ymin = -ymax; - xmin = ymin * aspect; - xmax = ymax * aspect; + fH = tan(angle / 360 * F_PI) * znear; + fW = fH * aspect; - glFrustum(xmin, xmax, ymin, ymax, znear, zfar); + glFrustum(-fW, fW, -fH, fH, znear, zfar); } void APIENTRY gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) { diff --git a/GL/matrix.c b/GL/matrix.c index 2de3e38..4037ca1 100644 --- a/GL/matrix.c +++ b/GL/matrix.c @@ -6,6 +6,7 @@ #include #include +#include "private.h" #include "../include/gl.h" #include "../containers/stack.h" @@ -15,46 +16,70 @@ static GLfloat gl_viewport_scale[3], gl_viewport_offset[3]; /* Depth range */ -static GLclampf gl_depthrange_near, gl_depthrange_far; +GLfloat DEPTH_RANGE_MULTIPLIER_L = (1 - 0) / 2; +GLfloat DEPTH_RANGE_MULTIPLIER_H = (0 + 1) / 2; /* Viewport size */ static GLint gl_viewport_x1, gl_viewport_y1, gl_viewport_width, gl_viewport_height; static Stack MATRIX_STACKS[3]; // modelview, projection, texture -static matrix_t NORMAL_MATRIX __attribute__((aligned(32))); -static matrix_t SCREENVIEW_MATRIX __attribute__((aligned(32))); +static Matrix4x4 NORMAL_MATRIX __attribute__((aligned(32))); +static Matrix4x4 SCREENVIEW_MATRIX __attribute__((aligned(32))); static GLenum MATRIX_MODE = GL_MODELVIEW; static GLubyte MATRIX_IDX = 0; -static const matrix_t IDENTITY = { - {1.0f, 0.0f, 0.0f, 0.0f}, - {0.0f, 1.0f, 0.0f, 0.0f}, - {0.0f, 0.0f, 1.0f, 0.0f}, - {0.0f, 0.0f, 0.0f, 1.0f} +static const Matrix4x4 IDENTITY = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; +GLfloat NEAR_PLANE_DISTANCE = 0.0f; + +static void _glStoreNearPlane() { + Matrix4x4* proj = (Matrix4x4*) stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)); + + GLfloat a = *(*proj + 10); + GLfloat b = *(*proj + 14); + + NEAR_PLANE_DISTANCE = -b / (1.0f - a); +} + void APIENTRY glDepthRange(GLclampf n, GLclampf f); -matrix_t* _glGetProjectionMatrix() { - return (matrix_t*) stack_top(&MATRIX_STACKS[1]); +static inline void upload_matrix(Matrix4x4* m) { + mat_load((matrix_t*) m); } -matrix_t* _glGetModelViewMatrix() { - return (matrix_t*) stack_top(&MATRIX_STACKS[0]); +static inline void multiply_matrix(Matrix4x4* m) { + mat_apply((matrix_t*) m); +} + +static inline void download_matrix(Matrix4x4* m) { + mat_store((matrix_t*) m); +} + +Matrix4x4* _glGetProjectionMatrix() { + return (Matrix4x4*) stack_top(&MATRIX_STACKS[1]); +} + +Matrix4x4* _glGetModelViewMatrix() { + return (Matrix4x4*) stack_top(&MATRIX_STACKS[0]); } void _glInitMatrices() { - init_stack(&MATRIX_STACKS[0], sizeof(matrix_t), 32); - init_stack(&MATRIX_STACKS[1], sizeof(matrix_t), 32); - init_stack(&MATRIX_STACKS[2], sizeof(matrix_t), 32); + init_stack(&MATRIX_STACKS[0], sizeof(Matrix4x4), 32); + init_stack(&MATRIX_STACKS[1], sizeof(Matrix4x4), 32); + init_stack(&MATRIX_STACKS[2], sizeof(Matrix4x4), 32); stack_push(&MATRIX_STACKS[0], IDENTITY); stack_push(&MATRIX_STACKS[1], IDENTITY); stack_push(&MATRIX_STACKS[2], IDENTITY); - memcpy(NORMAL_MATRIX, IDENTITY, sizeof(matrix_t)); - memcpy(SCREENVIEW_MATRIX, IDENTITY, sizeof(matrix_t)); + memcpy(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4)); + memcpy(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4)); glDepthRange(0.0f, 1.0f); glViewport(0, 0, vid_mode->width, vid_mode->height); @@ -98,7 +123,7 @@ static void transpose(GLfloat* m) { } static void recalculateNormalMatrix() { - memcpy(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(matrix_t)); + memcpy(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4)); inverse((GLfloat*) NORMAL_MATRIX); transpose((GLfloat*) NORMAL_MATRIX); } @@ -124,9 +149,20 @@ void APIENTRY glLoadIdentity() { } void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) { - mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); - mat_translate(x, y, z); - mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + static Matrix4x4 trn __attribute__((aligned(32))) = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + trn[M12] = x; + trn[M13] = y; + trn[M14] = z; + + upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + multiply_matrix(&trn); + download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -135,9 +171,20 @@ void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) { void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) { - mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); - mat_scale(x, y, z); - mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + static Matrix4x4 scale __attribute__((aligned(32))) = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + scale[M0] = x; + scale[M5] = y; + scale[M10] = z; + + upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + multiply_matrix(&scale); + download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -145,13 +192,42 @@ void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) { } void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + static Matrix4x4 rotate __attribute__((aligned(32))) = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + float r = DEG2RAD * -angle; + float c = cos(r); + float s = sin(r); + float invc = 1.0f - c; + float xs = x * s; + float zs = z * s; + float ys = y * s; + float xz = x * z; + float xy = y * x; + float yz = y * z; + vec3f_normalize(x, y, z); - mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); - mat_rotate(r * x, r * y, r * z); - mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + rotate[M0] = (x * x) * invc + c; + rotate[M1] = xy * invc + zs; + rotate[M2] = xz * invc - ys; + + rotate[M4] = xy * invc - zs; + rotate[M5] = (y * y) * invc + c; + rotate[M6] = yz * invc + xs; + + rotate[M8] = xz * invc + ys; + rotate[M9] = yz * invc - xs; + rotate[M10] = (z * z) * invc + c; + + upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + multiply_matrix(&rotate); + download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -160,7 +236,29 @@ void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { /* Load an arbitrary matrix */ void APIENTRY glLoadMatrixf(const GLfloat *m) { - stack_replace(MATRIX_STACKS + MATRIX_IDX, m); + static Matrix4x4 TEMP; + + TEMP[M0] = m[0]; + TEMP[M1] = m[1]; + TEMP[M2] = m[2]; + TEMP[M3] = m[3]; + + TEMP[M4] = m[4]; + TEMP[M5] = m[5]; + TEMP[M6] = m[6]; + TEMP[M7] = m[7]; + + TEMP[M8] = m[8]; + TEMP[M9] = m[9]; + TEMP[M10] = m[10]; + TEMP[M11] = m[11]; + + TEMP[M12] = m[12]; + TEMP[M13] = m[13]; + TEMP[M14] = m[14]; + TEMP[M15] = m[15]; + + stack_replace(MATRIX_STACKS + MATRIX_IDX, TEMP); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -173,23 +271,23 @@ void APIENTRY glOrtho(GLfloat left, GLfloat right, GLfloat znear, GLfloat zfar) { /* Ortho Matrix */ - static matrix_t OrthoMatrix __attribute__((aligned(32))) = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } + static Matrix4x4 OrthoMatrix __attribute__((aligned(32))) = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; - OrthoMatrix[0][0] = 2.0f / (right - left); - OrthoMatrix[1][1] = 2.0f / (top - bottom); - OrthoMatrix[2][2] = -2.0f / (zfar - znear); - OrthoMatrix[3][0] = -(right + left) / (right - left);; - OrthoMatrix[3][1] = -(top + bottom) / (top - bottom); - OrthoMatrix[3][2] = -(zfar + znear) / (zfar - znear); + OrthoMatrix[M0] = 2.0f / (right - left); + OrthoMatrix[M5] = 2.0f / (top - bottom); + OrthoMatrix[M10] = -2.0f / (zfar - znear); + OrthoMatrix[M12] = -(right + left) / (right - left); + OrthoMatrix[M13] = -(top + bottom) / (top - bottom); + OrthoMatrix[M14] = -(zfar + znear) / (zfar - znear); - mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); - mat_apply(&OrthoMatrix); - mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + multiply_matrix(&OrthoMatrix); + download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); } @@ -199,84 +297,145 @@ void APIENTRY glFrustum(GLfloat left, GLfloat right, GLfloat znear, GLfloat zfar) { /* Frustum Matrix */ - static matrix_t FrustumMatrix __attribute__((aligned(32))) = { - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, -1.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f } - }; + static Matrix4x4 FrustumMatrix __attribute__((aligned(32))); - FrustumMatrix[0][0] = (2.0f * znear) / (right - left); - FrustumMatrix[2][0] = (right + left) / (right - left); - FrustumMatrix[1][1] = (2.0f * znear) / (top - bottom); - FrustumMatrix[2][1] = (top + bottom) / (top - bottom); - FrustumMatrix[2][2] = zfar / (zfar - znear); - FrustumMatrix[3][2] = -(zfar * znear) / (zfar - znear); + memset(FrustumMatrix, 0, sizeof(float) * 16); - mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); - mat_apply(&FrustumMatrix); - mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + const float near2 = 2.0f * znear; + const float A = (right + left) / (right - left); + const float B = (top + bottom) / (top - bottom); + const float C = -((zfar + znear) / (zfar - znear)); + const float D = -((2.0f * zfar * znear) / (zfar - znear)); + + FrustumMatrix[M0] = near2 / (right - left); + FrustumMatrix[M5] = near2 / (top - bottom); + + FrustumMatrix[M8] = A; + FrustumMatrix[M9] = B; + FrustumMatrix[M10] = C; + FrustumMatrix[M11] = -1.0f; + FrustumMatrix[M14] = D; + + upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + multiply_matrix(&FrustumMatrix); + download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + + if(MATRIX_MODE == GL_PROJECTION) { + _glStoreNearPlane(); + } } /* Multiply the current matrix by an arbitrary matrix */ void glMultMatrixf(const GLfloat *m) { - static matrix_t TEMP __attribute__((aligned(32))) = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } - }; + static Matrix4x4 TEMP; - memcpy(TEMP, m, sizeof(matrix_t)); + TEMP[M0] = m[0]; + TEMP[M1] = m[1]; + TEMP[M2] = m[2]; + TEMP[M3] = m[3]; - mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); - mat_apply(&TEMP); - mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + TEMP[M4] = m[4]; + TEMP[M5] = m[5]; + TEMP[M6] = m[6]; + TEMP[M7] = m[7]; + + TEMP[M8] = m[8]; + TEMP[M9] = m[9]; + TEMP[M10] = m[10]; + TEMP[M11] = m[11]; + + TEMP[M12] = m[12]; + TEMP[M13] = m[13]; + TEMP[M14] = m[14]; + TEMP[M15] = m[15]; + + upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + multiply_matrix((Matrix4x4*) &TEMP); + download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); } + + if(MATRIX_MODE == GL_PROJECTION) { + _glStoreNearPlane(); + } } /* Load an arbitrary transposed matrix */ void glLoadTransposeMatrixf(const GLfloat *m) { - stack_replace(MATRIX_STACKS + MATRIX_IDX, m); - transpose(stack_top(MATRIX_STACKS + MATRIX_IDX)); + /* We store matrices transpose anyway, so m will be + * transpose compared to all other matrices */ + + static Matrix4x4 TEMP __attribute__((aligned(32))); + + TEMP[M0] = m[0]; + TEMP[M1] = m[4]; + TEMP[M2] = m[8]; + TEMP[M3] = m[12]; + + TEMP[M4] = m[1]; + TEMP[M5] = m[5]; + TEMP[M6] = m[9]; + TEMP[M7] = m[13]; + + TEMP[M8] = m[3]; + TEMP[M9] = m[6]; + TEMP[M10] = m[10]; + TEMP[M11] = m[14]; + + TEMP[M12] = m[4]; + TEMP[M13] = m[7]; + TEMP[M14] = m[11]; + TEMP[M15] = m[15]; + + stack_replace(MATRIX_STACKS + MATRIX_IDX, TEMP); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); } + + if(MATRIX_MODE == GL_PROJECTION) { + _glStoreNearPlane(); + } } /* Multiply the current matrix by an arbitrary transposed matrix */ void glMultTransposeMatrixf(const GLfloat *m) { - static matrix_t ml; + static Matrix4x4 TEMP __attribute__((aligned(32))); - ml[0][0] = m[0]; - ml[0][1] = m[4]; - ml[0][2] = m[8]; - ml[0][3] = m[12]; - ml[1][0] = m[1]; - ml[1][1] = m[5]; - ml[1][2] = m[9]; - ml[1][3] = m[13]; - ml[2][0] = m[2]; - ml[2][1] = m[6]; - ml[2][2] = m[10]; - ml[2][3] = m[14]; - ml[3][0] = m[3]; - ml[3][1] = m[7]; - ml[3][2] = m[11]; - ml[3][3] = m[15]; + TEMP[M0] = m[0]; + TEMP[M1] = m[4]; + TEMP[M2] = m[8]; + TEMP[M3] = m[12]; - mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); - mat_apply(&ml); - mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + TEMP[M4] = m[1]; + TEMP[M5] = m[5]; + TEMP[M6] = m[9]; + TEMP[M7] = m[13]; + + TEMP[M8] = m[3]; + TEMP[M9] = m[6]; + TEMP[M10] = m[10]; + TEMP[M11] = m[14]; + + TEMP[M12] = m[4]; + TEMP[M13] = m[7]; + TEMP[M14] = m[11]; + TEMP[M15] = m[15]; + + upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + multiply_matrix(&TEMP); + download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); } + + if(MATRIX_MODE == GL_PROJECTION) { + _glStoreNearPlane(); + } } /* Set the GL viewport */ @@ -294,30 +453,27 @@ void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { GLfloat hw = ((GLfloat) width) / 2.0f; GLfloat hh = ((GLfloat) height) / 2.0f; - SCREENVIEW_MATRIX[0][0] = hw; - SCREENVIEW_MATRIX[1][1] = -hh; - SCREENVIEW_MATRIX[2][2] = 1; //(gl_depthrange_far - gl_depthrange_near) / 2.0f; - SCREENVIEW_MATRIX[3][0] = (rw + lw) / 2.0f; - SCREENVIEW_MATRIX[3][1] = (tw + bw) / 2.0f; - // SCREENVIEW_MATRIX[3][2] = (gl_depthrange_far + gl_depthrange_near) / 2.0f; + SCREENVIEW_MATRIX[M0] = hw; + SCREENVIEW_MATRIX[M5] = -hh; + SCREENVIEW_MATRIX[M10] = 1; + SCREENVIEW_MATRIX[M12] = (rw + lw) / 2.0f; + SCREENVIEW_MATRIX[M13] = (tw + bw) / 2.0f; +} + +GLfloat _glGetNearPlane() { + return NEAR_PLANE_DISTANCE; } /* Set the depth range */ void APIENTRY glDepthRange(GLclampf n, GLclampf f) { - /* FIXME: This currently does nothing because the SCREENVIEW_MATRIX is multiplied prior to perpective division - * and not after as traditional GL. See here for more info: http://www.thecodecrate.com/opengl-es/opengl-viewport-matrix/ - * - * We probably need to make tweaks to the SCREENVIEW matrix or clipping or whatever to make this work - */ - if(n < 0.0f) n = 0.0f; else if(n > 1.0f) n = 1.0f; if(f < 0.0f) f = 0.0f; else if(f > 1.0f) f = 1.0f; - gl_depthrange_near = n; - gl_depthrange_far = f; + DEPTH_RANGE_MULTIPLIER_L = (f - n) / 2.0f; + DEPTH_RANGE_MULTIPLIER_H = (n + f) / 2.0f; } /* Vector Cross Product - Used by glhLookAtf2 */ @@ -333,11 +489,11 @@ void glhLookAtf2(const GLfloat* eyePosition3D, const GLfloat* upVector3D) { /* Look-At Matrix */ - static matrix_t MatrixLookAt __attribute__((aligned(32))) = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } + static Matrix4x4 MatrixLookAt __attribute__((aligned(32))) = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; GLfloat forward[3]; @@ -355,32 +511,40 @@ void glhLookAtf2(const GLfloat* eyePosition3D, //Recompute up as: up = side x forward vec3f_cross(side, forward, up); - MatrixLookAt[0][0] = side[0]; - MatrixLookAt[1][0] = side[1]; - MatrixLookAt[2][0] = side[2]; - MatrixLookAt[3][0] = 0; + MatrixLookAt[M0] = side[0]; + MatrixLookAt[M4] = side[1]; + MatrixLookAt[M8] = side[2]; + MatrixLookAt[M12] = 0; - MatrixLookAt[0][1] = up[0]; - MatrixLookAt[1][1] = up[1]; - MatrixLookAt[2][1] = up[2]; - MatrixLookAt[3][1] = 0; + MatrixLookAt[M1] = up[0]; + MatrixLookAt[M5] = up[1]; + MatrixLookAt[M9] = up[2]; + MatrixLookAt[M13] = 0; - MatrixLookAt[0][2] = -forward[0]; - MatrixLookAt[1][2] = -forward[1]; - MatrixLookAt[2][2] = -forward[2]; - MatrixLookAt[3][2] = 0; + MatrixLookAt[M2] = -forward[0]; + MatrixLookAt[M6] = -forward[1]; + MatrixLookAt[M10] = -forward[2]; + MatrixLookAt[M14] = 0; - MatrixLookAt[0][3] = - MatrixLookAt[1][3] = - MatrixLookAt[2][3] = 0; - MatrixLookAt[3][3] = 1; + MatrixLookAt[M3] = MatrixLookAt[11] = MatrixLookAt[15] = 0; + MatrixLookAt[M15] = 1; + + static Matrix4x4 trn __attribute__((aligned(32))) = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + trn[M12] = -eyePosition3D[0]; + trn[M13] = -eyePosition3D[1]; + trn[M14] = -eyePosition3D[2]; // Does not modify internal Modelview matrix - mat_load(&MatrixLookAt); - mat_translate(-eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]); - - mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); - mat_store(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + upload_matrix(&MatrixLookAt); + multiply_matrix(&trn); + multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + download_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); } void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, @@ -393,19 +557,19 @@ void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, } void _glApplyRenderMatrix() { - mat_load(&SCREENVIEW_MATRIX); - mat_apply(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF))); - mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + upload_matrix(&SCREENVIEW_MATRIX); + multiply_matrix(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF))); + multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); } void _glMatrixLoadTexture() { - mat_load(stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF))); + upload_matrix(stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF))); } void _glMatrixLoadModelView() { - mat_load(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + upload_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); } void _glMatrixLoadNormal() { - mat_load(&NORMAL_MATRIX); + upload_matrix(&NORMAL_MATRIX); } diff --git a/GL/private.h b/GL/private.h index ee78b3d..e1ad867 100644 --- a/GL/private.h +++ b/GL/private.h @@ -23,6 +23,49 @@ #define MAX_TEXTURE_SIZE 1024 +typedef float Matrix4x4[16]; + +/* This gives us an easy way to switch + * internal matrix order if necessary */ + +#define TRANSPOSE 0 + +#if TRANSPOSE +#define M0 0 +#define M1 4 +#define M2 8 +#define M3 12 +#define M4 1 +#define M5 5 +#define M6 9 +#define M7 13 +#define M8 2 +#define M9 6 +#define M10 10 +#define M11 14 +#define M12 3 +#define M13 7 +#define M14 11 +#define M15 15 +#else +#define M0 0 +#define M1 1 +#define M2 2 +#define M3 3 +#define M4 4 +#define M5 5 +#define M6 6 +#define M7 7 +#define M8 8 +#define M9 9 +#define M10 10 +#define M11 11 +#define M12 12 +#define M13 13 +#define M14 14 +#define M15 15 +#endif + typedef struct { pvr_poly_hdr_t hdr; } PVRHeader; @@ -195,8 +238,11 @@ void _glMatrixLoadModelView(); void _glMatrixLoadTexture(); void _glApplyRenderMatrix(); -matrix_t* _glGetProjectionMatrix(); -matrix_t* _glGetModelViewMatrix(); +extern GLfloat DEPTH_RANGE_MULTIPLIER_L; +extern GLfloat DEPTH_RANGE_MULTIPLIER_H; + +Matrix4x4* _glGetProjectionMatrix(); +Matrix4x4* _glGetModelViewMatrix(); void _glWipeTextureOnFramebuffers(GLuint texture); GLubyte _glCheckImmediateModeInactive(const char* func); @@ -207,6 +253,10 @@ GLubyte _glInitTextures(); void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit); void _glAllocateSpaceForMipmaps(TextureObject* active); +extern GLfloat NEAR_PLANE_DISTANCE; + +GLfloat _glGetNearPlane(); + typedef struct { const void* ptr; GLenum type; diff --git a/GL/state.c b/GL/state.c index 2e718bf..f927c54 100644 --- a/GL/state.c +++ b/GL/state.c @@ -421,7 +421,6 @@ GLAPI void APIENTRY glReadBuffer(GLenum mode) { GLAPI void APIENTRY glDepthMask(GLboolean flag) { GL_CONTEXT.depth.write = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE; - GL_CONTEXT.depth.comparison = _calc_pvr_depth_test(); } GLAPI void APIENTRY glDepthFunc(GLenum func) {