diff options
| author | StapleButter <thetotalworm@gmail.com> | 2017-07-14 18:35:34 +0200 | 
|---|---|---|
| committer | StapleButter <thetotalworm@gmail.com> | 2017-07-14 18:35:34 +0200 | 
| commit | d9786038527394e0a2912d9b8e091e039efd0833 (patch) | |
| tree | daf76868be9b3094f1faf152dafe61cdae6319df | |
| parent | cd6ecfc21ff6a8784f983503cb022514ad142bbe (diff) | |
3D: fix Z calculation in Z-buffering mode (should use original W, not normalized one). fixes horrendous Z-fighting in Pokémon games.
| -rw-r--r-- | src/GPU3D.cpp | 19 | 
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; |