mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-22 13:50:11 -06:00
hack so that the GL renderer can render lines
This commit is contained in:
@ -539,6 +539,11 @@ void DoSavestate(Savestate* file)
|
|||||||
file->Var32((u32*)&poly->IsShadowMask);
|
file->Var32((u32*)&poly->IsShadowMask);
|
||||||
file->Var32((u32*)&poly->IsShadow);
|
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->VTop);
|
||||||
file->Var32(&poly->VBottom);
|
file->Var32(&poly->VBottom);
|
||||||
file->Var32((u32*)&poly->YTop);
|
file->Var32((u32*)&poly->YTop);
|
||||||
@ -1017,6 +1022,14 @@ int ClipPolygon(Vertex* vertices, int nverts, int clipstart)
|
|||||||
return nverts;
|
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()
|
void SubmitPolygon()
|
||||||
{
|
{
|
||||||
Vertex clippedvertices[10];
|
Vertex clippedvertices[10];
|
||||||
@ -1038,13 +1051,15 @@ void SubmitPolygon()
|
|||||||
// TODO: work out how it works on the real thing
|
// TODO: work out how it works on the real thing
|
||||||
// the normalization part is a wild guess
|
// the normalization part is a wild guess
|
||||||
|
|
||||||
Vertex *v0, *v1, *v2;
|
Vertex *v0, *v1, *v2, *v3;
|
||||||
s64 normalX, normalY, normalZ;
|
s64 normalX, normalY, normalZ;
|
||||||
s64 dot;
|
s64 dot;
|
||||||
|
|
||||||
v0 = &TempVertexBuffer[0];
|
v0 = &TempVertexBuffer[0];
|
||||||
v1 = &TempVertexBuffer[1];
|
v1 = &TempVertexBuffer[1];
|
||||||
v2 = &TempVertexBuffer[2];
|
v2 = &TempVertexBuffer[2];
|
||||||
|
v3 = &TempVertexBuffer[3];
|
||||||
|
|
||||||
normalX = ((s64)(v0->Position[1]-v1->Position[1]) * (v2->Position[3]-v1->Position[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]));
|
- ((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]))
|
normalY = ((s64)(v0->Position[3]-v1->Position[3]) * (v2->Position[0]-v1->Position[0]))
|
||||||
@ -1170,6 +1185,7 @@ void SubmitPolygon()
|
|||||||
poly->TexPalette = TexPalette;
|
poly->TexPalette = TexPalette;
|
||||||
|
|
||||||
poly->Degenerate = false;
|
poly->Degenerate = false;
|
||||||
|
poly->Type = 0;
|
||||||
|
|
||||||
poly->FacingView = facingview;
|
poly->FacingView = facingview;
|
||||||
|
|
||||||
@ -1182,6 +1198,22 @@ void SubmitPolygon()
|
|||||||
|
|
||||||
if (!poly->Translucent) NumOpaquePolygons++;
|
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 (LastStripPolygon && clipstart > 0)
|
||||||
{
|
{
|
||||||
if (nverts == lastpolyverts)
|
if (nverts == lastpolyverts)
|
||||||
|
@ -66,7 +66,7 @@ typedef struct
|
|||||||
bool IsShadowMask;
|
bool IsShadowMask;
|
||||||
bool IsShadow;
|
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
|
u32 VTop, VBottom; // vertex indices
|
||||||
s32 YTop, YBottom; // Y coords
|
s32 YTop, YBottom; // Y coords
|
||||||
|
@ -73,6 +73,8 @@ typedef struct
|
|||||||
|
|
||||||
u32 NumIndices;
|
u32 NumIndices;
|
||||||
u16* Indices;
|
u16* Indices;
|
||||||
|
GLuint PrimType;
|
||||||
|
|
||||||
u32 NumEdgeIndices;
|
u32 NumEdgeIndices;
|
||||||
u16* EdgeIndices;
|
u16* EdgeIndices;
|
||||||
|
|
||||||
@ -104,7 +106,6 @@ u32 NumVertices;
|
|||||||
|
|
||||||
GLuint VertexArrayID;
|
GLuint VertexArrayID;
|
||||||
u16 IndexBuffer[2048 * 40];
|
u16 IndexBuffer[2048 * 40];
|
||||||
u32 NumTriangles;
|
|
||||||
|
|
||||||
GLuint TexMemID;
|
GLuint TexMemID;
|
||||||
GLuint TexPalMemID;
|
GLuint TexPalMemID;
|
||||||
@ -532,7 +533,6 @@ void BuildPolygons(RendererPolygon* polygons, int npolys)
|
|||||||
|
|
||||||
u16* iptr = &IndexBuffer[0];
|
u16* iptr = &IndexBuffer[0];
|
||||||
u16* eiptr = &IndexBuffer[2048*30];
|
u16* eiptr = &IndexBuffer[2048*30];
|
||||||
u32 numtriangles = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < npolys; i++)
|
for (int i = 0; i < npolys; i++)
|
||||||
{
|
{
|
||||||
@ -553,54 +553,111 @@ void BuildPolygons(RendererPolygon* polygons, int npolys)
|
|||||||
if (poly->WBuffer) vtxattr |= (1<<9);
|
if (poly->WBuffer) vtxattr |= (1<<9);
|
||||||
|
|
||||||
// assemble vertices
|
// 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 lastx, lasty;
|
||||||
u32 w = poly->FinalW[j];
|
int nout = 0;
|
||||||
|
for (int j = 0; j < poly->NumVertices; 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;
|
Vertex* vtx = poly->Vertices[j];
|
||||||
y = (vtx->HiresPosition[1] * ScaleFactor) >> 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x = vtx->FinalPosition[0];
|
|
||||||
y = vtx->FinalPosition[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
*vptr++ = x | (y << 16);
|
u32 z = poly->FinalZ[j];
|
||||||
*vptr++ = z | (w << 16);
|
u32 w = poly->FinalW[j];
|
||||||
|
|
||||||
*vptr++ = (vtx->FinalColor[0] >> 1) |
|
// Z should always fit within 16 bits, so it's okay to do this
|
||||||
((vtx->FinalColor[1] >> 1) << 8) |
|
u32 zshift = 0;
|
||||||
((vtx->FinalColor[2] >> 1) << 16) |
|
while (z > 0xFFFF) { z >>= 1; zshift++; }
|
||||||
(alpha << 24);
|
|
||||||
|
|
||||||
*vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 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++ = vtxattr | (zshift << 16);
|
if (lastx == x && lasty == y) continue;
|
||||||
*vptr++ = poly->TexParam;
|
|
||||||
*vptr++ = poly->TexPalette;
|
*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;
|
*iptr++ = vidx;
|
||||||
numtriangles++;
|
rp->NumIndices++;
|
||||||
rp->NumIndices += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
vidx++;
|
vidx++;
|
||||||
|
nout++;
|
||||||
|
if (nout >= 2) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rp->PrimType = GL_TRIANGLES;
|
||||||
|
|
||||||
|
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;
|
rp->EdgeIndices = eiptr;
|
||||||
@ -619,7 +676,6 @@ void BuildPolygons(RendererPolygon* polygons, int npolys)
|
|||||||
rp->NumEdgeIndices += 2;
|
rp->NumEdgeIndices += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
NumTriangles = numtriangles;
|
|
||||||
NumVertices = vidx;
|
NumVertices = vidx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,12 +683,13 @@ void RenderSinglePolygon(int i)
|
|||||||
{
|
{
|
||||||
RendererPolygon* rp = &PolygonList[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)
|
int RenderPolygonBatch(int i)
|
||||||
{
|
{
|
||||||
RendererPolygon* rp = &PolygonList[i];
|
RendererPolygon* rp = &PolygonList[i];
|
||||||
|
GLuint primtype = rp->PrimType;
|
||||||
u32 key = rp->RenderKey;
|
u32 key = rp->RenderKey;
|
||||||
int numpolys = 0;
|
int numpolys = 0;
|
||||||
u32 numindices = 0;
|
u32 numindices = 0;
|
||||||
@ -640,13 +697,14 @@ int RenderPolygonBatch(int i)
|
|||||||
for (int iend = i; iend < NumFinalPolys; iend++)
|
for (int iend = i; iend < NumFinalPolys; iend++)
|
||||||
{
|
{
|
||||||
RendererPolygon* cur_rp = &PolygonList[iend];
|
RendererPolygon* cur_rp = &PolygonList[iend];
|
||||||
|
if (cur_rp->PrimType != primtype) break;
|
||||||
if (cur_rp->RenderKey != key) break;
|
if (cur_rp->RenderKey != key) break;
|
||||||
|
|
||||||
numpolys++;
|
numpolys++;
|
||||||
numindices += cur_rp->NumIndices;
|
numindices += cur_rp->NumIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, numindices, GL_UNSIGNED_SHORT, rp->Indices);
|
glDrawElements(primtype, numindices, GL_UNSIGNED_SHORT, rp->Indices);
|
||||||
return numpolys;
|
return numpolys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define SAVESTATE_MAJOR 4
|
#define SAVESTATE_MAJOR 4
|
||||||
#define SAVESTATE_MINOR 0
|
#define SAVESTATE_MINOR 1
|
||||||
|
|
||||||
class Savestate
|
class Savestate
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user