public void Render(FSHP shape) { var model = shape.ParentModel; if (ImGui.CollapsingHeader("Shape Info", ImGuiTreeNodeFlags.DefaultOpen)) { ImGuiHelper.InputFromText("Name", shape, "Name", 200); //Doesn't need a direct property bind as property is readonly var skinCount = (int)shape.VertexSkinCount; ImGui.InputInt("Vertex Skin Count", ref skinCount, 0, 0, ImGuiInputTextFlags.ReadOnly); LoadLODSelector(shape); } if (ImGui.CollapsingHeader("Material Info", ImGuiTreeNodeFlags.DefaultOpen)) { LoadMaterialSelector(model, shape); } if (ImGui.CollapsingHeader("Bone Info", ImGuiTreeNodeFlags.DefaultOpen)) { LoadBoneSelector(model, shape); } if (ImGui.CollapsingHeader("Vertex Buffer Info", ImGuiTreeNodeFlags.DefaultOpen)) { } if (ImGui.CollapsingHeader("LOD Info")) { } if (ImGui.CollapsingHeader("Shape Morph Info")) { } }
public BfresMeshAsset(FSHP fshp) { Shape = fshp; MaterialAsset = new BfresMaterialAsset(); this.Name = fshp.Name; this.Material = Shape.Material; this.SkinCount = (int)fshp.VertexSkinCount; this.BoneIndex = fshp.BoneIndex; fshp.UpdateViewBuffer = () => { UpdateVertexData = true; }; CalculateBounding(); //Load vaos int[] buffers = new int[2]; GL.GenBuffers(2, buffers); int indexBuffer = buffers[0]; int vaoBuffer = buffers[1]; Vbo = vaoBuffer; Ibo = indexBuffer; vao = new VertexBufferObject(vaoBuffer, indexBuffer); defaultVao = new VertexBufferObject(vaoBuffer, indexBuffer); KeyGroups = fshp.LoadKeyGroups(); Attributes = Shape.LoadGLAttributes(); UpdateVertexBuffer(); UpdateDefaultVaoAttributes(); }
public void LoadEditor(FSHP mesh) { var material = mesh.Material; //MeshEditor.Render(mesh); MaterialEditor.LoadEditorMenus(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); }
/// <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); } }
static void LoadLODSelector(FSHP shape) { var displayLOD = shape.DisplayLOD; if (ImGui.BeginCombo("Display LOD", $"Mesh{displayLOD}")) { for (int i = 0; i < shape.PolygonGroups.Count; i++) { bool isSelected = displayLOD == i; if (ImGui.Selectable($"Mesh{i}", isSelected)) { shape.DisplayLOD = i; } if (isSelected) { ImGui.SetItemDefaultFocus(); } } ImGui.EndCombo(); } }
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(); } }
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); }
/// <summary> /// Loads the material renderer for the first time. /// </summary> public virtual void TryLoadShader(BFRES bfres, FMDL fmdl, FSHP mesh, BfresMeshAsset meshAsset) { }