SoftGPU: Calculate texcoords in transform.

No need to do it in rasterization, and should be faster to do it on the
verts, anyway.  This fixes the software issue of #11595, presumably
because of the w handling.
This commit is contained in:
Unknown W. Brackets 2018-11-25 19:19:11 -08:00
parent 036baf04d0
commit 3c5455f85b
2 changed files with 35 additions and 67 deletions

View File

@ -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<float> 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<float> tgen(gstate.tgenMatrix);
Vec3<float> stq = tgen * source + Vec3<float>(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<float> 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<float> tgen(gstate.tgenMatrix);
Vec3<float> stq = tgen * source + Vec3<float>(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<float>::AssignToAll(0.0f);

View File

@ -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<float>(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<float> tgen(gstate.tgenMatrix);
Vec3<float> stq = tgen * source + Vec3<float>(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();