Merge branch 'fixed-depth-issues'

This commit is contained in:
Luke Benstead 2019-09-15 14:27:41 +01:00
commit 96c103e379
6 changed files with 382 additions and 174 deletions

View File

@ -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) __attribute__((optimize("fast-math")));
void _glClipLineToNearZ(const Vertex* v1, const Vertex* v2, Vertex* vout, float* t) { 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); *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) { static inline void markDead(Vertex* vert) {
vert->flags = VERTEX_CMD_EOL; 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 #define B000 0

View File

@ -811,6 +811,7 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei
genTriangleStrip(_glSubmissionTargetStart(target), count); genTriangleStrip(_glSubmissionTargetStart(target), count);
break; break;
default: default:
fprintf(stderr, "Unhandled mode %d\n", (int) mode);
assert(0 && "Not Implemented"); assert(0 && "Not Implemented");
} }
@ -878,7 +879,7 @@ static void transform(SubmissionTarget* target) {
register float __x __asm__("fr12") = (vertex->xyz[0]); register float __x __asm__("fr12") = (vertex->xyz[0]);
register float __y __asm__("fr13") = (vertex->xyz[1]); register float __y __asm__("fr13") = (vertex->xyz[1]);
register float __z __asm__("fr14") = (vertex->xyz[2]); register float __z __asm__("fr14") = (vertex->xyz[2]);
register float __w __asm__("fr15"); register float __w __asm__("fr15") = (vertex->w);
__asm__ __volatile__( __asm__ __volatile__(
"fldi1 fr15\n" "fldi1 fr15\n"
@ -977,14 +978,15 @@ static void divide(SubmissionTarget* target) {
Vertex* vertex = _glSubmissionTargetStart(target); Vertex* vertex = _glSubmissionTargetStart(target);
ITERATE(target->count) { ITERATE(target->count) {
vertex->xyz[2] = 1.0f / vertex->w; float f = 1.0f / vertex->w;
vertex->xyz[0] *= vertex->xyz[2]; vertex->xyz[0] *= f;
vertex->xyz[1] *= vertex->xyz[2]; vertex->xyz[1] *= f;
vertex->xyz[2] = 1.0 - ((DEPTH_RANGE_MULTIPLIER_L * vertex->xyz[2] * f) + DEPTH_RANGE_MULTIPLIER_H);
++vertex; ++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(); TRACE();
// Compile the header // Compile the header
@ -993,6 +995,16 @@ static void push(PVRHeader* header, Vertex* output, const GLuint count, PolyList
_glUpdatePVRTextureContext(&cxt, textureUnit); _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); pvr_poly_compile(&header->hdr, &cxt);
/* Post-process the vertex list */ /* Post-process the vertex list */
@ -1143,7 +1155,7 @@ static void submitVertices(GLenum mode, GLsizei first, GLuint count, GLenum type
profiler_checkpoint("divide"); profiler_checkpoint("divide");
push(_glSubmissionTargetHeader(target), _glSubmissionTargetStart(target), target->count, target->output, 0); push(_glSubmissionTargetHeader(target), GL_FALSE, target->output, 0);
profiler_checkpoint("push"); profiler_checkpoint("push");
/* /*
@ -1179,7 +1191,6 @@ static void submitVertices(GLenum mode, GLsizei first, GLuint count, GLenum type
assert(vertex); assert(vertex);
PVRHeader* mtHeader = (PVRHeader*) vertex++; PVRHeader* mtHeader = (PVRHeader*) vertex++;
Vertex* mtStart = vertex;
/* Replace the UV coordinates with the ST ones */ /* Replace the UV coordinates with the ST ones */
VertexExtra* ve = aligned_vector_at(target->extras, 0); VertexExtra* ve = aligned_vector_at(target->extras, 0);
@ -1190,29 +1201,8 @@ static void submitVertices(GLenum mode, GLsizei first, GLuint count, GLenum type
++ve; ++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 */ /* Send the buffer again to the transparent list */
push(mtHeader, mtStart, target->count, _glTransparentPolyList(), 1); push(mtHeader, GL_TRUE, _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);
profiler_pop(); profiler_pop();
} }

View File

@ -4,14 +4,12 @@
/* Set the Perspective */ /* Set the Perspective */
void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect, void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect,
GLfloat znear, GLfloat zfar) { GLfloat znear, GLfloat zfar) {
GLfloat xmin, xmax, ymin, ymax; GLdouble fW, fH;
ymax = znear * tanf(angle * F_PI / 360.0f); fH = tan(angle / 360 * F_PI) * znear;
ymin = -ymax; fW = fH * aspect;
xmin = ymin * aspect;
xmax = ymax * 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) { void APIENTRY gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) {

View File

@ -6,6 +6,7 @@
#include <dc/matrix3d.h> #include <dc/matrix3d.h>
#include <dc/vec3f.h> #include <dc/vec3f.h>
#include "private.h"
#include "../include/gl.h" #include "../include/gl.h"
#include "../containers/stack.h" #include "../containers/stack.h"
@ -15,46 +16,70 @@
static GLfloat gl_viewport_scale[3], gl_viewport_offset[3]; static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
/* Depth range */ /* 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 */ /* Viewport size */
static GLint gl_viewport_x1, gl_viewport_y1, gl_viewport_width, gl_viewport_height; static GLint gl_viewport_x1, gl_viewport_y1, gl_viewport_width, gl_viewport_height;
static Stack MATRIX_STACKS[3]; // modelview, projection, texture static Stack MATRIX_STACKS[3]; // modelview, projection, texture
static matrix_t NORMAL_MATRIX __attribute__((aligned(32))); static Matrix4x4 NORMAL_MATRIX __attribute__((aligned(32)));
static matrix_t SCREENVIEW_MATRIX __attribute__((aligned(32))); static Matrix4x4 SCREENVIEW_MATRIX __attribute__((aligned(32)));
static GLenum MATRIX_MODE = GL_MODELVIEW; static GLenum MATRIX_MODE = GL_MODELVIEW;
static GLubyte MATRIX_IDX = 0; static GLubyte MATRIX_IDX = 0;
static const matrix_t IDENTITY = { static const Matrix4x4 IDENTITY = {
{1.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, 1.0f, 0.0f, 0.0f,
{0.0f, 0.0f, 1.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, 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); void APIENTRY glDepthRange(GLclampf n, GLclampf f);
matrix_t* _glGetProjectionMatrix() { static inline void upload_matrix(Matrix4x4* m) {
return (matrix_t*) stack_top(&MATRIX_STACKS[1]); mat_load((matrix_t*) m);
} }
matrix_t* _glGetModelViewMatrix() { static inline void multiply_matrix(Matrix4x4* m) {
return (matrix_t*) stack_top(&MATRIX_STACKS[0]); 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() { void _glInitMatrices() {
init_stack(&MATRIX_STACKS[0], sizeof(matrix_t), 32); init_stack(&MATRIX_STACKS[0], sizeof(Matrix4x4), 32);
init_stack(&MATRIX_STACKS[1], sizeof(matrix_t), 32); init_stack(&MATRIX_STACKS[1], sizeof(Matrix4x4), 32);
init_stack(&MATRIX_STACKS[2], sizeof(matrix_t), 32); init_stack(&MATRIX_STACKS[2], sizeof(Matrix4x4), 32);
stack_push(&MATRIX_STACKS[0], IDENTITY); stack_push(&MATRIX_STACKS[0], IDENTITY);
stack_push(&MATRIX_STACKS[1], IDENTITY); stack_push(&MATRIX_STACKS[1], IDENTITY);
stack_push(&MATRIX_STACKS[2], IDENTITY); stack_push(&MATRIX_STACKS[2], IDENTITY);
memcpy(NORMAL_MATRIX, IDENTITY, sizeof(matrix_t)); memcpy(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4));
memcpy(SCREENVIEW_MATRIX, IDENTITY, sizeof(matrix_t)); memcpy(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4));
glDepthRange(0.0f, 1.0f); glDepthRange(0.0f, 1.0f);
glViewport(0, 0, vid_mode->width, vid_mode->height); glViewport(0, 0, vid_mode->width, vid_mode->height);
@ -98,7 +123,7 @@ static void transpose(GLfloat* m) {
} }
static void recalculateNormalMatrix() { 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); inverse((GLfloat*) NORMAL_MATRIX);
transpose((GLfloat*) NORMAL_MATRIX); transpose((GLfloat*) NORMAL_MATRIX);
} }
@ -124,9 +149,20 @@ void APIENTRY glLoadIdentity() {
} }
void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) { void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); static Matrix4x4 trn __attribute__((aligned(32))) = {
mat_translate(x, y, z); 1.0f, 0.0f, 0.0f, 0.0f,
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); 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) { if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix(); recalculateNormalMatrix();
@ -135,9 +171,20 @@ void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) { void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) {
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); static Matrix4x4 scale __attribute__((aligned(32))) = {
mat_scale(x, y, z); 1.0f, 0.0f, 0.0f, 0.0f,
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); 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) { if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix(); 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) { 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 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); vec3f_normalize(x, y, z);
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); rotate[M0] = (x * x) * invc + c;
mat_rotate(r * x, r * y, r * z); rotate[M1] = xy * invc + zs;
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); 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) { if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix(); recalculateNormalMatrix();
@ -160,7 +236,29 @@ void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
/* Load an arbitrary matrix */ /* Load an arbitrary matrix */
void APIENTRY glLoadMatrixf(const GLfloat *m) { 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) { if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix(); recalculateNormalMatrix();
@ -173,23 +271,23 @@ void APIENTRY glOrtho(GLfloat left, GLfloat right,
GLfloat znear, GLfloat zfar) { GLfloat znear, GLfloat zfar) {
/* Ortho Matrix */ /* Ortho Matrix */
static matrix_t OrthoMatrix __attribute__((aligned(32))) = { static Matrix4x4 OrthoMatrix __attribute__((aligned(32))) = {
{ 1.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, 1.0f, 0.0f, 0.0f,
{ 0.0f, 0.0f, 1.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, 1.0f
}; };
OrthoMatrix[0][0] = 2.0f / (right - left); OrthoMatrix[M0] = 2.0f / (right - left);
OrthoMatrix[1][1] = 2.0f / (top - bottom); OrthoMatrix[M5] = 2.0f / (top - bottom);
OrthoMatrix[2][2] = -2.0f / (zfar - znear); OrthoMatrix[M10] = -2.0f / (zfar - znear);
OrthoMatrix[3][0] = -(right + left) / (right - left);; OrthoMatrix[M12] = -(right + left) / (right - left);
OrthoMatrix[3][1] = -(top + bottom) / (top - bottom); OrthoMatrix[M13] = -(top + bottom) / (top - bottom);
OrthoMatrix[3][2] = -(zfar + znear) / (zfar - znear); OrthoMatrix[M14] = -(zfar + znear) / (zfar - znear);
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
mat_apply(&OrthoMatrix); multiply_matrix(&OrthoMatrix);
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX));
} }
@ -199,84 +297,145 @@ void APIENTRY glFrustum(GLfloat left, GLfloat right,
GLfloat znear, GLfloat zfar) { GLfloat znear, GLfloat zfar) {
/* Frustum Matrix */ /* Frustum Matrix */
static matrix_t FrustumMatrix __attribute__((aligned(32))) = { static Matrix4x4 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 }
};
FrustumMatrix[0][0] = (2.0f * znear) / (right - left); memset(FrustumMatrix, 0, sizeof(float) * 16);
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);
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); const float near2 = 2.0f * znear;
mat_apply(&FrustumMatrix); const float A = (right + left) / (right - left);
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); 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 */ /* Multiply the current matrix by an arbitrary matrix */
void glMultMatrixf(const GLfloat *m) { void glMultMatrixf(const GLfloat *m) {
static matrix_t TEMP __attribute__((aligned(32))) = { static Matrix4x4 TEMP;
{ 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 }
};
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)); TEMP[M4] = m[4];
mat_apply(&TEMP); TEMP[M5] = m[5];
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); 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) { if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix(); recalculateNormalMatrix();
} }
if(MATRIX_MODE == GL_PROJECTION) {
_glStoreNearPlane();
}
} }
/* Load an arbitrary transposed matrix */ /* Load an arbitrary transposed matrix */
void glLoadTransposeMatrixf(const GLfloat *m) { void glLoadTransposeMatrixf(const GLfloat *m) {
stack_replace(MATRIX_STACKS + MATRIX_IDX, m); /* We store matrices transpose anyway, so m will be
transpose(stack_top(MATRIX_STACKS + MATRIX_IDX)); * 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) { if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix(); recalculateNormalMatrix();
} }
if(MATRIX_MODE == GL_PROJECTION) {
_glStoreNearPlane();
}
} }
/* Multiply the current matrix by an arbitrary transposed matrix */ /* Multiply the current matrix by an arbitrary transposed matrix */
void glMultTransposeMatrixf(const GLfloat *m) { void glMultTransposeMatrixf(const GLfloat *m) {
static matrix_t ml; static Matrix4x4 TEMP __attribute__((aligned(32)));
ml[0][0] = m[0]; TEMP[M0] = m[0];
ml[0][1] = m[4]; TEMP[M1] = m[4];
ml[0][2] = m[8]; TEMP[M2] = m[8];
ml[0][3] = m[12]; TEMP[M3] = 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];
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); TEMP[M4] = m[1];
mat_apply(&ml); TEMP[M5] = m[5];
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); 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) { if(MATRIX_MODE == GL_MODELVIEW) {
recalculateNormalMatrix(); recalculateNormalMatrix();
} }
if(MATRIX_MODE == GL_PROJECTION) {
_glStoreNearPlane();
}
} }
/* Set the GL viewport */ /* 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 hw = ((GLfloat) width) / 2.0f;
GLfloat hh = ((GLfloat) height) / 2.0f; GLfloat hh = ((GLfloat) height) / 2.0f;
SCREENVIEW_MATRIX[0][0] = hw; SCREENVIEW_MATRIX[M0] = hw;
SCREENVIEW_MATRIX[1][1] = -hh; SCREENVIEW_MATRIX[M5] = -hh;
SCREENVIEW_MATRIX[2][2] = 1; //(gl_depthrange_far - gl_depthrange_near) / 2.0f; SCREENVIEW_MATRIX[M10] = 1;
SCREENVIEW_MATRIX[3][0] = (rw + lw) / 2.0f; SCREENVIEW_MATRIX[M12] = (rw + lw) / 2.0f;
SCREENVIEW_MATRIX[3][1] = (tw + bw) / 2.0f; SCREENVIEW_MATRIX[M13] = (tw + bw) / 2.0f;
// SCREENVIEW_MATRIX[3][2] = (gl_depthrange_far + gl_depthrange_near) / 2.0f; }
GLfloat _glGetNearPlane() {
return NEAR_PLANE_DISTANCE;
} }
/* Set the depth range */ /* Set the depth range */
void APIENTRY glDepthRange(GLclampf n, GLclampf f) { 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; if(n < 0.0f) n = 0.0f;
else if(n > 1.0f) n = 1.0f; else if(n > 1.0f) n = 1.0f;
if(f < 0.0f) f = 0.0f; if(f < 0.0f) f = 0.0f;
else if(f > 1.0f) f = 1.0f; else if(f > 1.0f) f = 1.0f;
gl_depthrange_near = n; DEPTH_RANGE_MULTIPLIER_L = (f - n) / 2.0f;
gl_depthrange_far = f; DEPTH_RANGE_MULTIPLIER_H = (n + f) / 2.0f;
} }
/* Vector Cross Product - Used by glhLookAtf2 */ /* Vector Cross Product - Used by glhLookAtf2 */
@ -333,11 +489,11 @@ void glhLookAtf2(const GLfloat* eyePosition3D,
const GLfloat* upVector3D) { const GLfloat* upVector3D) {
/* Look-At Matrix */ /* Look-At Matrix */
static matrix_t MatrixLookAt __attribute__((aligned(32))) = { static Matrix4x4 MatrixLookAt __attribute__((aligned(32))) = {
{ 1.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, 1.0f, 0.0f, 0.0f,
{ 0.0f, 0.0f, 1.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, 1.0f
}; };
GLfloat forward[3]; GLfloat forward[3];
@ -355,32 +511,40 @@ void glhLookAtf2(const GLfloat* eyePosition3D,
//Recompute up as: up = side x forward //Recompute up as: up = side x forward
vec3f_cross(side, forward, up); vec3f_cross(side, forward, up);
MatrixLookAt[0][0] = side[0]; MatrixLookAt[M0] = side[0];
MatrixLookAt[1][0] = side[1]; MatrixLookAt[M4] = side[1];
MatrixLookAt[2][0] = side[2]; MatrixLookAt[M8] = side[2];
MatrixLookAt[3][0] = 0; MatrixLookAt[M12] = 0;
MatrixLookAt[0][1] = up[0]; MatrixLookAt[M1] = up[0];
MatrixLookAt[1][1] = up[1]; MatrixLookAt[M5] = up[1];
MatrixLookAt[2][1] = up[2]; MatrixLookAt[M9] = up[2];
MatrixLookAt[3][1] = 0; MatrixLookAt[M13] = 0;
MatrixLookAt[0][2] = -forward[0]; MatrixLookAt[M2] = -forward[0];
MatrixLookAt[1][2] = -forward[1]; MatrixLookAt[M6] = -forward[1];
MatrixLookAt[2][2] = -forward[2]; MatrixLookAt[M10] = -forward[2];
MatrixLookAt[3][2] = 0; MatrixLookAt[M14] = 0;
MatrixLookAt[0][3] = MatrixLookAt[M3] = MatrixLookAt[11] = MatrixLookAt[15] = 0;
MatrixLookAt[1][3] = MatrixLookAt[M15] = 1;
MatrixLookAt[2][3] = 0;
MatrixLookAt[3][3] = 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 // Does not modify internal Modelview matrix
mat_load(&MatrixLookAt); upload_matrix(&MatrixLookAt);
mat_translate(-eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]); multiply_matrix(&trn);
multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); download_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
mat_store(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
} }
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, 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() { void _glApplyRenderMatrix() {
mat_load(&SCREENVIEW_MATRIX); upload_matrix(&SCREENVIEW_MATRIX);
mat_apply(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF))); multiply_matrix(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
} }
void _glMatrixLoadTexture() { void _glMatrixLoadTexture() {
mat_load(stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF))); upload_matrix(stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF)));
} }
void _glMatrixLoadModelView() { void _glMatrixLoadModelView() {
mat_load(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); upload_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
} }
void _glMatrixLoadNormal() { void _glMatrixLoadNormal() {
mat_load(&NORMAL_MATRIX); upload_matrix(&NORMAL_MATRIX);
} }

