From e1216e91cc52c9429430f7dcdb180e7dd0d9b087 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Tue, 23 Jul 2013 20:47:18 +0200 Subject: [PATCH] softgpu: Implement texture scaling, texture offset and texture coordinate wrapping/clamping. --- GPU/GPUState.h | 4 ++++ GPU/Software/Rasterizer.cpp | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index f3a19cf6e4..d9495c1310 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -330,6 +330,10 @@ struct GPUgstate int getUVProjMode() const { return (texmapmode >> 8) & 3;} // 2 bits int getUVLS0() const { return texshade & 0x3; } // 2 bits int getUVLS1() const { return (texshade >> 8) & 0x3; } // 2 bits + + bool isTexCoordClampedS() const { return texwrap & 1; } + bool isTexCoordClampedT() const { return (texwrap >> 8) & 1; } + int getScissorX1() const { return scissor1 & 0x3FF; } int getScissorY1() const { return (scissor1 >> 10) & 0x3FF; } int getScissorX2() const { return scissor2 & 0x3FF; } diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index e42a90d4f4..712de4c83b 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -100,11 +100,39 @@ static inline u32 SampleNearest(int level, float s, float t) // TODO: Should probably check if textures are aligned properly... - // TODO: Not sure if that through mode treatment is correct.. - unsigned int u = (gstate.isModeThrough()) ? s : s * width; // TODO: -1? - unsigned int v = (gstate.isModeThrough()) ? t : t * height; // TODO: -1? + unsigned int u, v; + if (gstate.isModeThrough()) { + // TODO: Is it really this simple? + u = s; + v = t; + } else { + if (gstate.getUVGenMode() == 0) { + s *= getFloat24(gstate.texscaleu); + t *= getFloat24(gstate.texscalev); - // TODO: texcoord wrapping!! + s += getFloat24(gstate.texoffsetu); + t += getFloat24(gstate.texoffsetv); + + // TODO: Is this really only necessary for UV mapping? + if (gstate.isTexCoordClampedS()) { + if (s > 1.0) s = 1.0; + if (s < 0) s = 0; + } else { + // TODO: Does this work for negative coords? + s = fmod(s, 1.0f); + } + if (gstate.isTexCoordClampedT()) { + if (t > 1.0) t = 1.0; + if (t < 0.0) t = 0.0; + } else { + // TODO: Does this work for negative coords? + t = fmod(t, 1.0f); + } + } + + u = s * width; // TODO: width-1 instead? + v = t * height; // TODO: width-1 instead? + } // TODO: Assert tmap.tmn == 0 (uv texture mapping mode)