diff --git a/GPU/Directx9/TransformPipelineDX9.cpp b/GPU/Directx9/TransformPipelineDX9.cpp index af0b4c9e70..c9721ff655 100644 --- a/GPU/Directx9/TransformPipelineDX9.cpp +++ b/GPU/Directx9/TransformPipelineDX9.cpp @@ -494,22 +494,28 @@ void TransformDrawEngineDX9::SoftwareTransformAndDraw( // Scale UV? } else { // We do software T&L for now - float out[3], norm[3]; - float pos[3], nrm[3]; + float out[3]; + float pos[3]; Vec3f normal(0, 0, 1); + Vec3f worldnormal(0, 0, 1); reader.ReadPos(pos); - if (reader.hasNormal()) - reader.ReadNrm(nrm); if (!vertTypeIsSkinningEnabled(vertType)) { Vec3ByMatrix43(out, pos, gstate.worldMatrix); if (reader.hasNormal()) { - Norm3ByMatrix43(norm, nrm, gstate.worldMatrix); - normal = Vec3f(norm).Normalized(); + reader.ReadNrm(normal.AsArray()); + if (gstate.areNormalsReversed()) { + normal = -normal; + } + Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); + worldnormal = worldnormal.Normalized(); } } else { float weights[8]; reader.ReadWeights(weights); + if (reader.hasNormal()) + reader.ReadNrm(normal.AsArray()); + // Skinning Vec3f psum(0,0,0); Vec3f nsum(0,0,0); @@ -519,9 +525,9 @@ void TransformDrawEngineDX9::SoftwareTransformAndDraw( Vec3f tpos(out); psum += tpos * weights[i]; if (reader.hasNormal()) { - Norm3ByMatrix43(norm, nrm, gstate.boneMatrix+i*12); - Vec3f tnorm(norm); - nsum += tnorm * weights[i]; + Vec3f norm; + Norm3ByMatrix43(norm.AsArray(), normal.AsArray(), gstate.boneMatrix+i*12); + nsum += norm * weights[i]; } } } @@ -529,8 +535,12 @@ void TransformDrawEngineDX9::SoftwareTransformAndDraw( // Yes, we really must multiply by the world matrix too. Vec3ByMatrix43(out, psum.AsArray(), gstate.worldMatrix); if (reader.hasNormal()) { - Norm3ByMatrix43(norm, nsum.AsArray(), gstate.worldMatrix); - normal = Vec3f(norm).Normalized(); + normal = nsum; + if (gstate.areNormalsReversed()) { + normal = -normal; + } + Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); + worldnormal = worldnormal.Normalized(); } } @@ -544,11 +554,12 @@ void TransformDrawEngineDX9::SoftwareTransformAndDraw( unlitColor[2] = gstate.getMaterialAmbientB() / 255.f; unlitColor[3] = gstate.getMaterialAmbientA() / 255.f; } - float litColor0[4]; - float litColor1[4]; - lighter.Light(litColor0, litColor1, unlitColor, out, normal); if (gstate.isLightingEnabled()) { + float litColor0[4]; + float litColor1[4]; + lighter.Light(litColor0, litColor1, unlitColor, out, worldnormal); + // Don't ignore gstate.lmode - we should send two colors in that case for (int j = 0; j < 4; j++) { c0[j] = litColor0[j]; @@ -610,20 +621,16 @@ void TransformDrawEngineDX9::SoftwareTransformAndDraw( break; case GE_PROJMAP_NORMALIZED_NORMAL: // Use normalized normal as source - if (reader.hasNormal()) { - source = Vec3f(norm).Normalized(); - } else { + source = normal.Normalized(); + if (!reader.hasNormal()) { ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?"); - source = Vec3f(0.0f, 0.0f, 1.0f); } break; case GE_PROJMAP_NORMAL: // Use non-normalized normal as source! - if (reader.hasNormal()) { - source = Vec3f(norm); - } else { + source = normal; + if (!reader.hasNormal()) { ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?"); - source = Vec3f(0.0f, 0.0f, 1.0f); } break; } @@ -639,11 +646,11 @@ void TransformDrawEngineDX9::SoftwareTransformAndDraw( case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use two light sources to generate U and V. { - Vec3f lightpos0 = Vec3f(&lighter.lpos[gstate.getUVLS0()]).Normalized(); - Vec3f lightpos1 = Vec3f(&lighter.lpos[gstate.getUVLS1()]).Normalized(); + Vec3f lightpos0 = Vec3f(&lighter.lpos[gstate.getUVLS0() * 3]).Normalized(); + Vec3f lightpos1 = Vec3f(&lighter.lpos[gstate.getUVLS1() * 3]).Normalized(); - uv[0] = (1.0f + Dot(lightpos0, normal))/2.0f; - uv[1] = (1.0f - Dot(lightpos1, normal))/2.0f; + uv[0] = (1.0f + Dot(lightpos0, worldnormal))/2.0f; + uv[1] = (1.0f - Dot(lightpos1, worldnormal))/2.0f; uv[2] = 1.0f; } break; diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index 4041ddde72..7aca9239ff 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -305,7 +305,7 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) { // No skinning, just standard T&L. WRITE(p, " float3 worldpos = mul(float4(In.position.xyz, 1.0), u_world).xyz;\n"); if (hasNormal) - WRITE(p, " float3 worldnormal = normalize( mul(float4(In.normal, 0.0), u_world).xyz);\n"); + WRITE(p, " float3 worldnormal = normalize( mul(float4(In.normal, 0.0), u_world).xyz);\n", flipNormal ? "-" : ""); else WRITE(p, " float3 worldnormal = float3(0.0, 0.0, 1.0);\n"); } else { @@ -380,7 +380,7 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) { WRITE(p, " float3 worldpos = mul(float4(skinnedpos, 1.0), u_world).xyz;\n"); if (hasNormal) { - WRITE(p, " float3 skinnednormal = mul(float4(In.normal, 0.0), skinMatrix).xyz %s;\n", factor); + WRITE(p, " float3 skinnednormal = mul(float4(%sIn.normal, 0.0), skinMatrix).xyz %s;\n", flipNormal ? "-" : "", factor); WRITE(p, " float3 worldnormal = normalize(mul(float4(skinnednormal, 0.0), u_world).xyz);\n"); } else { WRITE(p, " float3 worldnormal = mul( mul( float4(0.0, 0.0, 1.0, 0.0), skinMatrix), u_world).xyz;\n");