mirror of https://github.com/mgba-emu/mgba.git
DS GX: Automatically normalize winding culling calculations (fixes #699)
This commit is contained in:
parent
78a22d6674
commit
507256e682
1
CHANGES
1
CHANGES
|
@ -3,6 +3,7 @@ Features:
|
|||
- DS GX: Toon shading
|
||||
Bugfixes:
|
||||
- DS GX: Fix vertex texture transformation (fixes mgba.io/i/702)
|
||||
- DS GX: Automatically normalize winding culling calculations (fixes mgba.io/i/699)
|
||||
Misc:
|
||||
- DS GX: Clean up and unify texture mapping
|
||||
|
||||
|
|
|
@ -53,6 +53,51 @@ static inline unsigned clz32(uint32_t bits) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned clz64(uint64_t bits) {
|
||||
#if defined(__GNUC__) || __clang__
|
||||
if (!bits) {
|
||||
return 64;
|
||||
}
|
||||
return __builtin_clzll(bits);
|
||||
#else
|
||||
static const int table[256] = {
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
if (bits & 0xFF00000000000000) {
|
||||
return table[bits >> 56];
|
||||
} else if (bits & 0x00FF000000000000) {
|
||||
return table[bits >> 48] + 8;
|
||||
} else if (bits & 0x0000FF0000000000) {
|
||||
return table[bits >> 40] + 16;
|
||||
} else if (bits & 0x000000FF00000000) {
|
||||
return table[bits >> 32] + 24;
|
||||
} else if (bits & 0x00000000FF000000) {
|
||||
return table[bits >> 24] + 32;
|
||||
} else if (bits & 0x0000000000FF0000) {
|
||||
return table[bits >> 16] + 40;
|
||||
} else if (bits & 0x000000000000FF00) {
|
||||
return table[bits >> 8] + 48;
|
||||
}
|
||||
return table[bits] + 56;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t toPow2(uint32_t bits) {
|
||||
if (!bits) {
|
||||
return 0;
|
||||
|
|
27
src/ds/gx.c
27
src/ds/gx.c
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <mgba/internal/ds/ds.h>
|
||||
#include <mgba/internal/ds/io.h>
|
||||
#include <mgba-util/math.h>
|
||||
|
||||
mLOG_DEFINE_CATEGORY(DS_GX, "DS GX", "ds.gx");
|
||||
|
||||
|
@ -237,6 +238,7 @@ static bool _clipPolygon(struct DSGX* gx, struct DSGXPolygon* poly) {
|
|||
int64_t ny = 0;
|
||||
int64_t nz = 0;
|
||||
int64_t dot = 0;
|
||||
int rank = 30;
|
||||
for (v = 0; v < poly->verts; ++v) {
|
||||
struct DSGXVertex* v0 = &gx->pendingVertices[poly->vertIds[v]];
|
||||
struct DSGXVertex* v1;
|
||||
|
@ -251,9 +253,28 @@ static bool _clipPolygon(struct DSGX* gx, struct DSGXPolygon* poly) {
|
|||
v1 = &gx->pendingVertices[poly->vertIds[v + 1 - 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]) >> 24;
|
||||
ny = ((int64_t) v0->viewCoord[3] * v2->viewCoord[0] - (int64_t) v0->viewCoord[0] * v2->viewCoord[3]) >> 24;
|
||||
nz = ((int64_t) v0->viewCoord[0] * v2->viewCoord[1] - (int64_t) v0->viewCoord[1] * v2->viewCoord[0]) >> 24;
|
||||
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);
|
||||
if (ry > rx) {
|
||||
rx = ry;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
dot += nx * v1->viewCoord[0] + ny * v1->viewCoord[1] + nz * v1->viewCoord[3];
|
||||
}
|
||||
if (!DSGXPolygonAttrsIsBackFace(poly->polyParams) && dot < 0) {
|
||||
|
|
Loading…
Reference in New Issue