Example #1
0
        private static TevStage ReadTevCombinerStage(EndianBinaryReader stream)
        {
            var retVal = new TevStage();

            retVal.Unknown0 = stream.ReadByte();
            for (int i = 0; i < 4; i++)
            {
                retVal.ColorIn[i] = (GXCombineColorInput)stream.ReadByte();
            }
            retVal.ColorOp    = (GXTevOp)stream.ReadByte();
            retVal.ColorBias  = (GXTevBias)stream.ReadByte();
            retVal.ColorScale = (GXTevScale)stream.ReadByte();
            retVal.ColorClamp = stream.ReadBoolean();
            retVal.ColorRegId = stream.ReadByte();
            for (int i = 0; i < 4; i++)
            {
                retVal.AlphaIn[i] = (GXCombineAlphaInput)stream.ReadByte();
            }
            retVal.AlphaOp    = (GXTevOp)stream.ReadByte();
            retVal.AlphaBias  = (GXTevBias)stream.ReadByte();
            retVal.AlphaScale = (GXTevScale)stream.ReadByte();
            retVal.AlphaClamp = stream.ReadBoolean();
            retVal.AlphaRegId = stream.ReadByte();
            retVal.Unknown1   = stream.ReadByte();

            Trace.Assert(retVal.Unknown0 == 0xFF);
            Trace.Assert(retVal.Unknown1 == 0xFF);
            return(retVal);
        }
Example #2
0
 public MaterialEntry(EndianBinaryReader er)
 {
     Name           = er.ReadString(Encoding.ASCII, 20).Replace("\0", "");
     BufferColor    = er.ReadColor8();
     ConstColors    = new Color[6];
     ConstColors[0] = er.ReadColor8();
     ConstColors[1] = er.ReadColor8();
     ConstColors[2] = er.ReadColor8();
     ConstColors[3] = er.ReadColor8();
     ConstColors[4] = er.ReadColor8();
     ConstColors[5] = er.ReadColor8();
     Flags          = er.ReadUInt32();
     //Material Flag:
     //  0-1: Nr texMap
     //  2-3: Nr texMatrix
     //  4-5: Nr texCoordGen
     //  6-8: Nr tevStage
     //    9: Has alphaCompare
     //   10: Has blendMode
     //   11: Use Texture Only
     //   12: Separate Blend Mode
     //   14: Has Indirect Parameter
     //15-16: Nr projectionTexGenParameter
     //   17: Has Font Shadow Parameter
     TexMaps = new TexMap[Flags & 3];
     for (int i = 0; i < (Flags & 3); i++)
     {
         TexMaps[i] = new TexMap(er);
     }
     TexMatrices = new TexMatrix[(Flags >> 2) & 3];
     for (int i = 0; i < ((Flags >> 2) & 3); i++)
     {
         TexMatrices[i] = new TexMatrix(er);
     }
     TexCoordGens = new TexCoordGen[(Flags >> 4) & 3];
     for (int i = 0; i < ((Flags >> 4) & 3); i++)
     {
         TexCoordGens[i] = new TexCoordGen(er);
     }
     TevStages = new TevStage[(Flags >> 6) & 7];
     for (int i = 0; i < ((Flags >> 6) & 7); i++)
     {
         TevStages[i] = new TevStage(er);
     }
     if (((Flags >> 9) & 1) == 1)
     {
         AlphaTest = new AlphaCompare(er);
     }
     if (((Flags >> 10) & 1) == 1)
     {
         ColorBlendMode = new BlendMode(er);
     }
     if (((Flags >> 12) & 1) == 1)
     {
         AlphaBlendMode = new BlendMode(er);
     }
     //Some more things
 }
