diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 569b674a2..b4994fa11 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -1078,6 +1078,9 @@ static void Render() xglDepthMask(GL_TRUE); glViewport(gfx3d.viewport.x,gfx3d.viewport.y,gfx3d.viewport.width,gfx3d.viewport.height); + + //it might be handy to print the size of the projection list, in case a game is doing something weird with it + //printf("%d\n",gfx3d.projlist->count); //we're not using the alpha clear color right now glClearColor(gfx3d.clearColor[0],gfx3d.clearColor[1],gfx3d.clearColor[2], clearAlpha); @@ -1090,6 +1093,7 @@ static void Render() { u32 lastTextureFormat = 0, lastTexturePalette = 0, lastPolyAttr = 0; + int lastProjIndex = -1; for(int i=0;icount;i++) { POLY *poly = &gfx3d.polylist->list[gfx3d.indexlist[i]]; @@ -1107,8 +1111,11 @@ static void Render() } //since we havent got the whole pipeline working yet, lets use opengl for the projection - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(poly->projMatrix); + if(lastProjIndex != poly->projIndex) { + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(gfx3d.projlist->projMatrix[poly->projIndex]); + lastProjIndex = poly->projIndex; + } glBegin(type==3?GL_TRIANGLES:GL_QUADS); for(int j=0;jcount = 0; vertlist->count = 0; + projlist->count = 0; } static BOOL flushPending = FALSE; @@ -597,10 +601,28 @@ static void SetVertex() } if(completed) { - MatrixCopy(polylist->list[polylist->count].projMatrix,mtxCurrent[0]); - polylist->list[polylist->count].polyAttr = polyAttr; - polylist->list[polylist->count].texParam = textureFormat; - polylist->list[polylist->count].texPalette = texturePalette; + POLY &poly = polylist->list[polylist->count]; + //todo - dont overrun proj list + + + //see if the last entry in the proj list matches the current matrix, if there is one. + if(projlist->count != 0 && + //but as a speed hack, we consider the matrices different if the first element differs. + //i think this should be good enough. + //!MatrixCompare(mtxCurrent[0],projlist->projMatrix[projlist->count-1]) + mtxCurrent[0][0] == projlist->projMatrix[projlist->count-1][0] + ) { + //it matches. use it + poly.projIndex = projlist->count-1; + } else { + MatrixCopy(projlist->projMatrix[projlist->count],mtxCurrent[0]); + poly.projIndex = projlist->count; + projlist->count++; + } + + poly.polyAttr = polyAttr; + poly.texParam = textureFormat; + poly.texPalette = texturePalette; polylist->count++; } } @@ -980,6 +1002,7 @@ void gfx3d_glFlush(unsigned long v) //the renderer wil lget the lists we just built gfx3d.polylist = polylist; gfx3d.vertlist = vertlist; + gfx3d.projlist = projlist; //we need to sort the poly list with alpha polys last //first, look for alpha polys @@ -1681,12 +1704,16 @@ bool gfx3d_loadstate(std::istream* is) //jiggle the lists. and also wipe them. this is clearly not the best thing to be doing. polylist = &polylists[listTwiddle]; vertlist = &vertlists[listTwiddle]; + projlist = &projlists[listTwiddle]; polylist->count = 0; vertlist->count = 0; + projlist->count = 0; gfx3d.polylist = &polylists[listTwiddle^1]; gfx3d.vertlist = &vertlists[listTwiddle^1]; + gfx3d.projlist = &projlists[listTwiddle^1]; gfx3d.polylist->count=0; gfx3d.vertlist->count=0; + gfx3d.projlist->count = 0; return true; } diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index 49209fbfb..bca62dd9e 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -29,9 +29,10 @@ void gfx3d_reset(); struct POLY { int type; //tri or quad - int vertIndexes[4]; //up to four verts can be referenced by this poly + u16 vertIndexes[4]; //up to four verts can be referenced by this poly u32 polyAttr, texParam, texPalette; //the hardware rendering params - float projMatrix[16]; + int projIndex; //the index into the projlist that this poly uses + u32 pad; bool isTranslucent() { @@ -51,22 +52,28 @@ struct POLY { #define POLYLIST_SIZE 100000 //#define POLYLIST_SIZE 2048 struct POLYLIST { - int count; POLY list[POLYLIST_SIZE]; + int count; +}; + +#define PROJLIST_SIZE 1000 +struct PROJLIST { + float projMatrix[PROJLIST_SIZE][16]; + int count; }; struct VERT { float coord[4]; float texcoord[2]; - u8 color[4]; u32 depth; + u8 color[4]; }; #define VERTLIST_SIZE 400000 //#define VERTLIST_SIZE 10000 struct VERTLIST { - int count; VERT list[VERTLIST_SIZE]; + int count; }; //used to communicate state to the renderer @@ -96,6 +103,7 @@ struct GFX3D POLYLIST* polylist; VERTLIST* vertlist; + PROJLIST* projlist; int indexlist[POLYLIST_SIZE]; BOOL wbuffer, sortmode; diff --git a/desmume/src/matrix.cpp b/desmume/src/matrix.cpp index ceacdc3c3..416d6542f 100644 --- a/desmume/src/matrix.cpp +++ b/desmume/src/matrix.cpp @@ -149,6 +149,11 @@ void MATRIXFASTCALL MatrixCopy (float* matrixDST, const float* matrixSRC) memcpy ((void*)matrixDST, matrixSRC, sizeof(float)*16); } +int MATRIXFASTCALL MatrixCompare (const float* matrixDST, const float* matrixSRC) +{ + return memcmp((void*)matrixDST, matrixSRC, sizeof(float)*16); +} + void MatrixStackInit (MatrixStack *stack) { stack->matrix = NULL; diff --git a/desmume/src/matrix.h b/desmume/src/matrix.h index 68c55cb37..38d37de16 100644 --- a/desmume/src/matrix.h +++ b/desmume/src/matrix.h @@ -48,6 +48,7 @@ void MATRIXFASTCALL MatrixScale (float * matrix, const float * ptr); float MATRIXFASTCALL MatrixGetMultipliedIndex (int index, float *matrix, float *rightMatrix); void MATRIXFASTCALL MatrixSet (float *matrix, int x, int y, float value); void MATRIXFASTCALL MatrixCopy (float * matrixDST, const float * matrixSRC); +int MATRIXFASTCALL MatrixCompare (const float * matrixDST, const float * matrixSRC); void MATRIXFASTCALL MatrixIdentity (float *matrix); void MatrixTranspose (float *matrix);