all repos — mgba @ 4f3754b74a543b014f7ad0e24cd164d0eae4e865

mGBA Game Boy Advance Emulator

DS GX: Properly center cross product in polygon normal calculations
Vicki Pfau vi@endrift.com
Sun, 16 Jul 2017 18:45:46 -0700
commit

4f3754b74a543b014f7ad0e24cd164d0eae4e865

parent

5f05662242ed37f20626e20b5b690a8cd1b7bd07

3 files changed, 27 insertions(+), 18 deletions(-)

jump to
M CHANGESCHANGES

@@ -6,6 +6,7 @@ - DS GX: Fix vertex texture transformation (fixes mgba.io/i/702)

- DS GX: Automatically normalize winding culling calculations (fixes mgba.io/i/699) - DS GX: Fixed viewport calculations (fixes mgba.io/i/709) - DS Video: Fix display capture blending value 16 (fixes mgba.io/i/757) + - DS GX: Properly center cross product in polygon normal calculations Misc: - DS GX: Clean up and unify texture mapping - DS Core: Add symbol loading
M include/mgba/internal/ds/gx.hinclude/mgba/internal/ds/gx.h

@@ -50,8 +50,8 @@

DECL_BITFIELD(DSGXPolygonAttrs, uint32_t); DECL_BITS(DSGXPolygonAttrs, Lights, 0, 4); DECL_BITS(DSGXPolygonAttrs, Mode, 4, 2); -DECL_BIT(DSGXPolygonAttrs, FrontFace, 6); -DECL_BIT(DSGXPolygonAttrs, BackFace, 7); +DECL_BIT(DSGXPolygonAttrs, BackFace, 6); +DECL_BIT(DSGXPolygonAttrs, FrontFace, 7); DECL_BIT(DSGXPolygonAttrs, UpdateDepth, 11); // TODO DECL_BITS(DSGXPolygonAttrs, Alpha, 16, 5);
M src/ds/gx.csrc/ds/gx.c

@@ -238,24 +238,32 @@ int64_t nx = 0;

int64_t ny = 0; int64_t nz = 0; int64_t dot = 0; - int rank = 30; + int rank = 29; for (v = 0; v < poly->verts; ++v) { - struct DSGXVertex* v0 = &gx->pendingVertices[poly->vertIds[v]]; + struct DSGXVertex v0 = gx->pendingVertices[poly->vertIds[v]]; struct DSGXVertex* v1; - struct DSGXVertex* v2; + struct DSGXVertex v2; if (v < poly->verts - 2) { v1 = &gx->pendingVertices[poly->vertIds[v + 1]]; - v2 = &gx->pendingVertices[poly->vertIds[v + 2]]; + v2 = gx->pendingVertices[poly->vertIds[v + 2]]; } else if (v < poly->verts - 1) { v1 = &gx->pendingVertices[poly->vertIds[v + 1]]; - v2 = &gx->pendingVertices[poly->vertIds[v + 2 - poly->verts]]; + v2 = gx->pendingVertices[poly->vertIds[v + 2 - poly->verts]]; } else { v1 = &gx->pendingVertices[poly->vertIds[v + 1 - poly->verts]]; - v2 = &gx->pendingVertices[poly->vertIds[v + 2 - poly->verts]]; + v2 = gx->pendingVertices[poly->vertIds[v + 2 - poly->verts]]; } - nx = ((int64_t) v0->viewCoord[1] * v2->viewCoord[3] - (int64_t) v0->viewCoord[3] * v2->viewCoord[1]); - ny = ((int64_t) v0->viewCoord[3] * v2->viewCoord[0] - (int64_t) v0->viewCoord[0] * v2->viewCoord[3]); - nz = ((int64_t) v0->viewCoord[0] * v2->viewCoord[1] - (int64_t) v0->viewCoord[1] * v2->viewCoord[0]); + // Center around v1 + v0.viewCoord[0] -= v1->viewCoord[0]; + v0.viewCoord[1] -= v1->viewCoord[1]; + v0.viewCoord[3] -= v1->viewCoord[3]; + v2.viewCoord[0] -= v1->viewCoord[0]; + v2.viewCoord[1] -= v1->viewCoord[1]; + v2.viewCoord[3] -= v1->viewCoord[3]; + // Calculate cross product + nx = ((int64_t) v0.viewCoord[1] * v2.viewCoord[3] - (int64_t) v0.viewCoord[3] * v2.viewCoord[1]); + ny = ((int64_t) v0.viewCoord[3] * v2.viewCoord[0] - (int64_t) v0.viewCoord[0] * v2.viewCoord[3]); + nz = ((int64_t) v0.viewCoord[0] * v2.viewCoord[1] - (int64_t) v0.viewCoord[1] * v2.viewCoord[0]); int rx = 64 - clz64(nx >= 0 ? nx : -nx); int ry = 64 - clz64(ny >= 0 ? ny : -ny); int rz = 64 - clz64(nz >= 0 ? nz : -nz);

@@ -265,22 +273,22 @@ }

if (rz > rx) { rx = rz; } - if (rx > 30) { - nx >>= rx - 30; - ny >>= rx - 30; - nz >>= rx - 30; - } if (rx > rank) { dot >>= rx - rank; rank = rx; } + if (rank > 29) { + nx >>= rank - 29; + ny >>= rank - 29; + nz >>= rank - 29; + } dot += nx * v1->viewCoord[0] + ny * v1->viewCoord[1] + nz * v1->viewCoord[3]; } - if (!DSGXPolygonAttrsIsBackFace(poly->polyParams) && dot < 0) { + if (!DSGXPolygonAttrsIsFrontFace(poly->polyParams) && dot < 0) { return false; } - if (!DSGXPolygonAttrsIsFrontFace(poly->polyParams) && dot > 0) { + if (!DSGXPolygonAttrsIsBackFace(poly->polyParams) && dot > 0) { return false; } }