Example #3
0
        private void GenerateTevColorAndAlphaCommands(Material mat)
        {
            for (int i = 0; i < 16; i++)
            {
                if (mat.TevStages[i] == null)
                {
                    continue;
                }
                TevStage stage = mat.TevStages[i].Value;
                if (mat.SwapModes[i] == null)
                {
                    continue;
                }
                TevSwapMode swapMode = mat.SwapModes[i].Value;

                BPCommand tev_color_env = new BPCommand()
                {
                    Register = BPRegister.TEV_COLOR_ENV_0 + i * 2
                };
                BPCommand tev_alpha_env = new BPCommand()
                {
                    Register = BPRegister.TEV_ALPHA_ENV_0 + i * 2
                };
                BPCommand ind_cmd = new BPCommand()
                {
                    Register = BPRegister.IND_CMD0 + i
                };

                tev_color_env.SetBits((int)stage.ColorInD, 0, 4);
                tev_color_env.SetBits((int)stage.ColorInC, 4, 4);
                tev_color_env.SetBits((int)stage.ColorInB, 8, 4);
                tev_color_env.SetBits((int)stage.ColorInA, 12, 4);

                tev_color_env.SetBits((int)stage.ColorBias, 16, 2);
                tev_color_env.SetBits((int)stage.ColorOp, 18, 1);
                tev_color_env.SetFlag(stage.ColorClamp, 19);
                tev_color_env.SetBits((int)stage.ColorScale, 20, 2);
                tev_color_env.SetBits((int)stage.ColorRegId, 22, 2);

                tev_alpha_env.SetBits((int)stage.AlphaInA, 13, 3);
                tev_alpha_env.SetBits((int)stage.AlphaInB, 10, 3);
                tev_alpha_env.SetBits((int)stage.AlphaInC, 7, 3);
                tev_alpha_env.SetBits((int)stage.AlphaInD, 4, 3);

                tev_alpha_env.SetBits((int)stage.AlphaBias, 16, 2);
                tev_alpha_env.SetBits((int)stage.AlphaOp, 18, 1);
                tev_alpha_env.SetFlag(stage.AlphaClamp, 19);
                tev_alpha_env.SetBits((int)stage.AlphaScale, 20, 2);
                tev_alpha_env.SetBits((int)stage.AlphaRegId, 22, 2);

                tev_alpha_env.SetBits(swapMode.RasSel, 0, 2);
                tev_alpha_env.SetBits(swapMode.TexSel, 2, 2);

                BPCommands.Add(tev_color_env);
                BPCommands.Add(tev_alpha_env);
                BPCommands.Add(ind_cmd);
            }
        }
Example #4
0
 public MaterialEntry(EndianBinaryReader er)
 {
     Name = er.ReadString(Encoding.ASCII, 20).Replace("\0", "");
     BufferColor = er.ReadColor8();
     ConstColors = new Color[6];
     ConstColors[0] = er.ReadColor8();
     ConstColors[1] = er.ReadColor8();
     ConstColors[2] = er.ReadColor8();
     ConstColors[3] = er.ReadColor8();
     ConstColors[4] = er.ReadColor8();
     ConstColors[5] = er.ReadColor8();
     Flags = er.ReadUInt32();
     //Material Flag:
     //  0-1: Nr texMap
     //  2-3: Nr texMatrix
     //  4-5: Nr texCoordGen
     //  6-8: Nr tevStage
     //    9: Has alphaCompare
     //   10: Has blendMode
     //   11: Use Texture Only
     //   12: Separate Blend Mode
     //   14: Has Indirect Parameter
     //15-16: Nr projectionTexGenParameter
     //   17: Has Font Shadow Parameter
     TexMaps = new TexMap[Flags & 3];
     for (int i = 0; i < (Flags & 3); i++)
     {
         TexMaps[i] = new TexMap(er);
     }
     TexMatrices = new TexMatrix[(Flags >> 2) & 3];
     for (int i = 0; i < ((Flags >> 2) & 3); i++)
     {
         TexMatrices[i] = new TexMatrix(er);
     }
     TexCoordGens = new TexCoordGen[(Flags >> 4) & 3];
     for (int i = 0; i < ((Flags >> 4) & 3); i++)
     {
         TexCoordGens[i] = new TexCoordGen(er);
     }
     TevStages = new TevStage[(Flags >> 6) & 7];
     for (int i = 0; i < ((Flags >> 6) & 7); i++)
     {
         TevStages[i] = new TevStage(er);
     }
     if (((Flags >> 9) & 1) == 1) AlphaTest = new AlphaCompare(er);
     if (((Flags >> 10) & 1) == 1) ColorBlendMode = new BlendMode(er);
     if (((Flags >> 12) & 1) == 1) AlphaBlendMode = new BlendMode(er);
     //Some more things
 }
