public GLSLCombineManager(F3DEX2Interpreter f3dex2) { supported = ((GraphicsContext.CurrentContext as IGraphicsContextInternal).GetAddress("glCreateShader") != IntPtr.Zero); F3DEX2 = f3dex2; shaderCache = new List<GLSLShaders>(); /*foreach (uint[] knownMux in KnownCombinerMuxes.Muxes) { BindCombiner(knownMux[0], knownMux[1], true); BindCombiner(knownMux[0], knownMux[1], false); }*/ }
public GLSLShaders(uint m0, uint m1, F3DEX2Interpreter f3dex2, bool tex) { F3DEX2 = f3dex2; Mux0 = m0; Mux1 = m1; HasLightingEnabled = Convert.ToBoolean(f3dex2.GeometryMode & (uint)General.GeometryMode.LIGHTING); Unpacked = new UnpackedCombinerMux(m0, m1); Textured = tex; StringBuilder vs = new StringBuilder(), fs = new StringBuilder(); vs.AppendFormat(shaderPrefix, Program.AppNameVer, "Vertex", m0, m1, HasLightingEnabled); vs.AppendLine(shaderVersion); vs.AppendLine(vertexShaderVariables); vs.AppendLine(shaderMainPrefix); vs.AppendLine(vertexShaderCommon); fs.AppendFormat(shaderPrefix, Program.AppNameVer, "Fragment", m0, m1, HasLightingEnabled); fs.AppendLine(shaderVersion); fs.AppendLine(fragmentShaderVariables); fs.AppendLine(shaderMainPrefix); // TODO can this be made nicer? texturing and lighting? if (Textured) fs.AppendLine(fragmentShaderCommon); fs.AppendLine(fragmentShaderLighting); if (!HasLightingEnabled) { fs.AppendLine("vec4 lightColor = gl_Color;"); vs.AppendLine("gl_FrontColor = gl_Color;"); } else fs.AppendLine("vec4 lightColor = gl_Color + Iamb + Idiff + Ispec;"); if (!Textured) fs.AppendLine("vec4 tex0color = lightColor;\nvec4 tex1color = lightColor;"); fs.AppendLine(); for (int i = 0; i < 2; i++) { StringBuilder calc = new StringBuilder(); calc.AppendFormat("{0} = vec4((", (i == 0 ? "combColor" : "outColor")); switch (Unpacked.cA[i]) { case UnpackedCombinerMux.ComponentsC16.CCMUX_COMBINED: calc.Append("combColor"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_TEXEL0: calc.Append("tex0color"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_TEXEL1: calc.Append("tex1color"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_PRIMITIVE: calc.Append("primColor"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_SHADE: calc.Append("lightColor"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_ENVIRONMENT: calc.Append("envColor"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_1: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_COMBINED_ALPHA: calc.Append("comb.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_TEXEL0_ALPHA: calc.Append("tex0color.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_TEXEL1_ALPHA: calc.Append("tex1color.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_PRIMITIVE_ALPHA: calc.Append("primColor.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_SHADE_ALPHA: calc.Append("lightColor.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_ENV_ALPHA: calc.Append("envColor.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_LOD_FRACTION: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_PRIM_LOD_FRAC: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); //unemulated for now break; case UnpackedCombinerMux.ComponentsC16.CCMUX_0: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; } calc.Append(" - "); switch (Unpacked.cB[i]) { case UnpackedCombinerMux.ComponentsC16.CCMUX_COMBINED: calc.Append("combColor"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_TEXEL0: calc.Append("tex0color"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_TEXEL1: calc.Append("tex1color"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_PRIMITIVE: calc.Append("primColor"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_SHADE: calc.Append("lightColor"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_ENVIRONMENT: calc.Append("envColor"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_1: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_COMBINED_ALPHA: calc.Append("comb.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_TEXEL0_ALPHA: calc.Append("tex0color.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_TEXEL1_ALPHA: calc.Append("tex1color.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_PRIMITIVE_ALPHA: calc.Append("primColor.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_SHADE_ALPHA: calc.Append("lightColor.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_ENV_ALPHA: calc.Append("envColor.a"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_LOD_FRACTION: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; case UnpackedCombinerMux.ComponentsC16.CCMUX_PRIM_LOD_FRAC: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); //unemulated for now break; case UnpackedCombinerMux.ComponentsC16.CCMUX_0: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; } calc.Append(") * "); switch (Unpacked.cC[i]) { case UnpackedCombinerMux.ComponentsC32.CCMUX_COMBINED: calc.Append("combColor"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_TEXEL0: calc.Append("tex0color"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_TEXEL1: calc.Append("tex1color"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_PRIMITIVE: calc.Append("primColor"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_SHADE: calc.Append("lightColor"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_ENVIRONMENT: calc.Append("envColor"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_1: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_COMBINED_ALPHA: calc.Append("comb.a"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_TEXEL0_ALPHA: calc.Append("tex0color.a"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_TEXEL1_ALPHA: calc.Append("tex1color.a"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_PRIMITIVE_ALPHA: calc.Append("primColor.a"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_SHADE_ALPHA: calc.Append("lightColor.a"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_ENV_ALPHA: calc.Append("envColor.a"); break; case UnpackedCombinerMux.ComponentsC32.CCMUX_LOD_FRACTION: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); //unemulated for now break; case UnpackedCombinerMux.ComponentsC32.CCMUX_PRIM_LOD_FRAC: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); //unemulated for now break; case UnpackedCombinerMux.ComponentsC32.CCMUX_K5: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); //unemulated for now break; case UnpackedCombinerMux.ComponentsC32.CCMUX_0: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; } calc.Append(" + "); switch (Unpacked.cD[i]) { case UnpackedCombinerMux.ComponentsC8.CCMUX_COMBINED: calc.Append("combColor"); break; case UnpackedCombinerMux.ComponentsC8.CCMUX_TEXEL0: calc.Append("tex0color"); break; case UnpackedCombinerMux.ComponentsC8.CCMUX_TEXEL1: calc.Append("tex1color"); break; case UnpackedCombinerMux.ComponentsC8.CCMUX_PRIMITIVE: calc.Append("primColor"); break; case UnpackedCombinerMux.ComponentsC8.CCMUX_SHADE: calc.Append("lightColor"); break; case UnpackedCombinerMux.ComponentsC8.CCMUX_ENVIRONMENT: calc.Append("envColor"); break; case UnpackedCombinerMux.ComponentsC8.CCMUX_1: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); break; case UnpackedCombinerMux.ComponentsC8.CCMUX_0: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; } calc.AppendLine(");"); calc.AppendFormat("{0} = vec4((", (i == 0 ? "combAlpha" : "outAlpha")); switch (Unpacked.aA[i]) { case UnpackedCombinerMux.ComponentsA8.ACMUX_COMBINED: calc.Append("combAlpha.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_TEXEL0: calc.Append("tex0color.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_TEXEL1: calc.Append("tex1color.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_PRIMITIVE: calc.Append("primColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_SHADE: calc.Append("lightColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_ENVIRONMENT: calc.Append("envColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_1: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_0: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; } calc.Append(" - "); switch (Unpacked.aB[i]) { case UnpackedCombinerMux.ComponentsA8.ACMUX_COMBINED: calc.Append("combAlpha.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_TEXEL0: calc.Append("tex0color.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_TEXEL1: calc.Append("tex1color.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_PRIMITIVE: calc.Append("primColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_SHADE: calc.Append("lightColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_ENVIRONMENT: calc.Append("envColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_1: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_0: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; } calc.Append(") * "); switch (Unpacked.aC[i]) { case UnpackedCombinerMux.ComponentsA8.ACMUX_COMBINED: calc.Append("combAlpha.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_TEXEL0: calc.Append("tex0color.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_TEXEL1: calc.Append("tex1color.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_PRIMITIVE: calc.Append("primColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_SHADE: calc.Append("lightColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_ENVIRONMENT: calc.Append("envColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_1: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_0: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; } calc.Append(" + "); switch (Unpacked.aD[i]) { case UnpackedCombinerMux.ComponentsA8.ACMUX_COMBINED: calc.Append("combAlpha.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_TEXEL0: calc.Append("tex0color.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_TEXEL1: calc.Append("tex1color.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_PRIMITIVE: calc.Append("primColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_SHADE: calc.Append("lightColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_ENVIRONMENT: calc.Append("envColor.a"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_1: calc.Append("vec4(1.0, 1.0, 1.0, 1.0)"); break; case UnpackedCombinerMux.ComponentsA8.ACMUX_0: calc.Append("vec4(0.0, 0.0, 0.0, 0.0)"); break; } calc.AppendLine(");"); calc.AppendLine("gl_FragColor.rgb = outColor.rgb;"); calc.AppendLine("gl_FragColor.a = outAlpha.a;"); fs.AppendLine(calc.ToString()); //fs.AppendLine("gl_FragColor = lightColor;"); } vs.AppendLine(shaderMainSuffix); fs.AppendLine(shaderMainSuffix); /*System.IO.StreamWriter sw = new System.IO.StreamWriter(string.Format(@"C:\Temp\{0:X8}_{1:X8}_{2}.txt", m0, m1, HasLightingEnabled ? "light" : "nolight")); sw.Write(vs.ToString()); sw.Write(fs.ToString()); sw.Close(); */ int vo = -1, fo = -1, p = -1; CreateShaders(vs.ToString(), fs.ToString(), ref vo, ref fo, ref p); VertexObject = vo; FragmentObject = fo; ProgramID = p; }