aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2019-06-12 03:55:40 +0200
committerArisotura <thetotalworm@gmail.com>2019-06-12 03:55:40 +0200
commit27f758d3534f58fb3c6587a63d81e608b42cdb86 (patch)
tree10132888f0c7a770d444e9e6ab7af3e06e7abcb3
parent4553da720c90a399d43a4a003ac9250ec4eded23 (diff)
hack so that the GL renderer can render lines
-rw-r--r--src/GPU3D.cpp34
-rw-r--r--src/GPU3D.h2
-rw-r--r--src/GPU3D_OpenGL.cpp140
-rw-r--r--src/Savestate.h2
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
{