Example #5
0
        private static bool GenerateFragmentShader(Shader shader, Material mat)
        {
            StringBuilder stream = new StringBuilder();

            // Shader Header
            stream.AppendLine("#version 330 core");
            stream.AppendLine();

            // Configure inputs to match our outputs from VS
            if (mat.VtxDesc.AttributeIsEnabled(ShaderAttributeIds.Position))
            {
                stream.AppendLine("in vec3 Position;");
            }

            if (mat.VtxDesc.AttributeIsEnabled(ShaderAttributeIds.Normal))
            {
                stream.AppendLine("in vec3 Normal;");
            }

            for (int i = 0; i < mat.NumChannelControls; i++)
            {
                stream.AppendLine(string.Format("in vec4 Color{0};", i));
            }

            for (int texGen = 0; texGen < mat.NumTexGens; texGen++)
            {
                stream.AppendLine(string.Format("in vec3 Tex{0};", texGen));
            }

            stream.AppendLine();

            // Final Output
            stream.AppendLine("// Final Output");
            stream.AppendLine("out vec4 PixelColor;");

            // Texture Inputs
            for (int i = 0; i < 8; i++)
            {
                if (mat.Textures[i] == null)
                {
                    continue;
                }

                stream.AppendLine(string.Format("uniform sampler2D Texture{0};", i));
            }

            // Main Function
            stream.AppendLine("void main()");
            stream.AppendLine("{");

            // Default initial values of the TEV registers.
            // ToDo: Does this need swizzling? themikelester has it marked as mat.registerColor[i==0?3:i-1]]
            stream.AppendLine("    // Initial TEV Register Values");
            for (int i = 0; i < 4; i++)
            {
                stream.AppendLine(string.Format("    vec4 {0} = vec4({1}, {2}, {3}, {4});", m_tevOutputRegs[i], mat.TevColor[i].R, mat.TevColor[i].G, mat.TevColor[i].B, mat.TevColor[i].A));
            }
            stream.AppendLine();

            // Constant Color Registers
            stream.AppendLine("    // Konst TEV Colors");
            for (int i = 0; i < 4; i++)
            {
                stream.AppendLine(string.Format("    vec4 konst{0} = vec4({1}, {2}, {3}, {4});", i, mat.TevKonstColors[i].R, mat.TevKonstColors[i].G, mat.TevKonstColors[i].B, mat.TevKonstColors[i].A));
            }
            stream.AppendLine();

            // Texture Samples
            bool[] oldCombos = new bool[256];
            for (int i = 0; i < mat.NumTevStages; i++)
            {
                TevOrder       order = mat.TevOrderInfos[i];
                int            tex   = order.TexMap;
                GXTexCoordSlot coord = order.TexCoordId;

                // This TEV probably doesn't use textures.
                if (tex == 0xFF || coord == GXTexCoordSlot.Null)
                {
                    continue;
                }

                if (IsNewTexCombo(tex, (int)coord, oldCombos))
                {
                    string swizzle = ""; // Uhh I don't know if we need to swizzle since everyone's been converted into ARGB
                    stream.AppendLine(string.Format("    vec4 texCol{0} = texture(Texture{0}, Tex{1}.xy){2};", tex, (int)coord, swizzle));
                }
            }
            stream.AppendLine();

            // ToDo: Implement indirect texturing.
            stream.AppendLine("    // TEV Stages");
            stream.AppendLine();
            stream.AppendLine();

            for (int i = 0; i < mat.NumTevStages; i++)
            {
                stream.AppendLine(string.Format("    // TEV Stage {0}", i));
                TevOrder order = mat.TevOrderInfos[i];
                TevStage stage = mat.TevStageInfos[i];

                TevSwapMode      swap     = mat.TevSwapModes[i];
                TevSwapModeTable rasTable = mat.TevSwapModeTables[swap.RasSel];
                TevSwapModeTable texTable = mat.TevSwapModeTables[swap.TexSel];

                // There's swapping involved in the ras table.
                stream.AppendLine(string.Format("    // Rasterization Swap Table: {0}", rasTable));
                if (!(rasTable.R == 0 && rasTable.G == 1 && rasTable.B == 2 && rasTable.A == 3))
                {
                    stream.AppendLine(string.Format("    {0} = {1}{2};", GetVertColorString(order), GetVertColorString(order), GetSwapModeSwizzleString(rasTable)));
                }
                stream.AppendLine();


                // There's swapping involved in the texture table.
                stream.AppendLine(string.Format("    // Texture Swap Table: {0}", texTable));
                if (!(texTable.R == 0 && texTable.G == 1 && texTable.B == 2 && texTable.A == 3))
                {
                    stream.AppendLine(string.Format("    {0} = {1}{2};", GetTexTapString(order), GetTexTapString(order), GetSwapModeSwizzleString(rasTable)));
                }
                stream.AppendLine();

                string[] colorInputs = new string[4];
                colorInputs[0] = GetColorInString(stage.ColorIn[0], mat.KonstColorSels[i], order);
                colorInputs[1] = GetColorInString(stage.ColorIn[1], mat.KonstColorSels[i], order);
                colorInputs[2] = GetColorInString(stage.ColorIn[2], mat.KonstColorSels[i], order);
                colorInputs[3] = GetColorInString(stage.ColorIn[3], mat.KonstColorSels[i], order);

                stream.AppendLine("    // Color and Alpha Operations");
                stream.AppendLine(string.Format("    {0}", GetColorOpString(stage.ColorOp, stage.ColorBias, stage.ColorScale, stage.ColorClamp, stage.ColorRegId, colorInputs)));

                string[] alphaInputs = new string[4];
                alphaInputs[0] = GetAlphaInString(stage.AlphaIn[0], mat.KonstAlphaSels[i], order);
                alphaInputs[1] = GetAlphaInString(stage.AlphaIn[1], mat.KonstAlphaSels[i], order);
                alphaInputs[2] = GetAlphaInString(stage.AlphaIn[2], mat.KonstAlphaSels[i], order);
                alphaInputs[3] = GetAlphaInString(stage.AlphaIn[3], mat.KonstAlphaSels[i], order);

                stream.AppendLine(string.Format("    {0}", GetAlphaOpString(stage.AlphaOp, stage.AlphaBias, stage.AlphaScale, stage.AlphaClamp, stage.AlphaRegId, alphaInputs)));
                stream.AppendLine();
            }
            stream.AppendLine();

            // Alpha Compare
            stream.AppendLine("    // Alpha Compare Test");
            AlphaCompare alphaCompare = mat.AlphaCompare;
            string       alphaOp;

            switch (alphaCompare.Operation)
            {
            case GXAlphaOp.And: alphaOp = "&&"; break;

            case GXAlphaOp.Or: alphaOp = "||"; break;

            case GXAlphaOp.XOR: alphaOp = "^"; break;     // Not really tested, unsupported in some examples but I don't see why.

            case GXAlphaOp.XNOR: alphaOp = "=="; break;   // Not really tested. ^

            default:
                WLog.Warning(LogCategory.TEVShaderGenerator, null, "Unsupported alpha compare operation: {0}", alphaCompare.Operation);
                alphaOp = "||";
                break;
            }

            // clip(result.a < 0.5 && result a > 0.2 ? -1 : 1)
            string ifContents = string.Format("(!({0} {1} {2}))",
                                              GetCompareString(alphaCompare.Comp0, m_tevOutputRegs[0] + ".a", alphaCompare.Reference0),
                                              alphaOp,
                                              GetCompareString(alphaCompare.Comp1, m_tevOutputRegs[0] + ".a", alphaCompare.Reference1));

            // clip equivelent
            stream.AppendLine("    // Alpha Compare (Clip)");
            stream.AppendLine(string.Format("    if{0}\n\t\tdiscard;", ifContents));

            //string output = "PixelColor = texCol0" + (mat.VtxDesc.AttributeIsEnabled(ShaderAttributeIds.Color0) ? " * Color0;" : ";");
            //stream.AppendLine(output);
            stream.AppendLine(string.Format("    PixelColor = {0};", m_tevOutputRegs[0]));

            stream.AppendLine("}");
            stream.AppendLine();

            // Compile the Fragment Shader and return whether it compiled sucesfully or not.
            Directory.CreateDirectory("ShaderDump");
            System.IO.File.WriteAllText("ShaderDump/" + mat.Name + "_frag_output", stream.ToString());
            return(shader.CompileSource(stream.ToString(), OpenTK.Graphics.OpenGL.ShaderType.FragmentShader));
        }
        private static void WriteStage(StringBuilder stream, int stageIndex, Material mat, MAT3 data)
        {
            // Basic TEV Operation:
            // Inputs: [0 <= A, B, C <= 255] [-1024 <= D <= 1023]
            // Lerp between A and B using C as the interpolation factor. Optionally negate the result
            // using op. Input D and a bias (0, +0.5, -0.5) are added to the result. Then a constant
            // scale (1, 2, 4, 0.5) is applied. Result is optionally clamped before being written to
            // an output buffer.

            TevStage tevStage = mat.TevStages[stageIndex];
            TevOrder tevOrder = mat.TevOrders[stageIndex];

            stream.AppendFormat("\t// TEV Stage {0}\n", stageIndex);
            stream.AppendFormat("\t// Unknown0: {0} ColorInA: {1} ColorInB: {2} ColorInC: {3} ColorInD: {4} ColorOp: {5} ColorBias: {6} ColorScale: {7} ColorClamp: {8} ColorRegId: {9}\n", tevStage.Unknown0, tevStage.ColorIn[0], tevStage.ColorIn[1], tevStage.ColorIn[2], tevStage.ColorIn[3], tevStage.ColorOp, tevStage.ColorBias, tevStage.ColorScale, tevStage.ColorClamp, tevStage.ColorRegister);
            stream.AppendFormat("\t// AlphaInA: {0} AlphaInB: {1} AlphaInC: {2} AlphaInD: {3} AlphaOp: {4} AlphaBias: {5} AlphaScale: {6} AlphaClamp: {7} AlphaRegId: {8} Unknown1: {9}\n", tevStage.AlphaIn[0], tevStage.AlphaIn[1], tevStage.AlphaIn[2], tevStage.AlphaIn[3], tevStage.AlphaOp, tevStage.AlphaBias, tevStage.AlphaScale, tevStage.AlphaClamp, tevStage.AlphaRegister, tevStage.Unknown1);
            stream.AppendFormat("\t// Tev Order TexCoordId: {0} TexMap: {1} ChannelId: {2}\n", tevOrder.TexCoordId, tevOrder.TexMap, tevOrder.ChannelId);

            TevSwapMode      swapMode     = mat.TevSwapModes[stageIndex];
            TevSwapModeTable rasSwapTable = mat.TevSwapModeTables[swapMode.RasSel];
            TevSwapModeTable texSwapTable = mat.TevSwapModeTables[swapMode.TexSel];

            stream.AppendFormat("\t// TEV Swap Mode: RasSel: {0} TexSel: {1}\n", swapMode.RasSel, swapMode.TexSel);
            stream.AppendFormat("\t// Ras Swap Table: R: {0} G: {1} B: {2} A: {3}\n", rasSwapTable.R, rasSwapTable.G, rasSwapTable.B, rasSwapTable.A);
            stream.AppendFormat("\t// Tex Swap Table: R: {0} G: {1} B: {2} A: {3}\n", texSwapTable.R, texSwapTable.G, texSwapTable.B, texSwapTable.A);

            int  texcoord     = (int)tevOrder.TexCoordId;
            bool bHasTexCoord = (int)tevOrder.TexCoordId < mat.NumTexGens;

            // Build a Swap Mode for swapping texture color input/rasterized color input to the TEV Stage.
            string[] rasSwapModeTable = new string[4];
            string   swapColors       = "rgba";

            for (int i = 0; i < 4; i++)
            {
                char[] swapTable = new char[4];

                swapTable[0]        = swapColors[rasSwapTable.R];
                swapTable[1]        = swapColors[rasSwapTable.G];
                swapTable[2]        = swapColors[rasSwapTable.B];
                swapTable[3]        = swapColors[rasSwapTable.A];
                rasSwapModeTable[i] = new string(swapTable);
            }

            string[] texSwapModeTable = new string[4];
            for (int i = 0; i < 4; i++)
            {
                char[] swapTable = new char[4];

                swapTable[0]        = swapColors[texSwapTable.R];
                swapTable[1]        = swapColors[texSwapTable.G];
                swapTable[2]        = swapColors[texSwapTable.B];
                swapTable[3]        = swapColors[texSwapTable.A];
                texSwapModeTable[i] = new string(swapTable);
            }


            // ToDo: Implement Indirect Stages

            // If our TEV Stage uses rasterized alpha or color inputs
            if (tevStage.ColorIn[0] == GXCombineColorInput.RasAlpha || tevStage.ColorIn[0] == GXCombineColorInput.RasColor ||
                tevStage.ColorIn[1] == GXCombineColorInput.RasAlpha || tevStage.ColorIn[1] == GXCombineColorInput.RasColor ||
                tevStage.ColorIn[2] == GXCombineColorInput.RasAlpha || tevStage.ColorIn[2] == GXCombineColorInput.RasColor ||
                tevStage.ColorIn[3] == GXCombineColorInput.RasAlpha || tevStage.ColorIn[3] == GXCombineColorInput.RasColor ||
                tevStage.AlphaIn[0] == GXCombineAlphaInput.RasAlpha || tevStage.AlphaIn[1] == GXCombineAlphaInput.RasAlpha ||
                tevStage.AlphaIn[2] == GXCombineAlphaInput.RasAlpha || tevStage.AlphaIn[3] == GXCombineAlphaInput.RasAlpha)
            {
                stream.AppendFormat("\t// TEV Swap Mode\n");
                stream.AppendFormat("\trastemp = {0}.{1};\n", m_tevRasTable[(int)tevOrder.ChannelId], rasSwapModeTable[rasSwapTable.A]); // ToDo: No idea if this works.
            }

            if (tevOrder.TexCoordId != GXTexCoordSlot.Null)
            {
                int texmap = tevOrder.TexMap;
                if (true /* !bHasIndStage*/)
                {
                    if (bHasTexCoord)
                    {
                        stream.AppendFormat("\ttevcoord.xy = TexGen{0}.xy;\n", texcoord);
                    }
                    else
                    {
                        stream.AppendFormat("\ttevcoord.xy = vec2(0, 0);\n");
                    }
                }

                string texswap = texSwapModeTable[texSwapTable.A]; // Again, no idea if this works.

                stream.Append("\ttextemp = ");
                SampleTexture(stream, "vec2(tevcoord.xy)", texswap, texmap);
            }
            else
            {
                stream.AppendFormat("\ttextemp = vec4(1,1,1,1); // tevOrder specified no texture!\n");
            }

            if (tevStage.ColorIn[0] == GXCombineColorInput.Konst || tevStage.ColorIn[1] == GXCombineColorInput.Konst ||
                tevStage.ColorIn[2] == GXCombineColorInput.Konst || tevStage.ColorIn[3] == GXCombineColorInput.Konst ||
                tevStage.AlphaIn[0] == GXCombineAlphaInput.Konst || tevStage.AlphaIn[1] == GXCombineAlphaInput.Konst ||
                tevStage.AlphaIn[2] == GXCombineAlphaInput.Konst || tevStage.AlphaIn[3] == GXCombineAlphaInput.Konst)
            {
                GXKonstColorSel kc = mat.KonstColorSelectors[stageIndex];
                GXKonstAlphaSel ka = mat.KonstAlphaSelectors[stageIndex];
                stream.AppendFormat("\t// KonstColorSel: {0} KonstAlphaSel: {1}\n", kc, ka);
                stream.AppendFormat("\tkonsttemp = vec4({0}, {1});\n", m_tevKSelTableC[(int)kc], m_tevKSelTableA[(int)ka]);
            }

            stream.AppendFormat("\ttevin_a = vec4({0}, {1});\n", m_tevCInputTable[(int)tevStage.ColorIn[0]], m_tevAInputTable[(int)tevStage.AlphaIn[0]]);
            stream.AppendFormat("\ttevin_b = vec4({0}, {1});\n", m_tevCInputTable[(int)tevStage.ColorIn[1]], m_tevAInputTable[(int)tevStage.AlphaIn[1]]);
            stream.AppendFormat("\ttevin_c = vec4({0}, {1});\n", m_tevCInputTable[(int)tevStage.ColorIn[2]], m_tevAInputTable[(int)tevStage.AlphaIn[2]]);
            stream.AppendFormat("\ttevin_d = vec4({0}, {1});\n", m_tevCInputTable[(int)tevStage.ColorIn[3]], m_tevAInputTable[(int)tevStage.AlphaIn[3]]);

            // COLOR COMBINER
            stream.AppendFormat("\t// Color Combine\n");
            stream.AppendFormat("\t{0} = clamp(", m_tevCOutputTable[(byte)tevStage.ColorRegister]);
            if (tevStage.ColorOp == GXTevOp.Add || tevStage.ColorOp == GXTevOp.Sub)
            {
                WriteTevRegular(stream, "rgb", tevStage.ColorBias, tevStage.ColorOp, tevStage.ColorScale, tevStage.ColorClamp);
            }
            else
            {
                string[] opTable = new string[]
                {
                    "((tevin_a.r > tevin_b.r) ?  tevin_c.rgb : vec3(0,0,0))",                                // GXTevOp::Comp_R8_GT
                    "((tevin_a.r == tevin_b.r) ? tevin_c.rgb : vec3(0,0,0))",                                // GXTevOp::Comp_R8_EQ
                    "((dot(tevin_a.rgb, comp16) >  dot(tevin_b.rgb, comp16)) ? tevin_c.rgb : vec3(0,0,0))",  // GXTevOp::Comp_GR16_GT
                    "((dot(tevin_a.rgb, comp16) == dot(tevin_b.rgb, comp16)) ? tevin_c.rgb : vec3(0,0,0))",  // GXTevOp::Comp_GR16_EQ
                    "((dot(tevin_a.rgb, comp24) >  dot(tevin_b.rgb, comp24)) ? tevin_c.rgb : vec3(0,0,0))",  // GXTevOp::Comp_GR24_GT
                    "((dot(tevin_a.rgb, comp24) == dot(tevin_b.rgb, comp24)) ? tevin_c.rgb : vec3(0,0,0))",  // GXTevOp::Comp_GR24_EQ
                    "(max(sign(tevin_a.rgb - tevin_b.rgb), vec3(0,0,0)) * tevin_c.rgb)",                     // GXTevOp::Comp_RGB8_GT
                    "((vec3(1,1,1) - sign(abs(tevin_a.rgb - tevin_b.rgb))) * tevin_c.rgb)",                  // GXTevOp::Comp_RGB8_EQ
                };

                int index = (int)tevStage.ColorOp - 8;
                stream.AppendFormat("tevin_d.rgb + {0}", opTable[index]);
            }

            if (tevStage.ColorClamp)
            {
                stream.AppendFormat(", vec3(0,0,0), vec3(1,1,1))");
            }
            else
            {
                stream.AppendFormat(", vec3(-1024, -1024, -1024), vec3(1023, 1023, 1023))");
            }
            stream.AppendFormat(";\n");

            // ALPHA COMBINER
            stream.AppendFormat("\t// Alpha Combine\n");
            stream.AppendFormat("\t{0} = clamp(", m_tevAOutputTable[(byte)tevStage.AlphaRegister]);
            if (tevStage.AlphaOp == GXTevOp.Add || tevStage.AlphaOp == GXTevOp.Sub)
            {
                WriteTevRegular(stream, "a", tevStage.AlphaBias, tevStage.AlphaOp, tevStage.AlphaScale, tevStage.AlphaClamp);
            }
            else
            {
                string[] opTable = new string[]
                {
                    "((tevin_a.r > tevin_b.r) ?  tevin_c.a : 0)",                                   // GXTevOp::Comp_R8_GT
                    "((tevin_a.r == tevin_b.r) ? tevin_c.a : 0)",                                   // GXTevOp::Comp_R8_EQ
                    "((dot(tevin_a.rgb, comp16) >  dot(tevin_b.rgb, comp16)) ? tevin_c.a : 0)",     // GXTevOp::Comp_GR16_GT
                    "((dot(tevin_a.rgb, comp16) == dot(tevin_b.rgb, comp16)) ? tevin_c.a : 0)",     // GXTevOp::Comp_GR16_EQ
                    "((dot(tevin_a.rgb, comp24) >  dot(tevin_b.rgb, comp24)) ? tevin_c.a : 0)",     // GXTevOp::Comp_GR24_GT
                    "((dot(tevin_a.rgb, comp24) == dot(tevin_b.rgb, comp24)) ? tevin_c.a : 0)",     // GXTevOp::Comp_GR24_EQ
                    "((tevin_a.a >  tevin_b.a) ? tevin_c.a : 0)",                                   // GXTevOp::Comp_RGB8_GT
                    "((tevin_a.a == tevin_b.a) ? tevin_c.a : 0)",                                   // GXTevOp::Comp_RGB8_EQ
                };

                int index = (int)tevStage.AlphaOp - 8;
                stream.AppendFormat("tevin_d.a + {0}", opTable[index]);
            }

            if (tevStage.AlphaClamp)
            {
                stream.AppendFormat(", 0, 1)");
            }
            else
            {
                stream.AppendFormat(", -1024, 1023)");
            }
            stream.AppendFormat(";\n");
            stream.AppendLine();
        }
