예제 #1
0
 public FMAT(BFRES bfres, FMDL fmdl, Model model, Material material)
 {
     Init();
     ParentFile       = bfres;
     Material         = material;
     ParentModel      = model;
     ParentBfresModel = fmdl;
     Reload(material);
 }
        /// <summary>
        /// Loads the material renderer for the first time.
        /// </summary>
        /// <returns></returns>
        public override void TryLoadShader(BFRES bfres, FMDL fmdl, FSHP mesh, BfresMeshAsset meshAsset)
        {
            var sharcfb = TryLoadShaderArchive(bfres,
                                               mesh.Material.ShaderArchive,
                                               mesh.Material.ShaderModel);

            if (sharcfb == null)
            {
                return;
            }

            OnLoad(sharcfb, fmdl, mesh, meshAsset);
        }
예제 #3
0
        public FSHP(ResFile resFile, FSKL skeleton, FMDL model, Shape shape)
        {
            ParentFile      = resFile;
            ParentModel     = model;
            Shape           = shape;
            ParentSkeleton  = skeleton;
            BoneIndex       = shape.BoneIndex;
            VertexBuffer    = model.Model.VertexBuffers[shape.VertexBufferIndex];
            VertexSkinCount = shape.VertexSkinCount;

            Name = shape.Name;

            UpdateVertexBuffer();
            UpdatePolygonGroups();
        }
        public ModelFolder(BFRES bfres, ResFile resFile, ResDict <Model> resDict)
        {
            foreach (Model model in resDict.Values)
            {
                var node = new BfresNodeBase(model.Name);
                node.Icon = "/Images/Model.png";
                AddChild(node);

                var fmdl = new FMDL(node, bfres, model);
                node.Tag = fmdl;
                bfres.Models.Add(fmdl);

                node.AddChild(new BfresNodeBase("Meshes"));
                node.AddChild(new MaterialFolder("Materials"));
                node.AddChild(new BfresNodeBase("Skeleton"));

                foreach (FSHP mesh in fmdl.Meshes)
                {
                    var meshNode = new BfresNodeBase(mesh.Name)
                    {
                        Tag  = mesh,
                        Icon = "/Images/Mesh.png"
                    };
                    mesh.ParentNode   = meshNode;
                    mesh.MeshSelected = (o, s) => {
                        meshNode.IsSelected = (bool)o;
                    };
                    node.Children[0].AddChild(meshNode);
                }

                foreach (FMAT mat in fmdl.Materials)
                {
                    var matNode = new BfresNodeBase(mat.Name)
                    {
                        Tag  = mat,
                        Icon = ((FMAT)mat).Icon,
                    };
                    mat.ParentNode = matNode;
                    node.Children[1].AddChild(matNode);
                }
                foreach (var bone in ((FSKL)fmdl.Skeleton).CreateBoneHierarchy())
                {
                    node.Children[2].AddChild(bone);
                }
            }
        }
        /// <summary>
        /// Loads the material renderer for the first time.
        /// </summary>
        /// <returns></returns>
        public override void TryLoadShader(BFRES bfres, FMDL fmdl, FSHP mesh, BfresMeshAsset meshAsset)
        {
            var bfsha = TryLoadShaderArchive(bfres,
                                             mesh.Material.ShaderArchive,
                                             mesh.Material.ShaderModel);

            if (bfsha == null)
            {
                return;
            }

            var shaderModel = bfsha.ShaderModels.Values.FirstOrDefault(x => x.Name == mesh.Material.ShaderModel);

            if (shaderModel != null)
            {
                OnLoad(shaderModel, fmdl, mesh, meshAsset);
            }
        }
예제 #6
0
        static void LoadBoneSelector(FMDL model, FSHP shape)
        {
            string selecteBone = model.Skeleton.Bones[shape.BoneIndex].Name;

            if (ImGui.BeginCombo("Bone", selecteBone))
            {
                for (int i = 0; i < model.Skeleton.Bones.Count; i++)
                {
                    bool isSelected = model.Skeleton.Bones[i].Name == selecteBone;
                    if (ImGui.Selectable(model.Skeleton.Bones[i].Name, isSelected))
                    {
                        shape.BoneIndex = (ushort)i;
                    }

                    if (isSelected)
                    {
                        ImGui.SetItemDefaultFocus();
                    }
                }
                ImGui.EndCombo();
            }
        }
