diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 051bef282b..f210325a96 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -199,6 +199,7 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData& case GE_TEXMAP_TEXTURE_COORDS: case GE_TEXMAP_UNKNOWN: case GE_TEXMAP_ENVIRONMENT_MAP: + case GE_TEXMAP_TEXTURE_MATRIX: { // TODO: What happens if vertex has no texture coordinates? // Note that for environment mapping, texture coordinates have been calculated during lighting @@ -212,39 +213,6 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData& t = (v0.texturecoords.t() * wq0 + v1.texturecoords.t() * wq1) * q_recip; } break; - case GE_TEXMAP_TEXTURE_MATRIX: - { - // projection mapping, TODO: Move this code to TransformUnit! - Vec3 source; - switch (gstate.getUVProjMode()) { - case GE_PROJMAP_POSITION: - source = (v0.modelpos * p + v1.modelpos * (1.0f - p)); - break; - - case GE_PROJMAP_UV: - source = Vec3f((v0.texturecoords * p + v1.texturecoords * (1.0f - p)), 0.0f); - break; - - case GE_PROJMAP_NORMALIZED_NORMAL: - source = (v0.normal.Normalized() * p + v1.normal.Normalized() * (1.0f - p)); - break; - - case GE_PROJMAP_NORMAL: - source = (v0.normal * p + v1.normal * (1.0f - p)); - break; - - default: - ERROR_LOG_REPORT(G3D, "Software: Unsupported UV projection mode %x", gstate.getUVProjMode()); - break; - } - - Mat3x3 tgen(gstate.tgenMatrix); - Vec3 stq = tgen * source + Vec3(gstate.tgenMatrix[9], gstate.tgenMatrix[10], gstate.tgenMatrix[11]); - float z_recip = 1.0f / stq.z; - s = stq.x * z_recip; - t = stq.y * z_recip; - } - break; default: ERROR_LOG_REPORT(G3D, "Software: Unsupported texture mapping mode %x!", gstate.getUVGenMode()); s = 0.0f; @@ -259,6 +227,7 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData& case GE_TEXMAP_TEXTURE_COORDS: case GE_TEXMAP_UNKNOWN: case GE_TEXMAP_ENVIRONMENT_MAP: + case GE_TEXMAP_TEXTURE_MATRIX: { // TODO: What happens if vertex has no texture coordinates? // Note that for environment mapping, texture coordinates have been calculated during lighting @@ -274,39 +243,6 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData& t = Interpolate(v0.texturecoords.t(), v1.texturecoords.t(), v2.texturecoords.t(), wq0, wq1, wq2, q_recip); } break; - case GE_TEXMAP_TEXTURE_MATRIX: - for (int i = 0; i < 4; ++i) { - // projection mapping, TODO: Move this code to TransformUnit! - Vec3 source; - switch (gstate.getUVProjMode()) { - case GE_PROJMAP_POSITION: - source = (v0.modelpos * w0[i] + v1.modelpos * w1[i] + v2.modelpos * w2[i]) * wsum_recip[i]; - break; - - case GE_PROJMAP_UV: - source = Vec3f((v0.texturecoords * w0[i] + v1.texturecoords * w1[i] + v2.texturecoords * w2[i]) * wsum_recip[i], 0.0f); - break; - - case GE_PROJMAP_NORMALIZED_NORMAL: - source = (v0.normal.Normalized() * w0[i] + v1.normal.Normalized() * w1[i] + v2.normal.Normalized() * w2[i]) * wsum_recip[i]; - break; - - case GE_PROJMAP_NORMAL: - source = (v0.normal * w0[i] + v1.normal * w1[i] + v2.normal * w2[i]) * wsum_recip[i]; - break; - - default: - ERROR_LOG_REPORT(G3D, "Software: Unsupported UV projection mode %x", gstate.getUVProjMode()); - break; - } - - Mat3x3 tgen(gstate.tgenMatrix); - Vec3 stq = tgen * source + Vec3(gstate.tgenMatrix[9], gstate.tgenMatrix[10], gstate.tgenMatrix[11]); - float z_recip = 1.0f / stq.z; - s[i] = stq.x * z_recip; - t[i] = stq.y * z_recip; - } - break; default: ERROR_LOG_REPORT(G3D, "Software: Unsupported texture mapping mode %x!", gstate.getUVGenMode()); s = Vec4::AssignToAll(0.0f); diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 4d51a9f3d1..c7799eaf3e 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -234,12 +234,44 @@ VertexData TransformUnit::ReadVertex(VertexReader& vreader) if (vreader.hasNormal()) { vertex.worldnormal = TransformUnit::ModelToWorldNormal(vertex.normal); - // TODO: Isn't there a flag that controls whether to normalize the normal? vertex.worldnormal /= vertex.worldnormal.Length(); } else { vertex.worldnormal = Vec3(0.0f, 0.0f, 1.0f); } + // Time to generate some texture coords. Lighting will handle shade mapping. + if (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX) { + Vec3f source; + switch (gstate.getUVProjMode()) { + case GE_PROJMAP_POSITION: + source = vertex.modelpos; + break; + + case GE_PROJMAP_UV: + source = Vec3f(vertex.texturecoords, 0.0f); + break; + + case GE_PROJMAP_NORMALIZED_NORMAL: + source = vertex.normal.Normalized(); + break; + + case GE_PROJMAP_NORMAL: + source = vertex.normal; + break; + + default: + source = Vec3f::AssignToAll(0.0f); + ERROR_LOG_REPORT(G3D, "Software: Unsupported UV projection mode %x", gstate.getUVProjMode()); + break; + } + + // TODO: What about uv scale and offset? + Mat3x3 tgen(gstate.tgenMatrix); + Vec3 stq = tgen * source + Vec3(gstate.tgenMatrix[9], gstate.tgenMatrix[10], gstate.tgenMatrix[11]); + float z_recip = 1.0f / stq.z; + vertex.texturecoords = Vec2f(stq.x * z_recip, stq.y * z_recip); + } + Lighting::Process(vertex, vreader.hasColor0()); } else { vertex.screenpos.x = (int)(pos[0] * 16) + gstate.getOffsetX16();