fixes to 3D rendering. polygons are almost pixel-perfect. clipping still doesn't get colors quite right.
This commit is contained in:
parent
261689d3d1
commit
dadf1eb5a5
37
GPU3D.cpp
37
GPU3D.cpp
|
@ -399,7 +399,7 @@ void ClipSegment(Vertex* outbuf, Vertex* vout, Vertex* vin)
|
||||||
s32 factor_den = factor_num - (vout->Position[3] - (plane*vout->Position[comp]));
|
s32 factor_den = factor_num - (vout->Position[3] - (plane*vout->Position[comp]));
|
||||||
|
|
||||||
Vertex mid;
|
Vertex mid;
|
||||||
#define INTERPOLATE(var) mid.var = vin->var + (((vout->var - vin->var) * factor_num) / factor_den);
|
#define INTERPOLATE(var) mid.var = (vin->var + ((vout->var - vin->var) * factor_num) / factor_den);
|
||||||
|
|
||||||
INTERPOLATE(Position[0]);
|
INTERPOLATE(Position[0]);
|
||||||
INTERPOLATE(Position[1]);
|
INTERPOLATE(Position[1]);
|
||||||
|
@ -587,6 +587,15 @@ void SubmitPolygon()
|
||||||
clippedvertices[1][c++] = vtx;
|
clippedvertices[1][c++] = vtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < c; i++)
|
||||||
|
{
|
||||||
|
Vertex* vtx = &clippedvertices[1][i];
|
||||||
|
|
||||||
|
vtx->Color[0] &= ~0xFFF; vtx->Color[0] += 0xFFF;
|
||||||
|
vtx->Color[1] &= ~0xFFF; vtx->Color[1] += 0xFFF;
|
||||||
|
vtx->Color[2] &= ~0xFFF; vtx->Color[2] += 0xFFF;
|
||||||
|
}
|
||||||
|
|
||||||
// Y clipping
|
// Y clipping
|
||||||
|
|
||||||
nverts = c; c = clipstart;
|
nverts = c; c = clipstart;
|
||||||
|
@ -643,6 +652,15 @@ void SubmitPolygon()
|
||||||
clippedvertices[1][c++] = vtx;
|
clippedvertices[1][c++] = vtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < c; i++)
|
||||||
|
{
|
||||||
|
Vertex* vtx = &clippedvertices[1][i];
|
||||||
|
|
||||||
|
vtx->Color[0] &= ~0xFFF; vtx->Color[0] += 0xFFF;
|
||||||
|
vtx->Color[1] &= ~0xFFF; vtx->Color[1] += 0xFFF;
|
||||||
|
vtx->Color[2] &= ~0xFFF; vtx->Color[2] += 0xFFF;
|
||||||
|
}
|
||||||
|
|
||||||
// Z clipping
|
// Z clipping
|
||||||
|
|
||||||
nverts = c; c = clipstart;
|
nverts = c; c = clipstart;
|
||||||
|
@ -699,6 +717,15 @@ void SubmitPolygon()
|
||||||
clippedvertices[1][c++] = vtx;
|
clippedvertices[1][c++] = vtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < c; i++)
|
||||||
|
{
|
||||||
|
Vertex* vtx = &clippedvertices[1][i];
|
||||||
|
|
||||||
|
vtx->Color[0] &= ~0xFFF; vtx->Color[0] += 0xFFF;
|
||||||
|
vtx->Color[1] &= ~0xFFF; vtx->Color[1] += 0xFFF;
|
||||||
|
vtx->Color[2] &= ~0xFFF; vtx->Color[2] += 0xFFF;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
{
|
{
|
||||||
LastStripPolygon = NULL;
|
LastStripPolygon = NULL;
|
||||||
|
@ -767,9 +794,9 @@ void SubmitVertex()
|
||||||
vertextrans->Position[2] = (vertex[0]*ClipMatrix[2] + vertex[1]*ClipMatrix[6] + vertex[2]*ClipMatrix[10] + vertex[3]*ClipMatrix[14]) >> 12;
|
vertextrans->Position[2] = (vertex[0]*ClipMatrix[2] + vertex[1]*ClipMatrix[6] + vertex[2]*ClipMatrix[10] + vertex[3]*ClipMatrix[14]) >> 12;
|
||||||
vertextrans->Position[3] = (vertex[0]*ClipMatrix[3] + vertex[1]*ClipMatrix[7] + vertex[2]*ClipMatrix[11] + vertex[3]*ClipMatrix[15]) >> 12;
|
vertextrans->Position[3] = (vertex[0]*ClipMatrix[3] + vertex[1]*ClipMatrix[7] + vertex[2]*ClipMatrix[11] + vertex[3]*ClipMatrix[15]) >> 12;
|
||||||
|
|
||||||
vertextrans->Color[0] = VertexColor[0];
|
vertextrans->Color[0] = (VertexColor[0] << 12) + 0xFFF;
|
||||||
vertextrans->Color[1] = VertexColor[1];
|
vertextrans->Color[1] = (VertexColor[1] << 12) + 0xFFF;
|
||||||
vertextrans->Color[2] = VertexColor[2];
|
vertextrans->Color[2] = (VertexColor[2] << 12) + 0xFFF;
|
||||||
|
|
||||||
vertextrans->Clipped = false;
|
vertextrans->Clipped = false;
|
||||||
vertextrans->ViewportTransformDone = false;
|
vertextrans->ViewportTransformDone = false;
|
||||||
|
@ -1408,7 +1435,7 @@ void Write32(u32 addr, u32 val)
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if ((CurCommand & 0xFF) || (NumCommands == 4))
|
if ((CurCommand & 0xFF) || (NumCommands == 4 && CurCommand == 0))
|
||||||
{
|
{
|
||||||
CmdFIFOEntry entry;
|
CmdFIFOEntry entry;
|
||||||
entry.Command = CurCommand & 0xFF;
|
entry.Command = CurCommand & 0xFF;
|
||||||
|
|
2
GPU3D.h
2
GPU3D.h
|
@ -25,7 +25,7 @@ namespace GPU3D
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
s32 Position[4];
|
s32 Position[4];
|
||||||
u8 Color[3];
|
s32 Color[3];
|
||||||
|
|
||||||
bool Clipped;
|
bool Clipped;
|
||||||
|
|
||||||
|
|
103
GPU3D_Soft.cpp
103
GPU3D_Soft.cpp
|
@ -78,9 +78,11 @@ void RenderPixel(u32 attr, s32 x, s32 y, s32 z, u8 vr, u8 vg, u8 vb)
|
||||||
void RenderPolygon(Polygon* polygon)
|
void RenderPolygon(Polygon* polygon)
|
||||||
{
|
{
|
||||||
int nverts = polygon->NumVertices;
|
int nverts = polygon->NumVertices;
|
||||||
|
bool isline = false;
|
||||||
|
|
||||||
int vtop = 0, vbot = 0;
|
int vtop = 0, vbot = 0;
|
||||||
s32 ytop = 191, ybot = 0;
|
s32 ytop = 192, ybot = 0;
|
||||||
|
s32 xtop = 256, xbot = 0;
|
||||||
|
|
||||||
// process the vertices, transform to screen coordinates
|
// process the vertices, transform to screen coordinates
|
||||||
// find the topmost and bottommost vertices of the polygon
|
// find the topmost and bottommost vertices of the polygon
|
||||||
|
@ -112,34 +114,36 @@ void RenderPolygon(Polygon* polygon)
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 scrX = (((posX + 0x1000) * Viewport[2]) >> 13) + Viewport[0];
|
s32 scrX = (((posX + 0x1000) * Viewport[2]) >> 13) + Viewport[0];
|
||||||
s32 scrY = (((posY + 0x1000) * Viewport[3]) >> 13) + Viewport[1];
|
s32 scrY = ((0x180000 - ((posY + 0x1000) * Viewport[3])) >> 13) + Viewport[1];
|
||||||
|
|
||||||
if (scrX < 0) scrX = 0;
|
if (scrX < 0) scrX = 0;
|
||||||
else if (scrX > 255) scrX = 255;
|
else if (scrX > 256) scrX = 256;
|
||||||
if (scrY < 0) scrY = 0;
|
if (scrY < 0) scrY = 0;
|
||||||
else if (scrY > 191) scrY = 191;
|
else if (scrY > 192) scrY = 192;
|
||||||
if (posZ < 0) posZ = 0;
|
if (posZ < 0) posZ = 0;
|
||||||
else if (posZ > 0xFFFFFF) posZ = 0xFFFFFF;
|
else if (posZ > 0xFFFFFF) posZ = 0xFFFFFF;
|
||||||
|
|
||||||
vtx->FinalPosition[0] = scrX;
|
vtx->FinalPosition[0] = scrX;
|
||||||
vtx->FinalPosition[1] = 191 - scrY;
|
vtx->FinalPosition[1] = scrY;
|
||||||
vtx->FinalPosition[2] = posZ;
|
vtx->FinalPosition[2] = posZ;
|
||||||
vtx->FinalPosition[3] = posW;
|
vtx->FinalPosition[3] = posW;
|
||||||
|
|
||||||
vtx->FinalColor[0] = vtx->Color[0] ? ((vtx->Color[0] << 4) + 0xF) : 0;
|
vtx->FinalColor[0] = vtx->Color[0] ? (((vtx->Color[0] >> 12) << 4) + 0xF) : 0;
|
||||||
vtx->FinalColor[1] = vtx->Color[1] ? ((vtx->Color[1] << 4) + 0xF) : 0;
|
vtx->FinalColor[1] = vtx->Color[1] ? (((vtx->Color[1] >> 12) << 4) + 0xF) : 0;
|
||||||
vtx->FinalColor[2] = vtx->Color[2] ? ((vtx->Color[2] << 4) + 0xF) : 0;
|
vtx->FinalColor[2] = vtx->Color[2] ? (((vtx->Color[2] >> 12) << 4) + 0xF) : 0;
|
||||||
|
|
||||||
vtx->ViewportTransformDone = true;
|
vtx->ViewportTransformDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vtx->FinalPosition[1] < ytop)
|
if (vtx->FinalPosition[1] < ytop || (vtx->FinalPosition[1] == ytop && vtx->FinalPosition[0] < xtop))
|
||||||
{
|
{
|
||||||
|
xtop = vtx->FinalPosition[0];
|
||||||
ytop = vtx->FinalPosition[1];
|
ytop = vtx->FinalPosition[1];
|
||||||
vtop = i;
|
vtop = i;
|
||||||
}
|
}
|
||||||
if (vtx->FinalPosition[1] > ybot)
|
if (vtx->FinalPosition[1] > ybot || (vtx->FinalPosition[1] == ybot && vtx->FinalPosition[0] > xbot))
|
||||||
{
|
{
|
||||||
|
xbot = vtx->FinalPosition[0];
|
||||||
ybot = vtx->FinalPosition[1];
|
ybot = vtx->FinalPosition[1];
|
||||||
vbot = i;
|
vbot = i;
|
||||||
}
|
}
|
||||||
|
@ -150,26 +154,51 @@ void RenderPolygon(Polygon* polygon)
|
||||||
int lcur = vtop, rcur = vtop;
|
int lcur = vtop, rcur = vtop;
|
||||||
int lnext, rnext;
|
int lnext, rnext;
|
||||||
|
|
||||||
if (polygon->FacingView)
|
if (ybot == ytop)
|
||||||
{
|
{
|
||||||
lnext = lcur + 1;
|
ybot++;
|
||||||
if (lnext >= nverts) lnext = 0;
|
isline = true;
|
||||||
rnext = rcur - 1;
|
|
||||||
if (rnext < 0) rnext = nverts - 1;
|
vtop = 0; vbot = 0;
|
||||||
|
xtop = 256; xbot = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
if (polygon->Vertices[i]->FinalPosition[0] < polygon->Vertices[vtop]->FinalPosition[0]) vtop = i;
|
||||||
|
if (polygon->Vertices[i]->FinalPosition[0] > polygon->Vertices[vbot]->FinalPosition[0]) vbot = i;
|
||||||
|
|
||||||
|
i = nverts - 1;
|
||||||
|
if (polygon->Vertices[i]->FinalPosition[0] < polygon->Vertices[vtop]->FinalPosition[0]) vtop = i;
|
||||||
|
if (polygon->Vertices[i]->FinalPosition[0] > polygon->Vertices[vbot]->FinalPosition[0]) vbot = i;
|
||||||
|
|
||||||
|
lcur = vtop; lnext = vtop;
|
||||||
|
rcur = vbot; rnext = vbot;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lnext = lcur - 1;
|
if (polygon->FacingView)
|
||||||
if (lnext < 0) lnext = nverts - 1;
|
{
|
||||||
rnext = rcur + 1;
|
lnext = lcur + 1;
|
||||||
if (rnext >= nverts) rnext = 0;
|
if (lnext >= nverts) lnext = 0;
|
||||||
|
rnext = rcur - 1;
|
||||||
|
if (rnext < 0) rnext = nverts - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lnext = lcur - 1;
|
||||||
|
if (lnext < 0) lnext = nverts - 1;
|
||||||
|
rnext = rcur + 1;
|
||||||
|
if (rnext >= nverts) rnext = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 y = ytop; y <= ybot; y++)
|
for (s32 y = ytop; y < ybot; y++)
|
||||||
{
|
{
|
||||||
if (y < ybot)
|
if (y > 191) break;
|
||||||
|
|
||||||
|
if (!isline)
|
||||||
{
|
{
|
||||||
while (y == polygon->Vertices[lnext]->FinalPosition[1])
|
while (y >= polygon->Vertices[lnext]->FinalPosition[1] && lcur != vbot)
|
||||||
{
|
{
|
||||||
lcur = lnext;
|
lcur = lnext;
|
||||||
|
|
||||||
|
@ -183,11 +212,9 @@ void RenderPolygon(Polygon* polygon)
|
||||||
lnext = lcur - 1;
|
lnext = lcur - 1;
|
||||||
if (lnext < 0) lnext = nverts - 1;
|
if (lnext < 0) lnext = nverts - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lcur == vbot) break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (y == polygon->Vertices[rnext]->FinalPosition[1])
|
while (y >= polygon->Vertices[rnext]->FinalPosition[1] && rcur != vbot)
|
||||||
{
|
{
|
||||||
rcur = rnext;
|
rcur = rnext;
|
||||||
|
|
||||||
|
@ -201,8 +228,6 @@ void RenderPolygon(Polygon* polygon)
|
||||||
rnext = rcur + 1;
|
rnext = rcur + 1;
|
||||||
if (rnext >= nverts) rnext = 0;
|
if (rnext >= nverts) rnext = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcur == vbot) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +251,20 @@ void RenderPolygon(Polygon* polygon)
|
||||||
s32 xl = vlcur->FinalPosition[0] + (((vlnext->FinalPosition[0] - vlcur->FinalPosition[0]) * lfactor) >> 12);
|
s32 xl = vlcur->FinalPosition[0] + (((vlnext->FinalPosition[0] - vlcur->FinalPosition[0]) * lfactor) >> 12);
|
||||||
s32 xr = vrcur->FinalPosition[0] + (((vrnext->FinalPosition[0] - vrcur->FinalPosition[0]) * rfactor) >> 12);
|
s32 xr = vrcur->FinalPosition[0] + (((vrnext->FinalPosition[0] - vrcur->FinalPosition[0]) * rfactor) >> 12);
|
||||||
|
|
||||||
if (xl<0 || xr>255)
|
if (xl > xr) // TODO: handle it in a more elegant way
|
||||||
|
{
|
||||||
|
Vertex* vtmp;
|
||||||
|
s32 tmp;
|
||||||
|
|
||||||
|
vtmp = vlcur; vlcur = vrcur; vrcur = vtmp;
|
||||||
|
vtmp = vlnext; vlnext = vrnext; vrnext = vtmp;
|
||||||
|
|
||||||
|
tmp = lfactor; lfactor = rfactor; rfactor = tmp;
|
||||||
|
|
||||||
|
tmp = xl; xl = xr; xr = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xl<0 || xr>256)
|
||||||
{
|
{
|
||||||
printf("!! BAD X %d %d\n", xl, xr);
|
printf("!! BAD X %d %d\n", xl, xr);
|
||||||
continue; // hax
|
continue; // hax
|
||||||
|
@ -262,13 +300,10 @@ void RenderPolygon(Polygon* polygon)
|
||||||
s32 gr = ((perspfactorr1 * vrcur->FinalColor[1]) + (perspfactorr2 * vrnext->FinalColor[1])) / (perspfactorr1 + perspfactorr2);
|
s32 gr = ((perspfactorr1 * vrcur->FinalColor[1]) + (perspfactorr2 * vrnext->FinalColor[1])) / (perspfactorr1 + perspfactorr2);
|
||||||
s32 br = ((perspfactorr1 * vrcur->FinalColor[2]) + (perspfactorr2 * vrnext->FinalColor[2])) / (perspfactorr1 + perspfactorr2);
|
s32 br = ((perspfactorr1 * vrcur->FinalColor[2]) + (perspfactorr2 * vrnext->FinalColor[2])) / (perspfactorr1 + perspfactorr2);
|
||||||
|
|
||||||
s32 xdiv;
|
if (xr == xl) xr++;
|
||||||
if (xr == xl)
|
s32 xdiv = 0x1000 / (xr - xl);
|
||||||
xdiv = 0;
|
|
||||||
else
|
|
||||||
xdiv = 0x1000 / (xr - xl);
|
|
||||||
|
|
||||||
for (s32 x = xl; x <= xr; x++)
|
for (s32 x = xl; x < xr; x++)
|
||||||
{
|
{
|
||||||
s32 xfactor = (x - xl) * xdiv;
|
s32 xfactor = (x - xl) * xdiv;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# depslib dependency file v1.0
|
# depslib dependency file v1.0
|
||||||
1487292827 source:c:\documents\sources\melonds\main.cpp
|
1487356459 source:c:\documents\sources\melonds\main.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
<windows.h>
|
<windows.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
1481161027 c:\documents\sources\melonds\types.h
|
1481161027 c:\documents\sources\melonds\types.h
|
||||||
|
|
||||||
1487349286 source:c:\documents\sources\melonds\nds.cpp
|
1487609259 source:c:\documents\sources\melonds\nds.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
<string.h>
|
<string.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
|
@ -146,16 +146,16 @@
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"NDSCart.h"
|
"NDSCart.h"
|
||||||
|
|
||||||
1487356069 c:\documents\sources\melonds\gpu3d.h
|
1487610598 c:\documents\sources\melonds\gpu3d.h
|
||||||
|
|
||||||
1487354054 source:c:\documents\sources\melonds\gpu3d.cpp
|
1487612707 source:c:\documents\sources\melonds\gpu3d.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
<string.h>
|
<string.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"GPU.h"
|
"GPU.h"
|
||||||
"FIFO.h"
|
"FIFO.h"
|
||||||
|
|
||||||
1487300658 source:c:\documents\sources\melonds\gpu3d_soft.cpp
|
1487611069 source:c:\documents\sources\melonds\gpu3d_soft.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
<string.h>
|
<string.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
|
|
Loading…
Reference in New Issue