aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-07-14 18:35:34 +0200
committerStapleButter <thetotalworm@gmail.com>2017-07-14 18:35:34 +0200
commitd9786038527394e0a2912d9b8e091e039efd0833 (patch)
treedaf76868be9b3094f1faf152dafe61cdae6319df /src
parentcd6ecfc21ff6a8784f983503cb022514ad142bbe (diff)
3D: fix Z calculation in Z-buffering mode (should use original W, not normalized one). fixes horrendous Z-fighting in Pokémon games.
Diffstat (limited to 'src')
-rw-r--r--src/GPU3D.cpp19
1 files changed, 8 insertions, 11 deletions
diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp
index f08ee5d..d818c5c 100644
--- a/src/GPU3D.cpp
+++ b/src/GPU3D.cpp
@@ -790,22 +790,15 @@ void SubmitPolygon()
poly->NumVertices++;
// viewport transform
- s32 posX, posY, posZ;
+ s32 posX, posY;
s32 w = vtx->Position[3];
if (w == 0)
{
posX = 0;
posY = 0;
- posZ = 0;
- w = 0x1000;
}
else
{
- // W is normalized, such that all the polygon's W values fit within 16 bits
- // the viewport transform for X and Y uses the original W values, but
- // the transform for Z uses the normalized W values
- // W normalization is applied to separate polygons, even within strips
-
posX = (((s64)(vtx->Position[0] + w) * Viewport[4]) / (((s64)w) << 1)) + Viewport[0];
posY = (((s64)(-vtx->Position[1] + w) * Viewport[5]) / (((s64)w) << 1)) + Viewport[3];
}
@@ -867,6 +860,11 @@ void SubmitPolygon()
Vertex* vtx = poly->Vertices[i];
s32 w, wshifted;
+ // W is normalized, such that all the polygon's W values fit within 16 bits
+ // the viewport transform for X/Y/Z uses the original W values, but
+ // when W-buffering is used, the normalized W is used
+ // W normalization is applied to separate polygons, even within strips
+
if (wsize < 16)
{
w = vtx->Position[3] << (16 - wsize);
@@ -882,11 +880,10 @@ void SubmitPolygon()
if (FlushAttributes & 0x2)
z = wshifted;
else if (wshifted)
- z = ((((s64)vtx->Position[2] * 0x4000) / wshifted) * 0x200) + 0x7FFE00;
+ z = ((((s64)vtx->Position[2] * 0x4000) / vtx->Position[3]) + 0x3FFF) * 0x200;
else
- z = 0x7FFEFF;
+ z = 0x3FFF;
- // checkme
if (z < 0) z = 0;
else if (z > 0xFFFFFF) z = 0xFFFFFF;