Example #7
0
        void ReadMaterial()
        {
            if (clyt.Materials.Count > 0)
            {
                throw new FormatException("Expecting just one mat1 section");
            }

            long baseOffset   = reader.Stream.Position - 8;
            int  numMaterials = reader.ReadInt32();

            while (numMaterials > 0)
            {
                // Read from table and jump to material
                long offset = baseOffset + reader.ReadUInt32();
                reader.Stream.PushToPosition(offset);

                var material = new Material();
                material.Name = reader.ReadString(0x14).Replace("\0", string.Empty);

                for (int i = 0; i < material.TevConstantColors.Length; i++)
                {
                    // TODO: Convert to RGBA
                    material.TevConstantColors[i] = reader.ReadUInt32();
                }

                uint flags           = reader.ReadUInt32();
                uint numTexMap       = flags & 0x3;
                uint numTexMatrix    = (flags >> 2) & 0x3;
                uint numTexCoordGen  = (flags >> 4) & 0x3;
                uint numTevStage     = (flags >> 6) & 0x7;
                bool hasAlphaCompare = ((flags >> 9) & 0x01) == 1;
                bool hasBlendMode    = ((flags >> 10) & 0x01) == 1;
                material.UseTextureOnly = ((flags >> 11) & 0x01) == 1;
                bool separateBlendMode  = ((flags >> 12) & 0x01) == 1;
                bool hasIndirectParam   = ((flags >> 13) & 0x01) == 1;
                uint numProjTexGenParam = (flags >> 14) & 0x03;
                bool hasFontShadowParam = ((flags >> 16) & 0x01) == 1;

                for (int i = 0; i < numTexMap; i++)
                {
                    var entry = new TextureMapEntry();
                    entry.Index = reader.ReadUInt16();

                    byte flag1 = reader.ReadByte();
                    byte flag2 = reader.ReadByte();
                    entry.WrapS     = (WrapMode)(flag1 & 0x3);
                    entry.WrapT     = (WrapMode)(flag2 & 0x3);
                    entry.MinFilter = (TextureFilter)((flag1 >> 2) & 0x3);
                    entry.MagFilter = (TextureFilter)((flag2 >> 2) & 0x3);

                    material.TexMapEntries.Add(entry);
                }

                for (int i = 0; i < numTexMatrix; i++)
                {
                    var entry = new TextureMatrixEntry();
                    entry.Translation = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    entry.Rotation    = reader.ReadSingle();
                    entry.Scale       = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                    material.TexMatrixEntries.Add(entry);
                }

                for (int i = 0; i < numTexCoordGen; i++)
                {
                    material.TextureCoordGen.Add(reader.ReadSingle());
                }

                for (int i = 0; i < numTevStage; i++)
                {
                    var stage = new TevStage();
                    stage.Param1 = reader.ReadUInt32();
                    stage.Param2 = reader.ReadUInt32();
                    stage.Param3 = reader.ReadUInt32();
                    material.TevStages.Add(stage);
                }

                if (hasAlphaCompare)
                {
                    material.AlphaCompare = new AlphaCompare {
                        Function  = reader.ReadUInt32(),
                        Reference = reader.ReadSingle(),
                    };
                }

                if (hasBlendMode)
                {
                    material.ColorBlendMode = new BlendMode {
                        BlendOperator     = reader.ReadByte(),
                        SourceFactor      = reader.ReadByte(),
                        DestinationFactor = reader.ReadByte(),
                        LogicOperator     = reader.ReadByte(),
                    };
                }

                if (separateBlendMode)
                {
                    material.AlphaBlendMode = new BlendMode {
                        BlendOperator     = reader.ReadByte(),
                        SourceFactor      = reader.ReadByte(),
                        DestinationFactor = reader.ReadByte(),
                        LogicOperator     = reader.ReadByte(),
                    };
                }

                if (hasIndirectParam || numProjTexGenParam > 0 || hasFontShadowParam)
                {
                    Console.WriteLine($"WARN: Material ({material.Name}) with unknown sections.");
                }

                clyt.Materials.Add(material);
                reader.Stream.PopPosition();
                numMaterials--;
            }
        }
