mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
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:
parent
036baf04d0
commit
3c5455f85b
@ -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);
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user