DS GX: First pass at shadow polygons

This commit is contained in:
Vicki Pfau 2017-03-21 15:57:42 -07:00
parent d5445799a6
commit 2a29a4dd58
2 changed files with 40 additions and 23 deletions

View File

@ -88,7 +88,7 @@ struct DSGXSoftwareRenderer {
struct DSGXSoftwareSpan** bucket; struct DSGXSoftwareSpan** bucket;
int32_t depthBuffer[DS_VIDEO_HORIZONTAL_PIXELS]; int32_t depthBuffer[DS_VIDEO_HORIZONTAL_PIXELS];
uint8_t polygonIdBuffer[DS_VIDEO_HORIZONTAL_PIXELS]; uint8_t stencilBuffer[DS_VIDEO_HORIZONTAL_PIXELS];
color_t* scanlineCache; color_t* scanlineCache;
bool flushPending; bool flushPending;
bool wSort; bool wSort;

View File

@ -245,19 +245,20 @@ static color_t _lookupColor(struct DSGXSoftwareRenderer* renderer, struct DSGXSo
} }
switch (poly->blendFormat) { switch (poly->blendFormat) {
default: default:
// TODO: Alpha
return _finishColor(r, g, b, pa); return _finishColor(r, g, b, pa);
case 1:
wr = (r * ta + ep->cr * (63 - ta)) >> 6;
wg = (g * ta + ep->cg * (63 - ta)) >> 6;
wb = (b * ta + ep->cb * (63 - ta)) >> 6;
return _finishColor(wr, wg, wb, pa);
case 0: case 0:
wr = ((r + 1) * (ep->cr + 1) - 1) >> 6; wr = ((r + 1) * (ep->cr + 1) - 1) >> 6;
wg = ((g + 1) * (ep->cg + 1) - 1) >> 6; wg = ((g + 1) * (ep->cg + 1) - 1) >> 6;
wb = ((b + 1) * (ep->cb + 1) - 1) >> 6; wb = ((b + 1) * (ep->cb + 1) - 1) >> 6;
wa = ((ta + 1) * (pa + 1) - 1) >> 6; wa = ((ta + 1) * (pa + 1) - 1) >> 6;
return _finishColor(wr, wg, wb, wa); return _finishColor(wr, wg, wb, wa);
case 1:
wr = (r * ta + ep->cr * (63 - ta)) >> 6;
wg = (g * ta + ep->cg * (63 - ta)) >> 6;
wb = (b * ta + ep->cb * (63 - ta)) >> 6;
return _finishColor(wr, wg, wb, pa);
case 3:
return _finishColor(r, g, b, pa);
} }
} }
@ -651,7 +652,7 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
color_t* scanline = &softwareRenderer->scanlineCache[DS_VIDEO_HORIZONTAL_PIXELS * y]; color_t* scanline = &softwareRenderer->scanlineCache[DS_VIDEO_HORIZONTAL_PIXELS * y];
memset(scanline, 0, sizeof(color_t) * DS_VIDEO_HORIZONTAL_PIXELS); memset(scanline, 0, sizeof(color_t) * DS_VIDEO_HORIZONTAL_PIXELS);
memset(softwareRenderer->polygonIdBuffer, 0, sizeof(softwareRenderer->polygonIdBuffer[0]) * DS_VIDEO_HORIZONTAL_PIXELS); memset(softwareRenderer->stencilBuffer, 0, sizeof(softwareRenderer->stencilBuffer[0]) * DS_VIDEO_HORIZONTAL_PIXELS);
for (i = 0; i < DS_VIDEO_HORIZONTAL_PIXELS; i += 4) { for (i = 0; i < DS_VIDEO_HORIZONTAL_PIXELS; i += 4) {
softwareRenderer->depthBuffer[i] = INT32_MAX; softwareRenderer->depthBuffer[i] = INT32_MAX;
softwareRenderer->depthBuffer[i + 1] = INT32_MAX; softwareRenderer->depthBuffer[i + 1] = INT32_MAX;
@ -673,21 +674,31 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
unsigned current = scanline[x]; unsigned current = scanline[x];
unsigned b = current >> 27; unsigned b = current >> 27;
unsigned ab = a; unsigned ab = a;
unsigned s = span->polyId;
if (b > ab) { if (b > ab) {
ab = b; ab = b;
} }
if (span->poly->blendFormat == 3) {
s |= 0x40;
}
if (a == 0x1F) { if (a == 0x1F) {
if (softwareRenderer->wSort) { if (softwareRenderer->wSort) {
if (span->ep[0].w < softwareRenderer->depthBuffer[x]) { if (span->ep[0].w < softwareRenderer->depthBuffer[x]) {
softwareRenderer->depthBuffer[x] = span->ep[0].w; if (!(s & 0x40) || !(softwareRenderer->stencilBuffer[x] & s & 0x40)) {
softwareRenderer->polygonIdBuffer[x] = span->polyId; softwareRenderer->depthBuffer[x] = span->ep[0].w;
scanline[x] = color; scanline[x] = color;
s &= ~0x40;
}
softwareRenderer->stencilBuffer[x] = s;
} }
} else { } else {
if (span->ep[0].z < softwareRenderer->depthBuffer[x]) { if (span->ep[0].z < softwareRenderer->depthBuffer[x]) {
softwareRenderer->depthBuffer[x] = span->ep[0].z; if (!(s & 0x40) || !(softwareRenderer->stencilBuffer[x] & s & 0x40)) {
softwareRenderer->polygonIdBuffer[x] = span->polyId; softwareRenderer->depthBuffer[x] = span->ep[0].z;
scanline[x] = color; scanline[x] = color;
s &= ~0x40;
}
softwareRenderer->stencilBuffer[x] = s;
} }
} }
} else if (a) { } else if (a) {
@ -696,22 +707,28 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
color = _mix32(a, color, 0x1F - a, current); color = _mix32(a, color, 0x1F - a, current);
color |= ab << 27; color |= ab << 27;
} }
if (softwareRenderer->polygonIdBuffer[x] != span->polyId) { if (softwareRenderer->stencilBuffer[x] != s) {
if (softwareRenderer->wSort) { if (softwareRenderer->wSort) {
if (span->ep[0].w < softwareRenderer->depthBuffer[x]) { if (span->ep[0].w < softwareRenderer->depthBuffer[x]) {
if (DSGXPolygonAttrsIsUpdateDepth(span->poly->poly->polyParams)) { if (s != 0x40 && !(softwareRenderer->stencilBuffer[x] & 0x40)) {
softwareRenderer->depthBuffer[x] = span->ep[0].w; if (DSGXPolygonAttrsIsUpdateDepth(span->poly->poly->polyParams)) {
softwareRenderer->depthBuffer[x] = span->ep[0].w;
}
scanline[x] = color;
s &= ~0x40;
} }
softwareRenderer->polygonIdBuffer[x] = span->polyId; softwareRenderer->stencilBuffer[x] = s;
scanline[x] = color;
} }
} else { } else {
if (span->ep[0].z < softwareRenderer->depthBuffer[x]) { if (span->ep[0].z < softwareRenderer->depthBuffer[x]) {
if (DSGXPolygonAttrsIsUpdateDepth(span->poly->poly->polyParams)) { if (s != 0x40 && !(softwareRenderer->stencilBuffer[x] & 0x40)) {
softwareRenderer->depthBuffer[x] = span->ep[0].z; if (DSGXPolygonAttrsIsUpdateDepth(span->poly->poly->polyParams)) {
softwareRenderer->depthBuffer[x] = span->ep[0].z;
}
scanline[x] = color;
s &= ~0x40;
} }
softwareRenderer->polygonIdBuffer[x] = span->polyId; softwareRenderer->stencilBuffer[x] = s;
scanline[x] = color;
} }
} }
} }