예제 #7
0
        static void LoadMaterialSelector(FMDL model, FSHP shape)
        {
            string selectedMaterial = model.Materials[shape.Shape.MaterialIndex].Name;

            if (ImGui.BeginCombo("Material", selectedMaterial))
            {
                for (int i = 0; i < model.Materials.Count; i++)
                {
                    bool isSelected = model.Materials[i].Name == selectedMaterial;
                    if (ImGui.Selectable(model.Materials[i].Name, isSelected))
                    {
                        shape.Shape.MaterialIndex = (ushort)i;
                        shape.Material            = (FMAT)model.Materials[i];
                    }

                    if (isSelected)
                    {
                        ImGui.SetItemDefaultFocus();
                    }
                }
                ImGui.EndCombo();
            }
        }
        /// <summary>
        /// Called once when the renderer can be loaded from a given shader model and mesh.
        /// </summary>
        public void OnLoad(BfshaLibrary.ShaderModel shaderModel, FMDL model, FSHP mesh, BfresMeshAsset meshAsset)
        {
            var shapeBlock = shaderModel.UniformBlocks.Values.FirstOrDefault(x =>
                                                                             x.Type == BfshaLibrary.UniformBlock.BlockType.Shape);

            //Models may update the shape block outside the shader if the shape block is unused so update mesh matrix manually
            if (shapeBlock.Size == 0 && mesh.VertexSkinCount == 0)
            {
                mesh.UpdateVertexBuffer(true);
                meshAsset.UpdateVertexBuffer();
            }

            //Assign some necessary data
            meshAsset.MaterialAsset = this;

            //Force reload from material editing
            mesh.ShaderReload += delegate
            {
                Console.WriteLine($"Reloading shader program {meshAsset.Name}");
                this.ReloadRenderState(meshAsset);
                this.ReloadProgram(meshAsset);
                mesh.HasValidShader = this.HasValidProgram;

                Console.WriteLine($"Program Validation: {this.HasValidProgram}");
                this.UpdateShader = true;
            };

            ShaderModel  = shaderModel;
            MaterialData = mesh.Material;
            ParentModel  = model;
            //Load mesh function for loading the custom shader for the first time
            LoadMesh(meshAsset);
            ReloadRenderState(meshAsset);
            ReloadProgram(meshAsset);

            var bfresMaterial = (FMAT)this.MaterialData;

            //Remap the vertex layouts from shader model attributes
            if (!IsSwitch)
            {
                //GX2 shaders can be directly mapped via string and location searches
                Dictionary <string, string> attributeLocations = new Dictionary <string, string>();
                for (int i = 0; i < shaderModel.Attributes.Count; i++)
                {
                    string key = shaderModel.Attributes.GetKey(i);
                    attributeLocations.Add(key, $"{key}_0_0");
                }
                meshAsset.UpdateVaoAttributes(attributeLocations);
            }
            else
            {
                Dictionary <string, int> attributeLocations = new Dictionary <string, int>();
                for (int i = 0; i < shaderModel.Attributes.Count; i++)
                {
                    string key      = shaderModel.Attributes.GetKey(i);
                    int    location = shaderModel.Attributes[i].Location;
                    attributeLocations.Add(key, location);
                }
                meshAsset.UpdateVaoAttributes(attributeLocations);
            }
        }
        /// <summary>
        /// Called once when the renderer can be loaded from a given shader model and mesh.
        /// </summary>
        public void OnLoad(SHARCFB sharcfb, FMDL model, FSHP mesh, BfresMeshAsset meshAsset)
        {
            ShaderModel = sharcfb.Programs.FirstOrDefault(x => x.Name == mesh.Material.ShaderModel);
            if (ShaderModel == null)
            {
                Console.WriteLine($"Failed to find program! {mesh.Material.ShaderModel}");
                return;
            }

            //Assign some necessary data
            meshAsset.MaterialAsset = this;

            //Force reload from material editing
            mesh.ShaderReload += delegate
            {
                Console.WriteLine($"Reloading shader program {meshAsset.Name}");
                this.ReloadRenderState(meshAsset);
                this.ReloadProgram(meshAsset);
                mesh.HasValidShader = this.HasValidProgram;

                Console.WriteLine($"Program Validation: {this.HasValidProgram}");
                this.UpdateShader = true;
            };

            MaterialData = mesh.Material;
            ParentModel  = model;
            //Load mesh function for loading the custom shader for the first time
            LoadMesh(meshAsset);
            ReloadRenderState(meshAsset);
            ReloadProgram(meshAsset);

            var gx2ShaderVertex = (GX2VertexShader)ShaderModel.GetGX2VertexShader(BinaryIndex);
            var bfresMaterial   = (FMAT)this.MaterialData;

            //Remap the vertex layouts from shader model attributes
            Dictionary <string, string> attributeLocations = new Dictionary <string, string>();

            for (int i = 0; i < gx2ShaderVertex.Attributes.Count; i++)
            {
                var symbol = ShaderModel.AttributeVariables.symbols.FirstOrDefault(
                    x => x.Name == gx2ShaderVertex.Attributes[i].Name);

                if (symbol == null)
                {
                    continue;
                }

                var attribVar   = gx2ShaderVertex.Attributes[i];
                var arrayCount  = Math.Max(1, attribVar.Count);
                var streamCount = attribVar.GetStreamCount();

                if (arrayCount > 1 || streamCount > 1)
                {
                    throw new Exception("Multiple attribute streams and variable counts not supported!");
                }

                attributeLocations.Add(symbol.SymbolName, $"{symbol.Name}_0_0");
            }

            meshAsset.UpdateVaoAttributes(attributeLocations);
        }