Example #8
0
                public Material(ref BinaryStream s)
                {
                    name = Encoding.ASCII.GetString(s.ReadBytes(28)).Replace("\0", "");

                    flag    = s.ReadUInt32();
                    unknown = s.ReadUInt32();

                    byte[] black = s.ReadBytes(4), white = s.ReadBytes(4);
                    blackColor = Color.FromArgb(black[3], black[0], black[1], black[2]);
                    whiteColor = Color.FromArgb(white[3], white[0], black[1], black[2]);

                    texMapCount                    = (uint)(flag & 0x03);
                    texSRTCount                    = (uint)((flag >> 2) & 0x03);
                    texCoordGenCount               = (uint)((flag >> 4) & 0x03);
                    tevStageCount                  = (uint)((flag >> 6) & 0x07);
                    hasAlphaCompare                = ((flag >> 9) & 0x01) == 1;
                    hasBlendMode                   = ((flag >> 10) & 0x01) == 1;
                    useTextureOnly                 = ((flag >> 11) & 0x01) == 1;
                    seperateBlendMode              = ((flag >> 12) & 0x01) == 1;
                    hasIndirectParameter           = ((flag >> 14) & 0x01) == 1;
                    projectionTexGenParameterCount = (uint)((flag >> 15) & 0x03);
                    hasFontShadowParameter         = ((flag >> 17) & 0x01) == 1;
                    thresholingAlphaInterpolation  = ((flag >> 18) & 0x01) == 1;

                    texMaps = new TexMap[texMapCount];
                    for (int i = 0; i < texMapCount; i++)
                    {
                        texMaps[i] = new TexMap(ref s);
                    }

                    texSRTs = new TexSRT[texSRTCount];
                    for (int i = 0; i < texSRTCount; i++)
                    {
                        texSRTs[i] = new TexSRT(ref s);
                    }

                    texCoords = new TexCoordGen[texCoordGenCount];
                    for (int i = 0; i < texCoordGenCount; i++)
                    {
                        texCoords[i] = new TexCoordGen(ref s);
                    }

                    tevStages = new TevStage[tevStageCount];
                    for (int i = 0; i < tevStageCount; i++)
                    {
                        tevStages[i] = new TevStage(ref s);
                    }

                    if (hasAlphaCompare)
                    {
                        alphaCompare = new AlphaCompare(ref s);
                    }

                    if (hasBlendMode)
                    {
                        blendMode = new BlendMode(ref s);
                    }

                    if (seperateBlendMode)
                    {
                        blendAlpha = new BlendMode(ref s);
                    }

                    if (hasIndirectParameter)
                    {
                        indirectParameter = new IndirectParameter(ref s);
                    }

                    projectionTexGenParameters = new ProjectionTexGenParameters[projectionTexGenParameterCount];
                    for (int i = 0; i < projectionTexGenParameterCount; i++)
                    {
                        projectionTexGenParameters[i] = new ProjectionTexGenParameters(ref s);
                    }

                    if (hasFontShadowParameter)
                    {
                        fontShadowParameter = new FontShadowParameter(ref s);
                    }

                    //System.Windows.Forms.MessageBox.Show($"[{s.BaseStream.Position}] mat end");
                }