From 4d3e57d6eb4197c2dd3bf533282378ea6edd54c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 2 Nov 2013 11:05:31 +0100 Subject: [PATCH] Move normal reversion into the vertex shader instead of the decoder. --- GPU/GLES/VertexDecoder.cpp | 34 ++++++------------------------ GPU/GLES/VertexShaderGenerator.cpp | 14 ++++++------ 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/GPU/GLES/VertexDecoder.cpp b/GPU/GLES/VertexDecoder.cpp index a948ab978..36ce87f8f 100644 --- a/GPU/GLES/VertexDecoder.cpp +++ b/GPU/GLES/VertexDecoder.cpp @@ -284,36 +284,27 @@ void VertexDecoder::Step_Color8888Morph() const void VertexDecoder::Step_NormalS8() const { s8 *normal = (s8 *)(decoded_ + decFmt.nrmoff); - u8 xorval = 0; - if (gstate.areNormalsReversed()) - xorval = 0xFF; // Using xor instead of - to handle -128 const s8 *sv = (const s8*)(ptr_ + nrmoff); for (int j = 0; j < 3; j++) - normal[j] = sv[j] ^ xorval; + normal[j] = sv[j]; normal[3] = 0; } void VertexDecoder::Step_NormalS16() const { s16 *normal = (s16 *)(decoded_ + decFmt.nrmoff); - u16 xorval = 0; - if (gstate.areNormalsReversed()) - xorval = 0xFFFF; const s16 *sv = (const s16*)(ptr_ + nrmoff); for (int j = 0; j < 3; j++) - normal[j] = sv[j] ^ xorval; + normal[j] = sv[j]; normal[3] = 0; } void VertexDecoder::Step_NormalFloat() const { - float *normal = (float *)(decoded_ + decFmt.nrmoff); - float multiplier = 1.0f; - if (gstate.areNormalsReversed()) - multiplier = -multiplier; - const float *fv = (const float*)(ptr_ + nrmoff); + u32 *normal = (u32 *)(decoded_ + decFmt.nrmoff); + const u32 *fv = (const u32*)(ptr_ + nrmoff); for (int j = 0; j < 3; j++) - normal[j] = fv[j] * multiplier; + normal[j] = fv[j]; } void VertexDecoder::Step_NormalS8Morph() const @@ -322,12 +313,8 @@ void VertexDecoder::Step_NormalS8Morph() const memset(normal, 0, sizeof(float)*3); for (int n = 0; n < morphcount; n++) { - float multiplier = gstate_c.morphWeights[n]; - if (gstate.areNormalsReversed()) { - multiplier = -multiplier; - } const s8 *bv = (const s8*)(ptr_ + onesize_*n + nrmoff); - multiplier *= (1.0f/127.0f); + float multiplier = gstate_c.morphWeights[n] * (1.0f/127.0f); for (int j = 0; j < 3; j++) normal[j] += bv[j] * multiplier; } @@ -339,12 +326,8 @@ void VertexDecoder::Step_NormalS16Morph() const memset(normal, 0, sizeof(float)*3); for (int n = 0; n < morphcount; n++) { - float multiplier = gstate_c.morphWeights[n]; - if (gstate.areNormalsReversed()) { - multiplier = -multiplier; - } + float multiplier = gstate_c.morphWeights[n] * (1.0f/32767.0f); const s16 *sv = (const s16 *)(ptr_ + onesize_*n + nrmoff); - multiplier *= (1.0f/32767.0f); for (int j = 0; j < 3; j++) normal[j] += sv[j] * multiplier; } @@ -357,9 +340,6 @@ void VertexDecoder::Step_NormalFloatMorph() const for (int n = 0; n < morphcount; n++) { float multiplier = gstate_c.morphWeights[n]; - if (gstate.areNormalsReversed()) { - multiplier = -multiplier; - } const float *fv = (const float*)(ptr_ + onesize_*n + nrmoff); for (int j = 0; j < 3; j++) normal[j] += fv[j] * multiplier; diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index b7796f696..8363c2566 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -109,6 +109,7 @@ void ComputeVertexShaderID(VertexShaderID *id, u32 vertType, int prim, bool useH } id->d[1] |= gstate.isLightingEnabled() << 24; id->d[1] |= (vertTypeGetWeightMask(vertType) >> GE_VTYPE_WEIGHT_SHIFT) << 25; + id->d[1] |= gstate.areNormalsReversed() << 26; } } @@ -162,6 +163,7 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear(); bool throughmode = (vertType & GE_VTYPE_THROUGH_MASK) != 0; bool flipV = gstate_c.flipTexture; + bool flipNormal = gstate.areNormalsReversed(); DoLightComputation doLight[4] = {LIGHT_OFF, LIGHT_OFF, LIGHT_OFF, LIGHT_OFF}; if (useHWTransform) { @@ -315,7 +317,7 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf // No skinning, just standard T&L. WRITE(p, " vec3 worldpos = (u_world * vec4(position.xyz, 1.0)).xyz;\n"); if (hasNormal) - WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(normal, 0.0)).xyz);\n"); + WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(%snormal, 0.0)).xyz);\n", flipNormal ? "-" : ""); else WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n"); } else { @@ -390,7 +392,7 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf WRITE(p, " vec3 worldpos = (u_world * vec4(skinnedpos, 1.0)).xyz;\n"); if (hasNormal) { - WRITE(p, " mediump vec3 skinnednormal = (skinMatrix * vec4(normal, 0.0)).xyz %s;\n", factor); + WRITE(p, " mediump vec3 skinnednormal = (skinMatrix * vec4(%snormal, 0.0)).xyz %s;\n", flipNormal ? "-" : "", factor); WRITE(p, " mediump vec3 worldnormal = normalize((u_world * vec4(skinnednormal, 0.0)).xyz);\n"); } else { WRITE(p, " mediump vec3 worldnormal = (u_world * (skinMatrix * vec4(0.0, 0.0, 1.0, 0.0))).xyz;\n"); @@ -558,13 +560,13 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf break; case GE_PROJMAP_NORMALIZED_NORMAL: // Use normalized transformed normal as source if (hasNormal) - temp_tc = "vec4(normalize(normal), 1.0)"; + temp_tc = flipNormal ? "vec4(normalize(-normal), 1.0)" : "vec4(normalize(normal), 1.0)"; else temp_tc = "vec4(0.0, 0.0, 1.0, 1.0)"; break; case GE_PROJMAP_NORMAL: // Use non-normalized transformed normal as source if (hasNormal) - temp_tc = "vec4(normal, 1.0)"; + temp_tc = flipNormal ? "vec4(-normal, 1.0)" : "vec4(normal, 1.0)"; else temp_tc = "vec4(0.0, 0.0, 1.0, 1.0)"; break; @@ -583,8 +585,8 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf break; } - if (flipV) - WRITE(p, " v_texcoord.y = 1.0 - v_texcoord.y;\n"); + if (flipV) + WRITE(p, " v_texcoord.y = 1.0 - v_texcoord.y;\n"); } // Compute fogdepth