View File

@ -23,6 +23,49 @@
#define MAX_TEXTURE_SIZE 1024 #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 { typedef struct {
pvr_poly_hdr_t hdr; pvr_poly_hdr_t hdr;
} PVRHeader; } PVRHeader;
@ -195,8 +238,11 @@ void _glMatrixLoadModelView();
void _glMatrixLoadTexture(); void _glMatrixLoadTexture();
void _glApplyRenderMatrix(); void _glApplyRenderMatrix();
matrix_t* _glGetProjectionMatrix(); extern GLfloat DEPTH_RANGE_MULTIPLIER_L;
matrix_t* _glGetModelViewMatrix(); extern GLfloat DEPTH_RANGE_MULTIPLIER_H;
Matrix4x4* _glGetProjectionMatrix();
Matrix4x4* _glGetModelViewMatrix();
void _glWipeTextureOnFramebuffers(GLuint texture); void _glWipeTextureOnFramebuffers(GLuint texture);
GLubyte _glCheckImmediateModeInactive(const char* func); GLubyte _glCheckImmediateModeInactive(const char* func);
@ -207,6 +253,10 @@ GLubyte _glInitTextures();
void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit); void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit);
void _glAllocateSpaceForMipmaps(TextureObject* active); void _glAllocateSpaceForMipmaps(TextureObject* active);
extern GLfloat NEAR_PLANE_DISTANCE;
GLfloat _glGetNearPlane();
typedef struct { typedef struct {
const void* ptr; const void* ptr;
GLenum type; GLenum type;

View File

@ -421,7 +421,6 @@ GLAPI void APIENTRY glReadBuffer(GLenum mode) {
GLAPI void APIENTRY glDepthMask(GLboolean flag) { GLAPI void APIENTRY glDepthMask(GLboolean flag) {
GL_CONTEXT.depth.write = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE; 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) { GLAPI void APIENTRY glDepthFunc(GLenum func) {