aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-03-16 15:55:18 +0100
committerStapleButter <thetotalworm@gmail.com>2017-03-16 15:55:18 +0100
commit7f85a100027c5dc25552e358edc080771b59c59a (patch)
treeb6f0c27430876941335a0ec933273a8793809d5e
parent1dc887d0bbad1ae9effcff891985eb92a1d98b74 (diff)
move viewport transform to polygon setup
-rw-r--r--GPU3D.cpp81
-rw-r--r--GPU3D.h12
-rw-r--r--GPU3D_Soft.cpp80
3 files changed, 84 insertions, 89 deletions
diff --git a/GPU3D.cpp b/GPU3D.cpp
index b10f1b1..ed1ab52 100644
--- a/GPU3D.cpp
+++ b/GPU3D.cpp
@@ -217,7 +217,7 @@ u32 CurRAMBank;
u32 ClearAttr1, ClearAttr2;
u32 FlushRequest;
-u32 FlushAttributes, CurFlushAttributes;
+u32 FlushAttributes;
@@ -293,7 +293,6 @@ void Reset()
FlushRequest = 0;
FlushAttributes = 0;
- CurFlushAttributes = 0;
SoftRenderer::Reset();
}
@@ -456,7 +455,6 @@ void ClipSegment(Vertex* outbuf, Vertex* vout, Vertex* vin)
INTERPOLATE(TexCoords[1]);
mid.Clipped = true;
- mid.ViewportTransformDone = false;
#undef INTERPOLATE
*outbuf = mid;
@@ -765,6 +763,7 @@ void SubmitPolygon()
if (NumPolygons >= 2048 || NumVertices+c > 6144)
{
LastStripPolygon = NULL;
+ // TODO: set DISP3DCNT overflow flag
return;
}
@@ -805,13 +804,79 @@ void SubmitPolygon()
for (int i = clipstart; i < c; i++)
{
- CurVertexRAM[NumVertices] = clippedvertices[1][i];
- poly->Vertices[i] = &CurVertexRAM[NumVertices];
+ Vertex* vtx = &CurVertexRAM[NumVertices];
+ *vtx = clippedvertices[1][i];
+ poly->Vertices[i] = vtx;
NumVertices++;
poly->NumVertices++;
+
+ // viewport transform
+ s32 posX, posY, posZ;
+ s32 w = vtx->Position[3];
+ if (w == 0)
+ {
+ posX = 0;
+ posY = 0;
+ posZ = 0;
+ w = 0x1000;
+ }
+ else
+ {
+ posX = (((s64)(vtx->Position[0] + w) * Viewport[2]) / (((s64)w) << 1)) + Viewport[0];
+ posY = (((s64)(-vtx->Position[1] + w) * Viewport[3]) / (((s64)w) << 1)) + Viewport[1];
+
+ if (FlushAttributes & 0x2) posZ = w;
+ else posZ = (((s64)vtx->Position[2] * 0x800000) / w) + 0x7FFEFF;
+ }
+
+ if (posX < 0) posX = 0;
+ else if (posX > 256) posX = 256;
+ if (posY < 0) posY = 0;
+ else if (posY > 192) posY = 192;
+ if (posZ < 0) posZ = 0;
+ else if (posZ > 0xFFFFFF) posZ = 0xFFFFFF;
+
+ vtx->FinalPosition[0] = posX;
+ vtx->FinalPosition[1] = posY;
+ vtx->FinalPosition[2] = posZ;
+ vtx->FinalPosition[3] = w;
+
+ vtx->FinalColor[0] = vtx->Color[0] >> 12;
+ if (vtx->FinalColor[0]) vtx->FinalColor[0] = ((vtx->FinalColor[0] << 4) + 0xF);
+ vtx->FinalColor[1] = vtx->Color[1] >> 12;
+ if (vtx->FinalColor[1]) vtx->FinalColor[1] = ((vtx->FinalColor[1] << 4) + 0xF);
+ vtx->FinalColor[2] = vtx->Color[2] >> 12;
+ if (vtx->FinalColor[2]) vtx->FinalColor[2] = ((vtx->FinalColor[2] << 4) + 0xF);
}
+ // determine bounds of the polygon
+ u32 vtop = 0, vbot = 0;
+ s32 ytop = 192, ybot = 0;
+ s32 xtop = 256, xbot = 0;
+
+ for (int i = 0; i < c; i++)
+ {
+ Vertex* vtx = poly->Vertices[i];
+
+ if (vtx->FinalPosition[1] < ytop || (vtx->FinalPosition[1] == ytop && vtx->FinalPosition[0] < xtop))
+ {
+ xtop = vtx->FinalPosition[0];
+ ytop = vtx->FinalPosition[1];
+ vtop = i;
+ }
+ if (vtx->FinalPosition[1] > ybot || (vtx->FinalPosition[1] == ybot && vtx->FinalPosition[0] > xbot))
+ {
+ xbot = vtx->FinalPosition[0];
+ ybot = vtx->FinalPosition[1];
+ vbot = i;
+ }
+ }
+
+ poly->VTop = vtop; poly->VBottom = vbot;
+ poly->YTop = ytop; poly->YBottom = ybot;
+ poly->XTop = xtop; poly->XBottom = xbot;
+
if (PolygonMode >= 2)
LastStripPolygon = poly;
else
@@ -845,7 +910,6 @@ void SubmitVertex()
}
vertextrans->Clipped = false;
- vertextrans->ViewportTransformDone = false;
VertexNum++;
VertexNumInPoly++;
@@ -1562,9 +1626,7 @@ void VBlank()
{
if (FlushRequest)
{
- SoftRenderer::DispCnt = DispCnt;
- SoftRenderer::AlphaRef = AlphaRef;
- SoftRenderer::RenderFrame(CurFlushAttributes, CurVertexRAM, CurPolygonRAM, NumPolygons);
+ SoftRenderer::RenderFrame(CurVertexRAM, CurPolygonRAM, NumPolygons);
CurRAMBank = CurRAMBank?0:1;
CurVertexRAM = &VertexRAM[CurRAMBank ? 6144 : 0];
@@ -1574,7 +1636,6 @@ void VBlank()
NumPolygons = 0;
FlushRequest = 0;
- CurFlushAttributes = FlushAttributes;
}
}
diff --git a/GPU3D.h b/GPU3D.h
index e2948bf..c1adc2f 100644
--- a/GPU3D.h
+++ b/GPU3D.h
@@ -36,8 +36,6 @@ typedef struct
s32 FinalPosition[4];
s32 FinalColor[3];
- bool ViewportTransformDone;
-
} Vertex;
typedef struct
@@ -52,9 +50,14 @@ typedef struct
bool FacingView;
bool Translucent;
+ u32 VTop, VBottom; // vertex indices
+ s32 YTop, YBottom; // Y coords
+ s32 XTop, XBottom; // associated X coords
+
} Polygon;
extern u32 DispCnt;
+extern u32 AlphaRef;
extern s32 Viewport[4];
extern u32 ClearAttr1, ClearAttr2;
@@ -81,14 +84,11 @@ void Write32(u32 addr, u32 val);
namespace SoftRenderer
{
-extern u32 DispCnt;
-extern u32 AlphaRef;
-
bool Init();
void DeInit();
void Reset();
-void RenderFrame(u32 attr, Vertex* vertices, Polygon* polygons, int npolys);
+void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys);
u32* GetLine(int line);
}
diff --git a/GPU3D_Soft.cpp b/GPU3D_Soft.cpp
index 1566ee8..5c9dc8e 100644
--- a/GPU3D_Soft.cpp
+++ b/GPU3D_Soft.cpp
@@ -27,9 +27,6 @@ namespace GPU3D
namespace SoftRenderer
{
-u32 DispCnt;
-u32 AlphaRef;
-
u32 ColorBuffer[256*192];
u32 DepthBuffer[256*192];
u32 AttrBuffer[256*192];
@@ -336,77 +333,14 @@ u32 RenderPixel(Polygon* polygon, s32 x, s32 y, s32 z, u8 vr, u8 vg, u8 vb, s16
return r | (g << 8) | (b << 16) | (a << 24);
}
-void RenderPolygon(Polygon* polygon, u32 wbuffer)
+void RenderPolygon(Polygon* polygon)
{
int nverts = polygon->NumVertices;
bool isline = false;
- int vtop = 0, vbot = 0;
- s32 ytop = 192, ybot = 0;
- s32 xtop = 256, xbot = 0;
-
- // process the vertices, transform to screen coordinates
- // find the topmost and bottommost vertices of the polygon
-
- for (int i = 0; i < nverts; i++)
- {
- Vertex* vtx = polygon->Vertices[i];
-
- if (!vtx->ViewportTransformDone)
- {
- s32 posX, posY, posZ;
- s32 w = vtx->Position[3];
- if (w == 0)
- {
- posX = 0;
- posY = 0;
- posZ = 0;
- w = 0x1000;
- }
- else
- {
- posX = (((s64)(vtx->Position[0] + w) * Viewport[2]) / (((s64)w) << 1)) + Viewport[0];
- posY = (((s64)(-vtx->Position[1] + w) * Viewport[3]) / (((s64)w) << 1)) + Viewport[1];
-
- if (wbuffer) posZ = w;
- else posZ = (((s64)vtx->Position[2] * 0x800000) / w) + 0x7FFEFF;
- }
-
- if (posX < 0) posX = 0;
- else if (posX > 256) posX = 256;
- if (posY < 0) posY = 0;
- else if (posY > 192) posY = 192;
- if (posZ < 0) posZ = 0;
- else if (posZ > 0xFFFFFF) posZ = 0xFFFFFF;
-
- vtx->FinalPosition[0] = posX;
- vtx->FinalPosition[1] = posY;
- vtx->FinalPosition[2] = posZ;
- vtx->FinalPosition[3] = w;
-
- vtx->FinalColor[0] = vtx->Color[0] >> 12;
- if (vtx->FinalColor[0]) vtx->FinalColor[0] = ((vtx->FinalColor[0] << 4) + 0xF);
- vtx->FinalColor[1] = vtx->Color[1] >> 12;
- if (vtx->FinalColor[1]) vtx->FinalColor[1] = ((vtx->FinalColor[1] << 4) + 0xF);
- vtx->FinalColor[2] = vtx->Color[2] >> 12;
- if (vtx->FinalColor[2]) vtx->FinalColor[2] = ((vtx->FinalColor[2] << 4) + 0xF);
-
- vtx->ViewportTransformDone = true;
- }
-
- if (vtx->FinalPosition[1] < ytop || (vtx->FinalPosition[1] == ytop && vtx->FinalPosition[0] < xtop))
- {
- xtop = vtx->FinalPosition[0];
- ytop = vtx->FinalPosition[1];
- vtop = i;
- }
- if (vtx->FinalPosition[1] > ybot || (vtx->FinalPosition[1] == ybot && vtx->FinalPosition[0] > xbot))
- {
- xbot = vtx->FinalPosition[0];
- ybot = vtx->FinalPosition[1];
- vbot = i;
- }
- }
+ int vtop = polygon->VTop, vbot = polygon->VBottom;
+ s32 ytop = polygon->YTop, ybot = polygon->YBottom;
+ s32 xtop = polygon->XTop, xbot = polygon->XBottom;
if (ytop > 191) return;
@@ -837,7 +771,7 @@ void RenderPolygon(Polygon* polygon, u32 wbuffer)
}
}
-void RenderFrame(u32 attr, Vertex* vertices, Polygon* polygons, int npolys)
+void RenderFrame(Vertex* vertices, Polygon* polygons, int npolys)
{
u32 polyid = (ClearAttr1 >> 24) & 0x3F;
@@ -900,13 +834,13 @@ void RenderFrame(u32 attr, Vertex* vertices, Polygon* polygons, int npolys)
for (int i = 0; i < npolys; i++)
{
if (polygons[i].Translucent) continue;
- RenderPolygon(&polygons[i], attr&0x2);
+ RenderPolygon(&polygons[i]);
}
for (int i = 0; i < npolys; i++)
{
if (!polygons[i].Translucent) continue;
- RenderPolygon(&polygons[i], attr&0x2);
+ RenderPolygon(&polygons[i]);
}
}