When projecting textures, flip V in frag shader.

Slower, but this way we actually project correctly.
This commit is contained in:
Unknown W. Brackets 2014-06-07 19:32:19 -07:00
parent da438b7c68
commit ed39bb7a9c
3 changed files with 21 additions and 7 deletions

View File

@ -370,10 +370,9 @@ void ComputeFragmentShaderID(FragmentShaderID *id) {
id0 |= 1 << 1;
id0 |= gstate.getTextureFunction() << 2;
id0 |= (doTextureAlpha & 1) << 5; // rgb or rgba
id0 |= (gstate_c.flipTexture & 1) << 6;
}
// 6 is free.
id0 |= (lmode & 1) << 7;
if (enableAlphaTest) {
id0 |= 1 << 8;
@ -585,10 +584,13 @@ void GenerateFragmentShader(char *buffer) {
// We may also be wrapping in such a surface, or either one in a too-small surface.
// Obviously, clamping to a smaller surface won't work. But better to clamp to something.
std::string ucoord = "v_texcoord.x";
std::string vcoord = "1.0 - v_texcoord.y";
std::string vcoord = "v_texcoord.y";
if (doTextureProjection) {
ucoord += " / v_texcoord.z";
vcoord = "1.0 - (v_texcoord.y / v_texcoord.z)";
vcoord = "(v_texcoord.y / v_texcoord.z)";
// Vertex texcoords are NOT flipped when projecting despite gstate_c.flipTexture.
} else if (gstate_c.flipTexture) {
vcoord = "1.0 - " + vcoord;
}
if (gstate.isTexCoordClampedS()) {
@ -603,10 +605,19 @@ void GenerateFragmentShader(char *buffer) {
vcoord = "mod(" + vcoord + ", u_texclamp.y)";
}
WRITE(p, " vec2 fixedcoord = vec2(%s, 1.0 - %s);\n", ucoord.c_str(), vcoord.c_str());
if (gstate_c.flipTexture) {
vcoord = "1.0 - " + vcoord;
}
WRITE(p, " vec2 fixedcoord = vec2(%s, %s);\n", ucoord.c_str(), vcoord.c_str());
texcoord = "fixedcoord";
// We already projected it.
doTextureProjection = false;
} else if (doTextureProjection && gstate_c.flipTexture) {
// Since we need to flip v, we project manually.
WRITE(p, " vec2 fixedcoord = vec2(v_texcoord.x / v_texcoord.z, 1.0 - (v_texcoord.y / v_texcoord.z));\n");
texcoord = "fixedcoord";
doTextureProjection = false;
}
if (doTextureProjection) {

View File

@ -172,6 +172,8 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
}
VertexReader reader(decoded, decVtxFormat, vertType);
// We flip in the fragment shader for GE_TEXMAP_TEXTURE_MATRIX.
const bool flipV = gstate_c.flipTexture && gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_MATRIX;
for (int index = 0; index < maxIndex; index++) {
reader.Goto(index);
@ -371,7 +373,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
memcpy(&transformed[index].x, v, 3 * sizeof(float));
transformed[index].fog = fogCoef;
memcpy(&transformed[index].u, uv, 3 * sizeof(float));
if (gstate_c.flipTexture) {
if (flipV) {
transformed[index].v = 1.0f - transformed[index].v;
}
transformed[index].color0_32 = c0.ToRGBA();

View File

@ -661,7 +661,8 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf
break;
}
if (flipV)
// Will flip in the fragment for GE_TEXMAP_TEXTURE_MATRIX.
if (flipV && gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_MATRIX)
WRITE(p, " v_texcoord.y = 1.0 - v_texcoord.y;\n");
}