From 153c8eb4997d21d3b2965cf38d4348f05c29860f Mon Sep 17 00:00:00 2001 From: iCatButler Date: Wed, 27 Apr 2016 12:18:13 +0100 Subject: Perspective correct texturing - replace calls to glOrtho with new matrix (z value becomes w) - store w value for each vertex - if any vertex does not have a w value set whole polygon to 1.0 - Reset vertex between draw calls to prevent stale w values persisting - validate PGXP values using stored copy of original (allow greater variance) - properly convert addresses before passing to plugin - rework memory to use a single pool with offsets - Implement floating point RTPS/RTPT transform, currently disabled. --- plugins/peopsxgl/pgxp_gpu.c | 74 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 9 deletions(-) (limited to 'plugins/peopsxgl/pgxp_gpu.c') diff --git a/plugins/peopsxgl/pgxp_gpu.c b/plugins/peopsxgl/pgxp_gpu.c index 1ce67bf8..eedf7b8d 100644 --- a/plugins/peopsxgl/pgxp_gpu.c +++ b/plugins/peopsxgl/pgxp_gpu.c @@ -38,6 +38,7 @@ typedef struct float z; unsigned int valid; unsigned int count; + unsigned int value; } PGXP_vertex; const unsigned int primStrideTable[] = { 1, 2, 1, 2, 2, 3, 2, 3, 0 }; @@ -60,15 +61,55 @@ void PGXP_SetAddress(unsigned int addr) currentAddr = addr; } +void PGXP_SetMatrix(float left, float right, float bottom, float top, float zNear, float zFar) +{ + GLfloat m[16]; + for (unsigned int i = 0; i < 16; ++i) + m[i] = 0.f; + + //if ((right-left) != 0) + //{ + // m[0] = 2 / (right - left); + // m[12] = -((right + left) / (right - left)); + //} + //if ((top-bottom) != 0) + //{ + // m[5] = 2 / (top - bottom); + // m[13] = -((top + bottom) / (top - bottom)); + //} + //m[10] = -2 / (zFar - zNear); + //m[14] = -((zFar + zNear) / (zFar - zNear)); + //m[15] = 1; + + if ((right-left) != 0) + { + m[0] = 2 / (right - left); + m[8] = -((right + left) / (right - left)); + } + if ((top-bottom) != 0) + { + m[5] = 2 / (top - bottom); + m[9] = -((top + bottom) / (top - bottom)); + } + m[10] = -2 / (zFar - zNear); + m[14] = -((zFar + zNear) / (zFar - zNear)); + m[11] = 1; + + glLoadMatrixf(m); + //glOrtho(left, right, bottom, top, zNear, zFar); +} + // Get parallel vertex values -int PGXP_GetVertices(unsigned int* addr, void* pOutput) +int PGXP_GetVertices(unsigned int* addr, void* pOutput, int xOffs, int yOffs) { - unsigned int primCmd = ((*addr >> 24) & 0xff); // primitive command - unsigned int primIdx = min((primCmd - 0x20) >> 2, 8); // index to primitive lookup - OGLVertex* pVertex = (OGLVertex*)pOutput; // pointer to output vertices - unsigned int stride = primStrideTable[primIdx]; // stride between vertices - unsigned int count = primCountTable[primIdx]; // number of vertices - PGXP_vertex* primStart = NULL; // pointer to first vertex + unsigned int primCmd = ((*addr >> 24) & 0xff); // primitive command + unsigned int primIdx = min((primCmd - 0x20) >> 2, 8); // index to primitive lookup + OGLVertex* pVertex = (OGLVertex*)pOutput; // pointer to output vertices + unsigned int stride = primStrideTable[primIdx]; // stride between vertices + unsigned int count = primCountTable[primIdx]; // number of vertices + PGXP_vertex* primStart = NULL; // pointer to first vertex + char invalidVert = 0; // Number of vertices without valid PGXP values + float w = 0; // W coordinate of transformed vertex if (PGXP_Mem == NULL) return 0; @@ -76,12 +117,27 @@ int PGXP_GetVertices(unsigned int* addr, void* pOutput) // Offset to start of primitive primStart = &PGXP_Mem[currentAddr + 1]; + // Find any invalid vertices for (unsigned i = 0; i < count; ++i) { + if(!primStart[stride * i].valid) + invalidVert++; + } + + for (unsigned i = 0; i < count; ++i) + { + w = primStart[stride * i].z; + // If there are any invalid vertices set all w values to 1 + // iCB: Could use plane equation to find w for single invalid vertex in a quad + if (invalidVert > 0) + w = 1; + if (primStart[stride * i].valid) { - pVertex[i].x = primStart[stride * i].x; - pVertex[i].y = primStart[stride * i].y; + // Premultiply x,y coorindates by w because they've already been divided by w + pVertex[i].x = (primStart[stride * i].x + xOffs) * w; + pVertex[i].y = (primStart[stride * i].y + yOffs) * w; + pVertex[i].z = w; } } -- cgit v1.2.3