From 27f758d3534f58fb3c6587a63d81e608b42cdb86 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 12 Jun 2019 03:55:40 +0200 Subject: hack so that the GL renderer can render lines --- src/GPU3D.cpp | 34 ++++++++++++- src/GPU3D.h | 2 +- src/GPU3D_OpenGL.cpp | 140 ++++++++++++++++++++++++++++++++++++--------------- src/Savestate.h | 2 +- 4 files changed, 134 insertions(+), 44 deletions(-) diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 98aa6eb..c94d363 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -539,6 +539,11 @@ void DoSavestate(Savestate* file) file->Var32((u32*)&poly->IsShadowMask); file->Var32((u32*)&poly->IsShadow); + if (file->IsAtleastVersion(4, 1)) + file->Var32((u32*)&poly->Type); + else + poly->Type = 0; + file->Var32(&poly->VTop); file->Var32(&poly->VBottom); file->Var32((u32*)&poly->YTop); @@ -1017,6 +1022,14 @@ int ClipPolygon(Vertex* vertices, int nverts, int clipstart) return nverts; } +bool ClipCoordsEqual(Vertex* a, Vertex* b) +{ + return a->Position[0] == b->Position[0] && + a->Position[1] == b->Position[1] && + a->Position[2] == b->Position[2] && + a->Position[3] == b->Position[3]; +} + void SubmitPolygon() { Vertex clippedvertices[10]; @@ -1038,13 +1051,15 @@ void SubmitPolygon() // TODO: work out how it works on the real thing // the normalization part is a wild guess - Vertex *v0, *v1, *v2; + Vertex *v0, *v1, *v2, *v3; s64 normalX, normalY, normalZ; s64 dot; v0 = &TempVertexBuffer[0]; v1 = &TempVertexBuffer[1]; v2 = &TempVertexBuffer[2]; + v3 = &TempVertexBuffer[3]; + normalX = ((s64)(v0->Position[1]-v1->Position[1]) * (v2->Position[3]-v1->Position[3])) - ((s64)(v0->Position[3]-v1->Position[3]) * (v2->Position[1]-v1->Position[1])); normalY = ((s64)(v0->Position[3]-v1->Position[3]) * (v2->Position[0]-v1->Position[0])) @@ -1170,6 +1185,7 @@ void SubmitPolygon() poly->TexPalette = TexPalette; poly->Degenerate = false; + poly->Type = 0; poly->FacingView = facingview; @@ -1182,6 +1198,22 @@ void SubmitPolygon() if (!poly->Translucent) NumOpaquePolygons++; + if (ClipCoordsEqual(v0, v1) || + ClipCoordsEqual(v0, v2) || + ClipCoordsEqual(v1, v2)) + { + poly->Type = 1; + } + else if (nverts == 4) + { + if (ClipCoordsEqual(v0, v3) || + ClipCoordsEqual(v1, v3) || + ClipCoordsEqual(v2, v3)) + { + poly->Type = 1; + } + } + if (LastStripPolygon && clipstart > 0) { if (nverts == lastpolyverts) diff --git a/src/GPU3D.h b/src/GPU3D.h index e115261..fd52488 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -66,7 +66,7 @@ typedef struct bool IsShadowMask; bool IsShadow; - int Type; // 0=polygon 1=horizontal line 2=vertical line 3=diagonal line 4=point + int Type; // 0=regular 1=line u32 VTop, VBottom; // vertex indices s32 YTop, YBottom; // Y coords diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 94ef079..2f25912 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -73,6 +73,8 @@ typedef struct u32 NumIndices; u16* Indices; + GLuint PrimType; + u32 NumEdgeIndices; u16* EdgeIndices; @@ -104,7 +106,6 @@ u32 NumVertices; GLuint VertexArrayID; u16 IndexBuffer[2048 * 40]; -u32 NumTriangles; GLuint TexMemID; GLuint TexPalMemID; @@ -532,7 +533,6 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) u16* iptr = &IndexBuffer[0]; u16* eiptr = &IndexBuffer[2048*30]; - u32 numtriangles = 0; for (int i = 0; i < npolys; i++) { @@ -553,54 +553,111 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) if (poly->WBuffer) vtxattr |= (1<<9); // assemble vertices - for (int j = 0; j < poly->NumVertices; j++) + if (poly->Type == 1) // line { - Vertex* vtx = poly->Vertices[j]; + rp->PrimType = GL_LINES; - u32 z = poly->FinalZ[j]; - u32 w = poly->FinalW[j]; + u32 lastx, lasty; + int nout = 0; + for (int j = 0; j < poly->NumVertices; j++) + { + Vertex* vtx = poly->Vertices[j]; - // Z should always fit within 16 bits, so it's okay to do this - u32 zshift = 0; - while (z > 0xFFFF) { z >>= 1; zshift++; } + u32 z = poly->FinalZ[j]; + u32 w = poly->FinalW[j]; - u32 x, y; - if (ScaleFactor > 1) - { - x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; - y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; - } - else - { - x = vtx->FinalPosition[0]; - y = vtx->FinalPosition[1]; - } + // Z should always fit within 16 bits, so it's okay to do this + u32 zshift = 0; + while (z > 0xFFFF) { z >>= 1; zshift++; } - *vptr++ = x | (y << 16); - *vptr++ = z | (w << 16); + u32 x, y; + if (ScaleFactor > 1) + { + x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; + y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; + } + else + { + x = vtx->FinalPosition[0]; + y = vtx->FinalPosition[1]; + } - *vptr++ = (vtx->FinalColor[0] >> 1) | - ((vtx->FinalColor[1] >> 1) << 8) | - ((vtx->FinalColor[2] >> 1) << 16) | - (alpha << 24); + if (lastx == x && lasty == y) continue; - *vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 16); + *vptr++ = x | (y << 16); + *vptr++ = z | (w << 16); - *vptr++ = vtxattr | (zshift << 16); - *vptr++ = poly->TexParam; - *vptr++ = poly->TexPalette; + *vptr++ = (vtx->FinalColor[0] >> 1) | + ((vtx->FinalColor[1] >> 1) << 8) | + ((vtx->FinalColor[2] >> 1) << 16) | + (alpha << 24); + + *vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 16); + + *vptr++ = vtxattr | (zshift << 16); + *vptr++ = poly->TexParam; + *vptr++ = poly->TexPalette; - if (j >= 2) - { - // build a triangle - *iptr++ = vidx_first; - *iptr++ = vidx - 1; *iptr++ = vidx; - numtriangles++; - rp->NumIndices += 3; + rp->NumIndices++; + + vidx++; + nout++; + if (nout >= 2) break; } + } + else + { + rp->PrimType = GL_TRIANGLES; - vidx++; + for (int j = 0; j < poly->NumVertices; j++) + { + Vertex* vtx = poly->Vertices[j]; + + u32 z = poly->FinalZ[j]; + u32 w = poly->FinalW[j]; + + // Z should always fit within 16 bits, so it's okay to do this + u32 zshift = 0; + while (z > 0xFFFF) { z >>= 1; zshift++; } + + u32 x, y; + if (ScaleFactor > 1) + { + x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; + y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; + } + else + { + x = vtx->FinalPosition[0]; + y = vtx->FinalPosition[1]; + } + + *vptr++ = x | (y << 16); + *vptr++ = z | (w << 16); + + *vptr++ = (vtx->FinalColor[0] >> 1) | + ((vtx->FinalColor[1] >> 1) << 8) | + ((vtx->FinalColor[2] >> 1) << 16) | + (alpha << 24); + + *vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 16); + + *vptr++ = vtxattr | (zshift << 16); + *vptr++ = poly->TexParam; + *vptr++ = poly->TexPalette; + + if (j >= 2) + { + // build a triangle + *iptr++ = vidx_first; + *iptr++ = vidx - 1; + *iptr++ = vidx; + rp->NumIndices += 3; + } + + vidx++; + } } rp->EdgeIndices = eiptr; @@ -619,7 +676,6 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) rp->NumEdgeIndices += 2; } - NumTriangles = numtriangles; NumVertices = vidx; } @@ -627,12 +683,13 @@ void RenderSinglePolygon(int i) { RendererPolygon* rp = &PolygonList[i]; - glDrawElements(GL_TRIANGLES, rp->NumIndices, GL_UNSIGNED_SHORT, rp->Indices); + glDrawElements(rp->PrimType, rp->NumIndices, GL_UNSIGNED_SHORT, rp->Indices); } int RenderPolygonBatch(int i) { RendererPolygon* rp = &PolygonList[i]; + GLuint primtype = rp->PrimType; u32 key = rp->RenderKey; int numpolys = 0; u32 numindices = 0; @@ -640,13 +697,14 @@ int RenderPolygonBatch(int i) for (int iend = i; iend < NumFinalPolys; iend++) { RendererPolygon* cur_rp = &PolygonList[iend]; + if (cur_rp->PrimType != primtype) break; if (cur_rp->RenderKey != key) break; numpolys++; numindices += cur_rp->NumIndices; } - glDrawElements(GL_TRIANGLES, numindices, GL_UNSIGNED_SHORT, rp->Indices); + glDrawElements(primtype, numindices, GL_UNSIGNED_SHORT, rp->Indices); return numpolys; } diff --git a/src/Savestate.h b/src/Savestate.h index bb12089..ef86f3c 100644 --- a/src/Savestate.h +++ b/src/Savestate.h @@ -23,7 +23,7 @@ #include "types.h" #define SAVESTATE_MAJOR 4 -#define SAVESTATE_MINOR 0 +#define SAVESTATE_MINOR 1 class Savestate { -- cgit v1.2.3