edge marking

This commit is contained in:
StapleButter 2017-06-03 22:33:14 +02:00
parent 64a447bb7c
commit 568b9fbf49
1 changed files with 96 additions and 72 deletions

View File

@ -923,8 +923,16 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
// * edges with slope = 0 are always filled
// edges are always filled if antialiasing is enabled or if the pixels are translucent
if (wireframe || (RenderDispCnt & (1<<5)))
{
l_filledge = true;
r_filledge = true;
}
else
{
l_filledge = (rp->SlopeL.Negative || !rp->SlopeL.XMajor);
r_filledge = (!rp->SlopeR.Negative && rp->SlopeR.XMajor) || (rp->SlopeR.Increment==0);
}
s32 wl = rp->SlopeL.Interp.Interpolate(polygon->FinalW[rp->CurVL], polygon->FinalW[rp->NextVL]);
s32 wr = rp->SlopeR.Interp.Interpolate(polygon->FinalW[rp->CurVR], polygon->FinalW[rp->NextVR]);
@ -1026,7 +1034,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
// checkme
if (polyalpha == 31)
{
if (!wireframe && !(RenderDispCnt & (1<<4)))
if (!(RenderDispCnt & (1<<4)))
{
if (!l_filledge)
continue;
@ -1073,8 +1081,6 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
{
// anti-aliasing: all edges are rendered
if (edge)
{
// calculate coverage
// TODO: optimize
s32 cov = 31;
@ -1102,16 +1108,8 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
AttrBuffer[pixeladdr+BufferSize] = AttrBuffer[pixeladdr];
}
}
}
else
{
// edge fill rules for opaque pixels
if (!wireframe)
{
if (!l_filledge)
else if (!l_filledge)
continue;
}
}
DepthBuffer[pixeladdr] = z;
}
@ -1256,7 +1254,7 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
// checkme
if (polyalpha == 31)
{
if (!wireframe && !(RenderDispCnt & (1<<4)))
if (!(RenderDispCnt & (1<<4)))
{
if (!r_filledge)
continue;
@ -1303,8 +1301,6 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
{
// anti-aliasing: all edges are rendered
if (edge)
{
// calculate coverage
// TODO: optimize
s32 cov = 31;
@ -1332,16 +1328,8 @@ void RenderPolygonScanline(RendererPolygon* rp, s32 y)
AttrBuffer[pixeladdr+BufferSize] = AttrBuffer[pixeladdr];
}
}
}
else
{
// edge fill rules for opaque pixels
if (!wireframe)
{
if (!r_filledge)
else if (!r_filledge)
continue;
}
}
DepthBuffer[pixeladdr] = z;
}
@ -1386,6 +1374,42 @@ void RenderScanline(s32 y, int npolys)
void ScanlineFinalPass(s32 y)
{
// to consider:
// clearing all polygon fog flags if the master flag isn't set?
// merging all final pass loops into one?
if (RenderDispCnt & (1<<5))
{
// edge marking
for (int x = 0; x < 256; x++)
{
u32 pixeladdr = FirstPixelOffset + (y*ScanlineWidth) + x;
u32 attr = AttrBuffer[pixeladdr];
if (!(attr & 0xF)) continue;
u32 polyid = attr >> 24;
u32 z = DepthBuffer[pixeladdr];
if (((polyid != (AttrBuffer[pixeladdr-1] >> 24)) && (z < DepthBuffer[pixeladdr-1])) ||
((polyid != (AttrBuffer[pixeladdr+1] >> 24)) && (z < DepthBuffer[pixeladdr+1])) ||
((polyid != (AttrBuffer[pixeladdr-ScanlineWidth] >> 24)) && (z < DepthBuffer[pixeladdr-ScanlineWidth])) ||
((polyid != (AttrBuffer[pixeladdr+ScanlineWidth] >> 24)) && (z < DepthBuffer[pixeladdr+ScanlineWidth])))
{
u16 edgecolor = RenderEdgeTable[polyid >> 3];
u32 edgeR = (edgecolor << 1) & 0x3E; if (edgeR) edgeR++;
u32 edgeG = (edgecolor >> 4) & 0x3E; if (edgeG) edgeG++;
u32 edgeB = (edgecolor >> 9) & 0x3E; if (edgeB) edgeB++;
ColorBuffer[pixeladdr] = edgeR | (edgeG << 8) | (edgeB << 16) | (ColorBuffer[pixeladdr] & 0xFF000000);
// break antialiasing coverage (checkme)
AttrBuffer[pixeladdr] = (AttrBuffer[pixeladdr] & 0xFFFFE0FF) | 0x00001000;
}
}
}
if (RenderDispCnt & (1<<7))
{
// fog
@ -1395,7 +1419,7 @@ void ScanlineFinalPass(s32 y)
// multiplied by 0x200 to match Z-buffer values
// fog is applied to the topmost two pixels, which is required for
// proper antialiasing
// proper antialiasing (TODO)
bool fogcolor = !(RenderDispCnt & (1<<6));
u32 fogshift = (RenderDispCnt >> 8) & 0xF;