* actually fix linear interpolation when y0>y1

* change the backfacing attribute bit, so that it doesn't mess with edgemarking
This commit is contained in:
StapleButter
2017-07-13 23:09:42 +02:00
parent 800540b710
commit a1401e724c
2 changed files with 25 additions and 19 deletions

View File

@ -849,7 +849,7 @@ void SubmitPolygon()
} }
u32 w = (u32)vtx->Position[3]; u32 w = (u32)vtx->Position[3];
while (w >> wsize) while ((w >> wsize) && (wsize < 32))
wsize += 4; wsize += 4;
} }
@ -1264,6 +1264,9 @@ void ExecuteCommand()
if (ExecParamCount >= CmdNumParams[entry.Command]) if (ExecParamCount >= CmdNumParams[entry.Command])
{ {
/*printf("0x%02X, ", entry.Command);
for (int k = 0; k < ExecParamCount; k++) printf("0x%08X, ", ExecParams[k]);
printf("\n");*/
CycleCount += CmdNumCycles[entry.Command]; CycleCount += CmdNumCycles[entry.Command];
ExecParamCount = 0; ExecParamCount = 0;

View File

@ -48,9 +48,9 @@ u32 AttrBuffer[BufferSize * 2];
// bit0-3: edge flags (left/right/top/bottom) // bit0-3: edge flags (left/right/top/bottom)
// bit8-12: antialiasing alpha // bit8-12: antialiasing alpha
// bit15: fog enable // bit15: fog enable
// bit23: backfacing flag
// bit24-29: polygon ID // bit24-29: polygon ID
// bit30: translucent flag // bit30: translucent flag
// bit31: backfacing flag
u8 StencilBuffer[256*2]; u8 StencilBuffer[256*2];
bool PrevIsShadowMask; bool PrevIsShadowMask;
@ -181,6 +181,9 @@ public:
this->x = x; this->x = x;
if (xdiff != 0 && wdiff != 0) if (xdiff != 0 && wdiff != 0)
{ {
// TODO: hardware tests show that this method is too precise
// I haven't yet figured out what the hardware does, though
s64 num = ((s64)x << (shift + 40)) / w1factor; s64 num = ((s64)x << (shift + 40)) / w1factor;
s64 denw0 = ((s64)(xdiff-x) << 40) / w0factor; s64 denw0 = ((s64)(xdiff-x) << 40) / w0factor;
s64 denw1 = num >> shift; s64 denw1 = num >> shift;
@ -197,24 +200,24 @@ public:
s32 Interpolate(s32 y0, s32 y1) s32 Interpolate(s32 y0, s32 y1)
{ {
if (xdiff == 0) return y0; if (xdiff == 0 || y0 == y1) return y0;
s32 ybase, ydiff;
if (y1 < y0)
{
ybase = y0;
ydiff = y1 - y0 - 1;
}
else
{
ybase = y0;
ydiff = y1 - y0;
}
if (wdiff != 0) if (wdiff != 0)
return ybase + ((ydiff * yfactor) >> shift); {
// perspective-correct approx. interpolation
if (y0 < y1)
return y0 + (((y1-y0) * yfactor) >> shift);
else
return y1 + (((y0-y1) * ((1<<shift)-yfactor)) >> shift);
}
else else
return ybase + ((ydiff * x) / xdiff); {
// linear interpolation
if (y0 < y1)
return y0 + (((y1-y0) * x) / xdiff);
else
return y1 + (((y0-y1) * (xdiff-x)) / xdiff);
}
} }
s32 InterpolateZ(s32 z0, s32 z1, bool wbuffer) s32 InterpolateZ(s32 z0, s32 z1, bool wbuffer)
@ -703,7 +706,7 @@ bool DepthTest_LessThan(s32 dstz, s32 z, u32 dstattr)
bool DepthTest_LessThan_FrontFacing(s32 dstz, s32 z, u32 dstattr) bool DepthTest_LessThan_FrontFacing(s32 dstz, s32 z, u32 dstattr)
{ {
if ((dstattr >> 30) == 0x2) // opaque, back facing if ((dstattr & 0x40800000) == 0x00800000) // opaque, back facing
{ {
if (z <= dstz) if (z <= dstz)
return true; return true;
@ -967,7 +970,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
Polygon* polygon = rp->PolyData; Polygon* polygon = rp->PolyData;
u32 polyattr = (polygon->Attr & 0x3F008000); u32 polyattr = (polygon->Attr & 0x3F008000);
if (!polygon->FacingView) polyattr |= (1<<31); if (!polygon->FacingView) polyattr |= (1<<23);
u32 polyalpha = (polygon->Attr >> 16) & 0x1F; u32 polyalpha = (polygon->Attr >> 16) & 0x1F;
bool wireframe = (polyalpha == 0); bool wireframe = (polyalpha == 0);