예제 #10
0
 /// <summary>
 /// Loads the material renderer for the first time.
 /// </summary>
 public virtual void TryLoadShader(BFRES bfres, FMDL fmdl, FSHP mesh, BfresMeshAsset meshAsset)
 {
 }
        public BfresModelAsset(BFRES bfres, BfresRender render, FMDL model)
        {
            ParentRender = render;
            ModelData    = model;
            Name         = model.Name;

            List <Vector3> positons = new List <Vector3>();

            foreach (FSHP mesh in model.Meshes)
            {
                //Create a mesh asset for rendering onto
                var meshAsset = new BfresMeshAsset(mesh);
                Meshes.Add(meshAsset);

                foreach (var customRender in BfshaRenders)
                {
                    var materialRender = (ShaderRenderBase)Activator.CreateInstance(customRender);
                    if (materialRender.UseRenderer(
                            mesh.Material,
                            mesh.Material.ShaderArchive,
                            mesh.Material.ShaderModel))
                    {
                        materialRender.TryLoadShader(bfres, ResModel, mesh, meshAsset);
                        break;
                    }
                }

                //Check for the GX2 shader decompiler as needed for Wii U games
                if (System.IO.File.Exists("GFD\\gx2shader-decompiler.exe"))
                {
                    foreach (var customRender in SharcfbRenders)
                    {
                        var materialRender = (SharcFBRenderer)Activator.CreateInstance(customRender);
                        if (materialRender.UseRenderer(
                                mesh.Material,
                                mesh.Material.ShaderArchive,
                                mesh.Material.ShaderModel))
                        {
                            materialRender.TryLoadShader(bfres, ResModel, mesh, meshAsset);
                            break;
                        }
                    }
                }

                mesh.Material.MaterialAsset = (BfresMaterialAsset)meshAsset.MaterialAsset;

                ((BfresMaterialAsset)meshAsset.MaterialAsset).ParentRenderer = render;
                ((BfresMaterialAsset)meshAsset.MaterialAsset).ParentModel    = this.ResModel;

                //Calculate total boundings
                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    positons.Add(mesh.Vertices[i].Position);
                }
            }
            SkeletonRenderer = new SkeletonRenderer(model.Skeleton);

            //Calculate the total bounding sphere
            BoundingSphere = GLFrameworkEngine.Utils.BoundingSphereGenerator.GenerateBoundingSphere(positons);
            positons.Clear();
        }