3D: change viewport handling to match hardware. finally fixes #18
This commit is contained in:
parent
ad58a68fc9
commit
1acf355d99
|
@ -203,7 +203,7 @@ s32 TexMatrix[16];
|
|||
s32 ClipMatrix[16];
|
||||
bool ClipMatrixDirty;
|
||||
|
||||
s32 Viewport[4];
|
||||
u32 Viewport[6];
|
||||
|
||||
s32 ProjMatrixStack[16];
|
||||
s32 PosMatrixStack[31][16];
|
||||
|
@ -723,7 +723,6 @@ void SubmitPolygon()
|
|||
// clipping
|
||||
|
||||
nverts = ClipPolygon<true>(clippedvertices, nverts, clipstart);
|
||||
|
||||
if (nverts == 0)
|
||||
{
|
||||
LastStripPolygon = NULL;
|
||||
|
@ -803,24 +802,12 @@ void SubmitPolygon()
|
|||
// the transform for Z uses the normalized W values
|
||||
// W normalization is applied to separate polygons, even within strips
|
||||
|
||||
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;
|
||||
posX = (((s64)(vtx->Position[0] + w) * Viewport[4]) / (((s64)w) << 1)) + Viewport[0];
|
||||
posY = (((s64)(-vtx->Position[1] + w) * Viewport[5]) / (((s64)w) << 1)) + Viewport[3];
|
||||
}
|
||||
|
||||
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->FinalPosition[0] = posX & 0x1FF;
|
||||
vtx->FinalPosition[1] = posY & 0xFF;
|
||||
|
||||
vtx->FinalColor[0] = vtx->Color[0] >> 12;
|
||||
if (vtx->FinalColor[0]) vtx->FinalColor[0] = ((vtx->FinalColor[0] << 4) + 0xF);
|
||||
|
@ -1711,10 +1698,12 @@ void ExecuteCommand()
|
|||
|
||||
case 0x60: // viewport x1,y1,x2,y2
|
||||
// note: viewport Y coordinates are upside-down
|
||||
Viewport[0] = ExecParams[0] & 0xFF;
|
||||
Viewport[1] = 191 - (ExecParams[0] >> 24);
|
||||
Viewport[2] = ((ExecParams[0] >> 16) & 0xFF) - Viewport[0] + 1;
|
||||
Viewport[3] = (191 - ((ExecParams[0] >> 8) & 0xFF)) - Viewport[1] + 1;
|
||||
Viewport[0] = ExecParams[0] & 0xFF; // x0
|
||||
Viewport[1] = (191 - ((ExecParams[0] >> 8) & 0xFF)) & 0xFF; // y0
|
||||
Viewport[2] = (ExecParams[0] >> 16) & 0xFF; // x1
|
||||
Viewport[3] = (191 - (ExecParams[0] >> 24)) & 0xFF; // y1
|
||||
Viewport[4] = (Viewport[2] - Viewport[0] + 1) & 0x1FF; // width
|
||||
Viewport[5] = (Viewport[1] - Viewport[3] + 1) & 0xFF; // height
|
||||
break;
|
||||
|
||||
case 0x70: // box test
|
||||
|
|
|
@ -1049,10 +1049,12 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
|||
Interpolator interpX(xstart, xend+1, wl, wr, 8);
|
||||
|
||||
if (x < 0) x = 0;
|
||||
s32 xlimit;
|
||||
|
||||
// part 1: left edge
|
||||
edge = yedge | 0x1;
|
||||
for (; x < xstart+l_edgelen; x++)
|
||||
xlimit = xstart+l_edgelen; if (xlimit > 256) xlimit = 256;
|
||||
for (; x < xlimit; x++)
|
||||
{
|
||||
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||
u32 attr = (polygon->Attr & 0x3F008000);
|
||||
|
@ -1180,8 +1182,9 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
|||
|
||||
// part 2: polygon inside
|
||||
edge = yedge;
|
||||
if (wireframe && !edge) x = xend-r_edgelen+1;
|
||||
else for (; x <= xend-r_edgelen; x++)
|
||||
xlimit = xend-r_edgelen+1; if (xlimit > 256) xlimit = 256;
|
||||
if (wireframe && !edge) x = xlimit;
|
||||
else for (; x < xlimit; x++)
|
||||
{
|
||||
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||
u32 attr = (polygon->Attr & 0x3F008000);
|
||||
|
@ -1268,11 +1271,10 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
|
|||
AttrBuffer[pixeladdr] = attr;
|
||||
}
|
||||
|
||||
if (xend > 255) xend = 255;
|
||||
|
||||
// part 3: right edge
|
||||
edge = yedge | 0x2;
|
||||
for (; x <= xend; x++)
|
||||
xlimit = xend+1; if (xlimit > 256) xlimit = 256;
|
||||
for (; x < xlimit; x++)
|
||||
{
|
||||
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
|
||||
u32 attr = (polygon->Attr & 0x3F008000);
|
||||
|
@ -1679,23 +1681,29 @@ void RenderPolygons(bool threaded, Polygon* polygons, int npolys)
|
|||
// TODO: Y-sorting for translucent polygons
|
||||
// TODO: all sorting should be done in GPU3D.cpp
|
||||
|
||||
// polygons with ybottom>192 aren't rendered at all
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < npolys; i++)
|
||||
{
|
||||
if (polygons[i].Translucent) continue;
|
||||
|
||||
if (polygons[i].YBottom > 192) continue;
|
||||
SetupPolygon(&PolygonList[j++], &polygons[i]);
|
||||
}
|
||||
for (int i = 0; i < npolys; i++)
|
||||
{
|
||||
if (!polygons[i].Translucent) continue;
|
||||
|
||||
if (polygons[i].YBottom > 192) continue;
|
||||
SetupPolygon(&PolygonList[j++], &polygons[i]);
|
||||
}
|
||||
|
||||
RenderScanline(0, npolys);
|
||||
RenderScanline(0, j);
|
||||
|
||||
for (s32 y = 1; y < 192; y++)
|
||||
{
|
||||
RenderScanline(y, npolys);
|
||||
RenderScanline(y, j);
|
||||
ScanlineFinalPass(y-1);
|
||||
|
||||
if (threaded)
|
||||
|
|
Loading…
Reference in New Issue