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);
            }*/
        }
Exemple #2
0
        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;
        }