Merge pull request #7736 from unknownbrackets/uv-rotation

Process UV rotation even in full transform
This commit is contained in:
Henrik Rydgård 2015-05-11 20:09:29 +02:00
commit 63ee530046
3 changed files with 38 additions and 19 deletions

View file

@ -58,18 +58,26 @@ static void SwapUVs(TransformedVertex &a, TransformedVertex &b) {
// to to or
// 1 0 0 1 1 2 3 0
// Note: 0 is BR and 2 is TL.
// See comment below where this was called before.
/*
static void RotateUV(TransformedVertex v[4]) {
float x1 = v[2].x;
float x2 = v[0].x;
float y1 = v[2].y;
float y2 = v[0].y;
static void RotateUV(TransformedVertex v[4], float flippedMatrix[16]) {
// Transform these two coordinates to figure out whether they're flipped or not.
Vec4f tl;
Vec3ByMatrix44(tl.AsArray(), v[2].pos, flippedMatrix);
Vec4f br;
Vec3ByMatrix44(br.AsArray(), v[0].pos, flippedMatrix);
const float invtlw = 1.0f / tl.w;
const float invbrw = 1.0f / br.w;
const float x1 = tl.x * invtlw;
const float x2 = br.x * invbrw;
const float y1 = tl.y * invtlw;
const float y2 = br.y * invbrw;
if ((x1 < x2 && y1 < y2) || (x1 > x2 && y1 > y2))
SwapUVs(v[1], v[3]);
}*/
}
static void RotateUVThrough(TransformedVertex v[4]) {
float x1 = v[2].x;
@ -476,6 +484,22 @@ void SoftwareTransform(
numTrans = vertexCount;
drawIndexed = true;
} else {
float flippedMatrix[16];
if (!throughmode) {
memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float));
const bool invertedY = gstate_c.vpHeight < 0;
if (invertedY) {
flippedMatrix[5] = -flippedMatrix[5];
flippedMatrix[13] = -flippedMatrix[13];
}
const bool invertedX = gstate_c.vpWidth < 0;
if (invertedX) {
flippedMatrix[0] = -flippedMatrix[0];
flippedMatrix[12] = -flippedMatrix[12];
}
}
//rectangles always need 2 vertices, disregard the last one if there's an odd number
vertexCount = vertexCount & ~1;
numTrans = 0;
@ -515,13 +539,8 @@ void SoftwareTransform(
// That's the four corners. Now process UV rotation.
if (throughmode)
RotateUVThrough(trans);
// Apparently, non-through RotateUV just breaks things.
// If we find a game where it helps, we'll just have to figure out how they differ.
// Possibly, it has something to do with flipped viewport Y axis, which a few games use.
// One game might be one of the Metal Gear ones, can't find the issue right now though.
// else
// RotateUV(trans);
else
RotateUV(trans, flippedMatrix);
// Triangle: BR-TR-TL
indsOut[0] = i * 2 + 0;

View file

@ -125,7 +125,7 @@ static inline int CalcClipMask(const ClipCoords& v)
} \
}
static void RotateUVThrough(VertexData &tl, VertexData &tr, VertexData &bl, VertexData &br) {
static void RotateUVThrough(const VertexData &tl, const VertexData &br, VertexData &tr, VertexData &bl) {
const fixed16 x1 = tl.screenpos.x;
const fixed16 x2 = br.screenpos.x;
const fixed16 y1 = tl.screenpos.y;
@ -211,7 +211,7 @@ void ProcessRect(const VertexData& v0, const VertexData& v1)
bottomright = &buf[i];
}
RotateUVThrough(*topleft, *topright, *bottomleft, *bottomright);
RotateUVThrough(v0, v1, *topright, *bottomleft);
// Four triangles to do backfaces as well. Two of them will get backface culled.
Rasterizer::DrawTriangle(*topleft, *topright, *bottomright);

View file

@ -125,8 +125,8 @@ static void ExpandRectangles(std::vector<GPUDebugVertex> &vertices, std::vector<
vert[3].u = orig_tl.u;
// That's the four corners. Now process UV rotation.
if (throughMode)
RotateUVThrough(vert);
// This is the same for through and non-through, since it's already transformed.
RotateUVThrough(vert);
// Build the two 3 point triangles from our 4 coordinates.
*ind++ = v + 0;