DS GX: Partial polygon clipping
Vicki Pfau vi@endrift.com
Fri, 03 Mar 2017 18:16:35 -0800
1 files changed,
46 insertions(+),
1 deletions(-)
jump to
M
src/ds/gx.c
→
src/ds/gx.c
@@ -23,6 +23,8 @@ static void DSGXDummyRendererGetScanline(struct DSGXRenderer* renderer, int y, color_t** output);
static void DSGXWriteFIFO(struct DSGX* gx, struct DSGXEntry entry); +static bool _boxTestVertex(struct DSGX* gx, struct DSGXVertex* vertex); + static const int32_t _gxCommandCycleBase[DS_GX_CMD_MAX] = { [DS_GX_CMD_NOP] = 0, [DS_GX_CMD_MTX_MODE] = 2,@@ -176,6 +178,46 @@ gx->p->memory.io9[DS9_REG_CLIPMTX_RESULT_1E >> 1] = gx->clipMatrix.m[15];
gx->p->memory.io9[DS9_REG_CLIPMTX_RESULT_1F >> 1] = gx->clipMatrix.m[15] >> 16; } +static bool _clipPolygon(struct DSGX* gx, struct DSGXPolygon* poly) { + struct DSGXVertex* vbuf = gx->vertexBuffer[gx->bufferIndex]; + int nOffscreen = 0; + unsigned offscreenVerts[4] = {}; + int v; + // Collect offscreen vertices + for (v = 0; v < poly->verts; ++v) { + if (!_boxTestVertex(gx, &vbuf[gx->currentPoly.vertIds[v]])) { + offscreenVerts[nOffscreen] = gx->currentPoly.vertIds[v]; + ++nOffscreen; + } + } + if (!nOffscreen) { + return true; + } + + // All of the vertices are offscreen + // TODO: clip vertices instead of discarding them + if (nOffscreen == poly->verts) { + // Remove all vertices before remaking them + gx->vertexIndex -= poly->verts; + // Put back the ones that are on the strip + for (v = 0; v < gx->currentPoly.verts; ++v) { + unsigned vid = gx->currentPoly.vertIds[v]; + int ov; + for (ov = 0; ov < nOffscreen; ++ov) { + if (vid != offscreenVerts[ov]) { + continue; + } + vbuf[gx->vertexIndex] = vbuf[vid]; + gx->currentPoly.vertIds[v] = gx->vertexIndex; + ++gx->vertexIndex; + break; + } + } + return false; + } + return true; +} + static int32_t _dotViewport(struct DSGXVertex* vertex, int32_t* col) { int64_t a; int64_t b;@@ -308,7 +350,10 @@ pbuf[gx->polygonIndex].vertIds[3] = gx->currentPoly.vertIds[2];
gx->currentPoly.verts = 2; break; } - ++gx->polygonIndex; + + if (_clipPolygon(gx, &pbuf[gx->polygonIndex])) { + ++gx->polygonIndex; + } } }