diff --git a/.vs/Switch_Toolbox/v15/.suo b/.vs/Switch_Toolbox/v15/.suo index b8907ae0..77f0d499 100644 Binary files a/.vs/Switch_Toolbox/v15/.suo and b/.vs/Switch_Toolbox/v15/.suo differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide index d6e1040a..dc5ad167 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm index 55f89ca0..3eef1be4 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal index 8669fc12..267103b5 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal differ diff --git a/Switch_FileFormatsMain/FileFormats/Archives/ME01.cs b/Switch_FileFormatsMain/FileFormats/Archives/ME01.cs index 6cdcf92e..f3cf4456 100644 --- a/Switch_FileFormatsMain/FileFormats/Archives/ME01.cs +++ b/Switch_FileFormatsMain/FileFormats/Archives/ME01.cs @@ -129,7 +129,10 @@ namespace FirstPlugin writer.Write(Alignment); writer.Write(new uint[files.Count]); //Save space for offsets for (int i = 0; i < files.Count; i++) + { + files[i].SaveFileFormat(); writer.Write(files[i].FileData.Length); + } for (int i = 0; i < files.Count; i++) { @@ -155,7 +158,6 @@ namespace FirstPlugin { Offsets[i] = (uint)(writer.Position - DataStart); - files[i].SaveFileFormat(); writer.Write(files[i].FileData); Align(writer, (int)Alignment); } diff --git a/Switch_FileFormatsMain/FileFormats/Archives/TMPK.cs b/Switch_FileFormatsMain/FileFormats/Archives/TMPK.cs index 2348f401..f160509b 100644 --- a/Switch_FileFormatsMain/FileFormats/Archives/TMPK.cs +++ b/Switch_FileFormatsMain/FileFormats/Archives/TMPK.cs @@ -103,6 +103,8 @@ namespace FirstPlugin writer.Write(0); for (int i = 0; i < files.Count; i++) { + files[i].SaveFileFormat(); + files[i]._posHeader = writer.Position; writer.Write(uint.MaxValue); writer.Write(uint.MaxValue); @@ -119,7 +121,6 @@ namespace FirstPlugin SetAlignment(writer, files[i].FileName); writer.WriteUint32Offset(files[i]._posHeader + 4); - files[i].SaveFileFormat(); writer.Write(files[i].FileData); } writer.Close(); diff --git a/Switch_FileFormatsMain/FileFormats/GMX/GMX.cs b/Switch_FileFormatsMain/FileFormats/GMX/GMX.cs index 42578b63..10d2744a 100644 --- a/Switch_FileFormatsMain/FileFormats/GMX/GMX.cs +++ b/Switch_FileFormatsMain/FileFormats/GMX/GMX.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using Switch_Toolbox.Library; using Switch_Toolbox.Library.IO; using Switch_Toolbox.Library.Rendering; +using Switch_Toolbox.Library.Forms; namespace FirstPlugin { @@ -39,19 +40,103 @@ namespace FirstPlugin } } + Viewport viewport + { + get + { + var editor = LibraryGUI.Instance.GetObjectEditor(); + return editor.GetViewport(); + } + set + { + var editor = LibraryGUI.Instance.GetObjectEditor(); + editor.LoadViewport(value); + } + } + + bool DrawablesLoaded = false; + public override void OnClick(TreeView treeView) + { + if (Runtime.UseOpenGL) + { + if (viewport == null) + { + viewport = new Viewport(ObjectEditor.GetDrawableContainers()); + viewport.Dock = DockStyle.Fill; + } + + if (!DrawablesLoaded) + { + ObjectEditor.AddContainer(DrawableContainer); + DrawablesLoaded = true; + } + + viewport.ReloadDrawables(DrawableContainer); + LibraryGUI.Instance.LoadEditor(viewport); + + viewport.Text = Text; + } + } + public Header GMXHeader; + public GMX_Renderer Renderer; + + public DrawableContainer DrawableContainer = new DrawableContainer(); public void Load(System.IO.Stream stream) { CanSave = true; + //Set renderer + Renderer = new GMX_Renderer(); + DrawableContainer.Name = FileName; + DrawableContainer.Drawables.Add(Renderer); + + //Read file GMXHeader = new Header(); GMXHeader.Read(new FileReader(stream)); for (int i = 0; i < GMXHeader.Meshes.Count; i++) { - var node = new TreeNode($"Mesh ({i})"); - node.Tag = GMXHeader.Meshes[i]; - Nodes.Add(node); + var renderedMesh = new GenericRenderedObject(); + renderedMesh.Text = $"Mesh ({i})"; + renderedMesh.ImageKey = "mesh"; + renderedMesh.SelectedImageKey = "mesh"; + renderedMesh.Checked = true; + + if (GMXHeader.Meshes[i].VertexGroup != null) + { + renderedMesh.vertices = GMXHeader.Meshes[i].VertexGroup.Vertices; + } + + if (GMXHeader.Meshes[i].IndexGroup != null) + { + renderedMesh.lodMeshes = new List(); + var msh = new STGenericObject.LOD_Mesh(); + msh.PrimitiveType = STPolygonType.Triangle; + msh.FirstVertex = 0; + + /* int VertexID = 0; + for (int f = 0; f < GMXHeader.Meshes[i].VertexCount; f+= 3) + { + msh.faces.AddRange(new List() { VertexID + 2, VertexID + 1, VertexID }); + VertexID++; + }*/ + + for (int f = 0; f < GMXHeader.Meshes[i].IndexGroup.Indices.Length / 3; f++) + { + ushort face0 = GMXHeader.Meshes[i].IndexGroup.Indices[f + 0]; + ushort face1 = GMXHeader.Meshes[i].IndexGroup.Indices[f + 1]; + ushort face2 = GMXHeader.Meshes[i].IndexGroup.Indices[f + 2]; + + msh.faces.AddRange(new List() { face2, face1, face0, }); + } + + renderedMesh.lodMeshes.Add(msh); + } + + renderedMesh.Tag = GMXHeader.Meshes[i]; + Nodes.Add(renderedMesh); + Renderer.Meshes.Add(renderedMesh); } } public void Unload() @@ -99,7 +184,7 @@ namespace FirstPlugin break; case "INDX": INDX indexGrp = new INDX(); - indexGrp.Read(reader); + indexGrp.Read(reader, GetLastMesh()); GetLastMesh().IndexGroup = indexGrp; break; case "VMAP": @@ -140,6 +225,7 @@ namespace FirstPlugin PADX padding = new PADX(); + Console.WriteLine("Saving GMX"); writer.WriteSignature("GMX2"); writer.Write(HeaderSize); for (int i = 0; i < Meshes.Count; i++) @@ -171,6 +257,8 @@ namespace FirstPlugin } writer.WriteSignature("ENDX"); writer.Write(8); //Last section size + writer.Close(); + writer.Dispose(); } public class VERT @@ -194,6 +282,35 @@ namespace FirstPlugin Vertices.Add(vert); } } + else if (mesh.VertexSize == 12) + { + for (int v = 0; v < mesh.VertexCount; v++) + { + Vertex vert = new Vertex(); + vert.pos = reader.ReadVec3(); + Vertices.Add(vert); + } + } + else if (mesh.VertexSize == 20) + { + for (int v = 0; v < mesh.VertexCount; v++) + { + Vertex vert = new Vertex(); + vert.pos = reader.ReadVec3(); + vert.uv0 = reader.ReadVec2(); + Vertices.Add(vert); + } + } + else if (mesh.VertexSize == 24) + { + for (int v = 0; v < mesh.VertexCount; v++) + { + Vertex vert = new Vertex(); + vert.pos = reader.ReadVec3(); + vert.nrm = reader.ReadVec3(); + Vertices.Add(vert); + } + } else if (mesh.VertexSize == 36) { for (int v = 0; v < mesh.VertexCount; v++) @@ -205,7 +322,6 @@ namespace FirstPlugin vert.uv0 = reader.ReadVec2(); Vertices.Add(vert); Unknowns.Add(Unknown); - Console.WriteLine($"Unknown {Unknown}"); } } else @@ -287,14 +403,13 @@ namespace FirstPlugin { public ushort[] Indices; - public void Read(FileReader reader) + public void Read(FileReader reader, MESH mesh) { reader.ReadSignature(4, "INDX"); uint SectionSize = reader.ReadUInt32(); - uint FaceCount = (SectionSize - 8) / sizeof(ushort); - Indices = new ushort[FaceCount]; - for (int i = 0; i < FaceCount; i++) + Indices = new ushort[mesh.FaceCount]; + for (int i = 0; i < mesh.FaceCount; i++) { Indices[i] = reader.ReadUInt16(); } @@ -331,7 +446,7 @@ namespace FirstPlugin writer.WriteSignature("VMAP"); writer.Write(Indices.Length * sizeof(ushort) + 8); for (int i = 0; i < Indices.Length; i++) - writer.Write(Indices[i]); + writer.Write(Indices[i]); } } diff --git a/Switch_FileFormatsMain/FileFormats/MKAGPDX/MKAGPDX_Model.cs b/Switch_FileFormatsMain/FileFormats/MKAGPDX/MKAGPDX_Model.cs index 8d690771..6c2e8845 100644 --- a/Switch_FileFormatsMain/FileFormats/MKAGPDX/MKAGPDX_Model.cs +++ b/Switch_FileFormatsMain/FileFormats/MKAGPDX/MKAGPDX_Model.cs @@ -95,7 +95,7 @@ namespace FirstPlugin } Skeleton.bones.AddRange(((STSkeleton)model.DrawableContainer.Drawables[0]).bones); - Objects.AddRange(((Renderer)model.DrawableContainer.Drawables[1]).Meshes); + Objects.AddRange(((GenericModelRenderer)model.DrawableContainer.Drawables[1]).Meshes); model.Unload(); } @@ -173,20 +173,20 @@ namespace FirstPlugin var model = new STGenericModel(); model.Materials = Materials; - model.Objects = ((Renderer)DrawableContainer.Drawables[1]).Meshes; + model.Objects = ((GenericModelRenderer)DrawableContainer.Drawables[1]).Meshes; assimp.SaveFromModel(model, FileName, new List(), ((STSkeleton)DrawableContainer.Drawables[0])); } public void Unload() { - foreach (var mesh in ((Renderer)DrawableContainer.Drawables[1]).Meshes) + foreach (var mesh in ((GenericModelRenderer)DrawableContainer.Drawables[1]).Meshes) { mesh.vertices.Clear(); mesh.faces.Clear(); mesh.display = new int[0]; } - ((Renderer)DrawableContainer.Drawables[1]).Meshes.Clear(); + ((GenericModelRenderer)DrawableContainer.Drawables[1]).Meshes.Clear(); DrawableContainer.Drawables.Clear(); DrawableContainer = null; @@ -202,302 +202,6 @@ namespace FirstPlugin return null; } - public struct DisplayVertex - { - // Used for rendering. - public Vector3 pos; - public Vector3 nrm; - public Vector3 tan; - public Vector2 uv; - public Vector4 col; - public Vector4 node; - public Vector4 weight; - public Vector2 uv2; - public Vector2 uv3; - - public static int Size = 4 * (3 + 3 + 3 + 2 + 4 + 4 + 4 + 2 + 2); - } - - - public class MeshWrapper : STGenericObject - { - public int[] display; - public int DisplayId; - - public List CreateDisplayVertices() - { - display = lodMeshes[DisplayLODIndex].getDisplayFace().ToArray(); - - List displayVertList = new List(); - - if (lodMeshes[DisplayLODIndex].faces.Count <= 3) - return displayVertList; - - foreach (Vertex v in vertices) - { - DisplayVertex displayVert = new DisplayVertex() - { - pos = v.pos, - nrm = v.nrm, - tan = v.tan.Xyz, - col = v.col, - uv = v.uv0, - uv2 = v.uv1, - uv3 = v.uv2, - node = new Vector4( - v.boneIds.Count > 0 ? v.boneIds[0] : -1, - v.boneIds.Count > 1 ? v.boneIds[1] : -1, - v.boneIds.Count > 2 ? v.boneIds[2] : -1, - v.boneIds.Count > 3 ? v.boneIds[3] : -1), - weight = new Vector4( - v.boneWeights.Count > 0 ? v.boneWeights[0] : 0, - v.boneWeights.Count > 1 ? v.boneWeights[1] : 0, - v.boneWeights.Count > 2 ? v.boneWeights[2] : 0, - v.boneWeights.Count > 3 ? v.boneWeights[3] : 0), - }; - - displayVertList.Add(displayVert); - - /* Console.WriteLine($"---------------------------------------------------------------------------------------"); - Console.WriteLine($"Position {displayVert.pos.X} {displayVert.pos.Y} {displayVert.pos.Z}"); - Console.WriteLine($"Normal {displayVert.nrm.X} {displayVert.nrm.Y} {displayVert.nrm.Z}"); - Console.WriteLine($"Tanget {displayVert.tan.X} {displayVert.tan.Y} {displayVert.tan.Z}"); - Console.WriteLine($"Color {displayVert.col.X} {displayVert.col.Y} {displayVert.col.Z} {displayVert.col.W}"); - Console.WriteLine($"UV Layer 1 {displayVert.uv.X} {displayVert.uv.Y}"); - Console.WriteLine($"UV Layer 2 {displayVert.uv2.X} {displayVert.uv2.Y}"); - Console.WriteLine($"UV Layer 3 {displayVert.uv3.X} {displayVert.uv3.Y}"); - Console.WriteLine($"Bone Index {displayVert.node.X} {displayVert.node.Y} {displayVert.node.Z} {displayVert.node.W}"); - Console.WriteLine($"Weights {displayVert.weight.X} {displayVert.weight.Y} {displayVert.weight.Z} {displayVert.weight.W}"); - Console.WriteLine($"---------------------------------------------------------------------------------------");*/ - } - - return displayVertList; - } - - } - - public class Renderer : AbstractGlDrawable - { - public Vector3 Max = new Vector3(0); - public Vector3 Min = new Vector3(0); - - public List SelectedTypes = new List(); - - public Vector3 position = new Vector3(0, 0, 0); - - protected bool Selected = false; - protected bool Hovered = false; - - // public override bool IsSelected() => Selected; - // public override bool IsSelected(int partIndex) => Selected; - - public bool IsHovered() => Selected; - - // gl buffer objects - int vbo_position; - int ibo_elements; - - public List Meshes = new List(); - - private void GenerateBuffers() - { - GL.GenBuffers(1, out vbo_position); - GL.GenBuffers(1, out ibo_elements); - } - - public void Destroy() - { - GL.DeleteBuffer(vbo_position); - GL.DeleteBuffer(ibo_elements); - } - - public void UpdateVertexData() - { - if (!Runtime.OpenTKInitialized) - return; - - DisplayVertex[] Vertices; - int[] Faces; - - int poffset = 0; - int voffset = 0; - List Vs = new List(); - List Ds = new List(); - foreach (var m in Meshes) - { - m.Offset = poffset * 4; - List pv = m.CreateDisplayVertices(); - Vs.AddRange(pv); - - for (int i = 0; i < m.lodMeshes[m.DisplayLODIndex].displayFaceSize; i++) - { - Ds.Add(m.display[i] + voffset); - } - poffset += m.lodMeshes[m.DisplayLODIndex].displayFaceSize; - voffset += pv.Count; - } - - // Binds - Vertices = Vs.ToArray(); - Faces = Ds.ToArray(); - - // Bind only once! - GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Length * DisplayVertex.Size), Vertices, BufferUsageHint.StaticDraw); - - GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements); - GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(Faces.Length * sizeof(int)), Faces, BufferUsageHint.StaticDraw); - - LibraryGUI.Instance.UpdateViewport(); - } - - public ShaderProgram defaultShaderProgram; - - public override void Prepare(GL_ControlModern control) - { - string pathFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "MKAGPDX") + "\\MKAGPDX_Model.frag"; - string pathVert = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "MKAGPDX") + "\\MKAGPDX_Model.vert"; - - var defaultFrag = new FragmentShader(File.ReadAllText(pathFrag)); - var defaultVert = new VertexShader(File.ReadAllText(pathVert)); - - defaultShaderProgram = new ShaderProgram(defaultFrag, defaultVert, control); - } - - public override void Prepare(GL_ControlLegacy control) - { - } - - private void CheckBuffers() - { - if (!Runtime.OpenTKInitialized) - return; - - bool buffersWereInitialized = ibo_elements != 0 && vbo_position != 0; - if (!buffersWereInitialized) - { - GenerateBuffers(); - UpdateVertexData(); - } - } - public override void Draw(GL_ControlLegacy control, Pass pass) - { - CheckBuffers(); - - if (!Runtime.OpenTKInitialized) - return; - } - - public override void Draw(GL_ControlModern control, Pass pass) - { - CheckBuffers(); - - if (!Runtime.OpenTKInitialized) - return; - - control.CurrentShader = defaultShaderProgram; - SetRenderSettings(defaultShaderProgram); - - Matrix4 camMat = control.ModelMatrix * control.CameraMatrix * control.ProjectionMatrix; - - GL.Disable(EnableCap.CullFace); - - GL.Uniform3(defaultShaderProgram["difLightDirection"], Vector3.TransformNormal(new Vector3(0f, 0f, -1f), camMat.Inverted()).Normalized()); - GL.Uniform3(defaultShaderProgram["difLightColor"], new Vector3(1)); - GL.Uniform3(defaultShaderProgram["ambLightColor"], new Vector3(1)); - - defaultShaderProgram.EnableVertexAttributes(); - - foreach (var mdl in Meshes) - { - DrawModel(mdl, defaultShaderProgram); - } - - defaultShaderProgram.DisableVertexAttributes(); - - GL.UseProgram(0); - GL.Disable(EnableCap.DepthTest); - GL.Enable(EnableCap.DepthTest); - GL.Enable(EnableCap.CullFace); - } - private void SetRenderSettings(ShaderProgram shader) - { - shader.SetBoolToInt("renderVertColor", Runtime.renderVertColor); - GL.Uniform1(defaultShaderProgram["renderType"], (int)Runtime.viewportShading); - - } - private void DrawModel(MeshWrapper m, ShaderProgram shader, bool drawSelection = false) - { - if (m.lodMeshes[m.DisplayLODIndex].faces.Count <= 3) - return; - - SetVertexAttributes(m, shader); - - if (m.Checked) - { - if ((m.IsSelected)) - { - DrawModelSelection(m, shader); - } - else - { - if (Runtime.RenderModelWireframe) - { - DrawModelWireframe(m, shader); - } - - if (Runtime.RenderModels) - { - GL.DrawElements(PrimitiveType.Triangles, m.lodMeshes[m.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, m.Offset); - } - } - } - } - private static void DrawModelSelection(MeshWrapper p, ShaderProgram shader) - { - //This part needs to be reworked for proper outline. Currently would make model disappear - - GL.DrawElements(PrimitiveType.Triangles, p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset); - - GL.Enable(EnableCap.StencilTest); - // use vertex color for wireframe color - GL.Uniform1(shader["colorOverride"], 1); - GL.PolygonMode(MaterialFace.Front, PolygonMode.Line); - GL.Enable(EnableCap.LineSmooth); - GL.LineWidth(1.5f); - GL.DrawElements(PrimitiveType.Triangles, p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset); - GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); - GL.Uniform1(shader["colorOverride"], 0); - - GL.Enable(EnableCap.DepthTest); - } - private void SetVertexAttributes(MeshWrapper m, ShaderProgram shader) - { - GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position); - GL.VertexAttribPointer(shader.GetAttribute("vPosition"), 3, VertexAttribPointerType.Float, false, DisplayVertex.Size, 0); //+12 - GL.VertexAttribPointer(shader.GetAttribute("vNormal"), 3, VertexAttribPointerType.Float, false, DisplayVertex.Size, 12); //+12 - GL.VertexAttribPointer(shader.GetAttribute("vTangent"), 3, VertexAttribPointerType.Float, false, DisplayVertex.Size, 24); //+12 - GL.VertexAttribPointer(shader.GetAttribute("vUV0"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 36); //+8 - GL.VertexAttribPointer(shader.GetAttribute("vColor"), 4, VertexAttribPointerType.Float, false, DisplayVertex.Size, 44); //+16 - GL.VertexAttribIPointer(shader.GetAttribute("vBone"), 4, VertexAttribIntegerType.Int, DisplayVertex.Size, new IntPtr(60)); //+16 - GL.VertexAttribPointer(shader.GetAttribute("vWeight"), 4, VertexAttribPointerType.Float, false, DisplayVertex.Size, 76);//+16 - GL.VertexAttribPointer(shader.GetAttribute("vUV1"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 92);//+8 - GL.VertexAttribPointer(shader.GetAttribute("vUV2"), 2, VertexAttribPointerType.Float, false, DisplayVertex.Size, 100);//+8 - GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements); - } - private static void DrawModelWireframe(MeshWrapper p, ShaderProgram shader) - { - // use vertex color for wireframe color - GL.Uniform1(shader["colorOverride"], 1); - GL.PolygonMode(MaterialFace.Front, PolygonMode.Line); - GL.Enable(EnableCap.LineSmooth); - GL.LineWidth(1.5f); - GL.DrawElements(PrimitiveType.Triangles, p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset); - GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); - GL.Uniform1(shader["colorOverride"], 0); - } - } - Viewport viewport { get @@ -550,12 +254,12 @@ namespace FirstPlugin public List LowerNodes = new List(); public STSkeleton Skeleton { get; set; } - Renderer DrawableRenderer { get; set; } + GenericModelRenderer DrawableRenderer { get; set; } public void Read(FileReader reader, MKAGPDX_Model root) { Skeleton = new STSkeleton(); - DrawableRenderer = new Renderer(); + DrawableRenderer = new GenericModelRenderer(); root.DrawableContainer.Drawables.Add(Skeleton); root.DrawableContainer.Drawables.Add(DrawableRenderer); @@ -720,13 +424,13 @@ namespace FirstPlugin } else if (Node.IsMesh) { - MeshWrapper meshNode = new MeshWrapper(); + GenericRenderedObject meshNode = new GenericRenderedObject(); meshNode.ImageKey = "mesh"; meshNode.SelectedImageKey = "mesh"; int i = 0; - meshNode.lodMeshes = new List(); - var msh = new MeshWrapper.LOD_Mesh(); + meshNode.lodMeshes = new List(); + var msh = new GenericRenderedObject.LOD_Mesh(); msh.PrimitiveType = STPolygonType.Triangle; msh.FirstVertex = 0; msh.faces = Node.SubMeshes[0].Faces; @@ -738,12 +442,12 @@ namespace FirstPlugin { if (i > 0) { - MeshWrapper subMeshNode = new MeshWrapper(); + GenericRenderedObject subMeshNode = new GenericRenderedObject(); subMeshNode.ImageKey = "mesh"; subMeshNode.SelectedImageKey = "mesh"; - subMeshNode.lodMeshes = new List(); - var submsh = new MeshWrapper.LOD_Mesh(); + subMeshNode.lodMeshes = new List(); + var submsh = new GenericRenderedObject.LOD_Mesh(); submsh.PrimitiveType = STPolygonType.Triangle; submsh.FirstVertex = 0; submsh.faces = subMesh.Faces; diff --git a/Switch_FileFormatsMain/GL/GMX_Renderer.cs b/Switch_FileFormatsMain/GL/GMX_Renderer.cs new file mode 100644 index 00000000..1748f2e3 --- /dev/null +++ b/Switch_FileFormatsMain/GL/GMX_Renderer.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Switch_Toolbox.Library.Rendering; + +namespace FirstPlugin +{ + public class GMX_Renderer : GenericModelRenderer + { + + } +} diff --git a/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj b/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj index 9b3277a3..9087fc87 100644 --- a/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj +++ b/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj @@ -265,6 +265,7 @@ + diff --git a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache index b70f8afa..6d1c5aaa 100644 Binary files a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache and b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache differ diff --git a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache index d8a8af2b..4c03237a 100644 Binary files a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache and b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache differ diff --git a/Switch_Toolbox_Library/Compression/STLibraryCompression.cs b/Switch_Toolbox_Library/Compression/STLibraryCompression.cs index 1518809c..7ac15ea2 100644 --- a/Switch_Toolbox_Library/Compression/STLibraryCompression.cs +++ b/Switch_Toolbox_Library/Compression/STLibraryCompression.cs @@ -145,13 +145,18 @@ namespace Switch_Toolbox.Library.IO //Mario Tennis Aces Custom compression public class MTA_CUSTOM { + [DllImport("Lib/LibTennis.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void DecompressBuffer(IntPtr output, IntPtr input, uint len); + public unsafe byte[] Decompress(byte[] input, uint decompressedLength) { fixed (byte* outputPtr = new byte[decompressedLength]) { fixed (byte* inputPtr = input) { - Decompress(outputPtr, inputPtr, decompressedLength); + DecompressBuffer((IntPtr)outputPtr, (IntPtr)inputPtr, decompressedLength); + + // Decompress(outputPtr, inputPtr, decompressedLength); } byte[] decomp = new byte[decompressedLength]; diff --git a/Switch_Toolbox_Library/Generics/GenericObject.cs b/Switch_Toolbox_Library/Generics/GenericObject.cs index 1b441366..759c3726 100644 --- a/Switch_Toolbox_Library/Generics/GenericObject.cs +++ b/Switch_Toolbox_Library/Generics/GenericObject.cs @@ -29,6 +29,11 @@ namespace Switch_Toolbox.Library } + public virtual STGenericMaterial GetMaterial() + { + return new STGenericMaterial(); + } + public List PolygonGroups = new List(); public bool HasPos; diff --git a/Switch_Toolbox_Library/IO/STFileLoader.cs b/Switch_Toolbox_Library/IO/STFileLoader.cs index 7f07e270..5953bd9d 100644 --- a/Switch_Toolbox_Library/IO/STFileLoader.cs +++ b/Switch_Toolbox_Library/IO/STFileLoader.cs @@ -194,6 +194,29 @@ namespace Switch_Toolbox.Library.IO return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true, CompressionType.Yaz0, DecompressedFileSize, CompressedFileSize); } + if (Path.GetExtension(FileName) == ".cbtex") + { + fileReader.Position = 0; + byte compType = fileReader.ReadByte(); + if (compType == 0x50) + { + if (data == null) + data = File.ReadAllBytes(FileName); + + fileReader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; + + fileReader.Seek(4, System.IO.SeekOrigin.Begin); + uint decompSize = fileReader.ReadUInt32(); + uint compSize = (uint)fileReader.BaseStream.Length - 8; + + var comp = new STLibraryCompression.MTA_CUSTOM(); + data = comp.Decompress(data, decompSize); + + return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true, + CompressionType.MarioTennisCustom, DecompressedFileSize, CompressedFileSize); + } + fileReader.Position = 0; + } if (Path.GetExtension(FileName) == ".lz") { if (data == null) diff --git a/Switch_Toolbox_Library/Interfaces/IArchiveFile.cs b/Switch_Toolbox_Library/Interfaces/IArchiveFile.cs index 2ee86f6f..bab77050 100644 --- a/Switch_Toolbox_Library/Interfaces/IArchiveFile.cs +++ b/Switch_Toolbox_Library/Interfaces/IArchiveFile.cs @@ -144,7 +144,7 @@ namespace Switch_Toolbox.Library public void SaveFileFormat() { if (FileFormat != null && FileFormat.CanSave) - _fileData = FileFormat.Save(); + FileData = FileFormat.Save(); } [Browsable(false)] diff --git a/Switch_Toolbox_Library/PublicEnums.cs b/Switch_Toolbox_Library/PublicEnums.cs index d3186d54..d1d2547e 100644 --- a/Switch_Toolbox_Library/PublicEnums.cs +++ b/Switch_Toolbox_Library/PublicEnums.cs @@ -15,5 +15,6 @@ namespace Switch_Toolbox.Library Lz4, Lz4f, Zstb, + MarioTennisCustom, } } diff --git a/Switch_Toolbox_Library/Rendering/GenericModelRenderer/GenericModelRenderer.cs b/Switch_Toolbox_Library/Rendering/GenericModelRenderer/GenericModelRenderer.cs new file mode 100644 index 00000000..aecbc465 --- /dev/null +++ b/Switch_Toolbox_Library/Rendering/GenericModelRenderer/GenericModelRenderer.cs @@ -0,0 +1,448 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using GL_EditorFramework.GL_Core; +using GL_EditorFramework.Interfaces; +using Switch_Toolbox.Library.IO; +using Switch_Toolbox.Library; +using OpenTK; +using OpenTK.Graphics.OpenGL; + +namespace Switch_Toolbox.Library.Rendering +{ + public class GenericModelRenderer : AbstractGlDrawable + { + public List Meshes = new List(); + public STSkeleton Skeleton = new STSkeleton(); + + public Matrix4 ModelTransform = Matrix4.Identity; + + // gl buffer objects + int vbo_position; + int ibo_elements; + + private void GenerateBuffers() + { + GL.GenBuffers(1, out vbo_position); + GL.GenBuffers(1, out ibo_elements); + + UpdateVertexData(); + UpdateTextureMaps(); + } + + public void Destroy() + { + GL.DeleteBuffer(vbo_position); + GL.DeleteBuffer(ibo_elements); + } + + public void UpdateVertexData() + { + if (!Runtime.OpenTKInitialized) + return; + + GenericRenderedObject.DisplayVertex[] Vertices; + int[] Faces; + + int poffset = 0; + int voffset = 0; + List Vs = new List(); + List Ds = new List(); + + foreach (GenericRenderedObject shape in Meshes) + { + List pv = shape.CreateDisplayVertices(); + Vs.AddRange(pv); + + int GroupOffset = 0; + int groupIndex = 0; + if (shape.PolygonGroups.Count > 0) + { + foreach (var group in shape.PolygonGroups) + { + group.Offset = poffset * 4; + + for (int i = 0; i < group.displayFaceSize; i++) + { + Ds.Add(shape.display[GroupOffset + i] + voffset); + } + + poffset += group.displayFaceSize; + GroupOffset += group.displayFaceSize; + } + + voffset += pv.Count; + } + else if (shape.lodMeshes.Count > 0) + { + shape.Offset = poffset * 4; + + for (int i = 0; i < shape.lodMeshes[shape.DisplayLODIndex].displayFaceSize; i++) + { + Ds.Add(shape.display[i] + voffset); + } + poffset += shape.lodMeshes[shape.DisplayLODIndex].displayFaceSize; + voffset += pv.Count; + } + } + + // Binds + Vertices = Vs.ToArray(); + Faces = Ds.ToArray(); + + // Bind only once! + GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position); + GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Length * GenericRenderedObject.DisplayVertex.Size), Vertices, BufferUsageHint.StaticDraw); + + GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements); + GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(Faces.Length * sizeof(int)), Faces, BufferUsageHint.StaticDraw); + + LibraryGUI.Instance.UpdateViewport(); + } + + public void UpdateTextureMaps() + { + if (!Runtime.OpenTKInitialized) + return; + + LibraryGUI.Instance.UpdateViewport(); + } + + public ShaderProgram defaultShaderProgram; + + public override void Prepare(GL_ControlModern control) + { + string pathFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "GFBModel.frag"); + string pathVert = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "GFBModel.vert"); + string pathUtiltyFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Utility") + "\\Utility.frag"; + string pathPbrUtiltyFrag = System.IO.Path.Combine(Runtime.ExecutableDir, "Shader", "Utility") + "\\PbrUtility.frag"; + + + var defaultFrag = new FragmentShader(File.ReadAllText(pathFrag)); + var defaultVert = new VertexShader(File.ReadAllText(pathVert)); + var utiltyFrag = new FragmentShader(System.IO.File.ReadAllText(pathUtiltyFrag)); + var pbrUtiltyFrag = new FragmentShader(System.IO.File.ReadAllText(pathPbrUtiltyFrag)); + + defaultShaderProgram = new ShaderProgram(new Shader[] + { utiltyFrag, pbrUtiltyFrag, defaultVert, defaultFrag }, control); + } + + public override void Prepare(GL_ControlLegacy control) + { + + } + + public override void Draw(GL_ControlLegacy control, Pass pass) + { + if (!Runtime.OpenTKInitialized) + return; + } + + public override void Draw(GL_ControlModern control, Pass pass) + { + if (!Runtime.OpenTKInitialized || pass == Pass.TRANSPARENT) + return; + + bool buffersWereInitialized = ibo_elements != 0 && vbo_position != 0; + if (!buffersWereInitialized) + GenerateBuffers(); + + ShaderProgram shader = defaultShaderProgram; + control.CurrentShader = shader; + control.UpdateModelMatrix(Matrix4.CreateScale(Runtime.previewScale) * ModelTransform); + + Matrix4 camMat = control.ModelMatrix * control.CameraMatrix * control.ProjectionMatrix; + + Matrix4 invertedCamera = Matrix4.Identity; + if (invertedCamera.Determinant != 0) + invertedCamera = camMat.Inverted(); + + Vector3 lightDirection = new Vector3(0f, 0f, -1f); + + shader.SetVector3("difLightDirection", Vector3.TransformNormal(lightDirection, invertedCamera).Normalized()); + + // GL.Enable(EnableCap.AlphaTest); + // GL.AlphaFunc(AlphaFunction.Gequal, 0.1f); + + SetRenderSettings(shader); + + DrawModels(shader, control); + + + GL.UseProgram(0); + GL.Disable(EnableCap.DepthTest); + GL.Enable(EnableCap.DepthTest); + GL.Enable(EnableCap.CullFace); + } + + private static void SetBoneUniforms(GLControl control, ShaderProgram shader, STSkeleton Skeleton, STGenericObject mesh) + { + int i = 0; + foreach (var bone in Skeleton.bones) + { + Matrix4 transform = bone.invert * bone.Transform; + GL.UniformMatrix4(GL.GetUniformLocation(shader.programs[control], String.Format("bones[{0}]", i++)), false, ref transform); + } + + /* foreach (var FaceGroup in fshp.Shape.FaceGroups) + { + if (FaceGroup.BoneIndexList == null) + continue; + + for (int i = 0; i < FaceGroup.BoneIndexList.Length; i++) + { + GL.Uniform1(GL.GetUniformLocation(shader.programs[control], String.Format("boneIds[{0}]", i)), FaceGroup.BoneIndexList[i]); + + Matrix4 transform = fmdl.Skeleton.Renderable.bones[(int)FaceGroup.BoneIndexList[i]].invert * fmdl.Skeleton.Renderable.bones[(int)FaceGroup.BoneIndexList[i]].Transform; + GL.UniformMatrix4(GL.GetUniformLocation(shader.programs[control], String.Format("bones[{0}]", i)), false, ref transform); + } + }*/ + } + + private void SetUniformBlocks(STGenericMaterial mat, ShaderProgram shader, STGenericObject m) + { + + } + + private static void SetUniforms(STGenericMaterial mat, ShaderProgram shader, STGenericObject m) + { + + } + + private static void SetUniformData(STGenericMaterial mat, ShaderProgram shader, string propertyName) + { + + } + + private static void LoadDebugTextureMaps(ShaderProgram shader) + { + GL.ActiveTexture(TextureUnit.Texture0 + 1); + GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.RenderableTex.TexID); + + GL.Uniform1(shader["debugOption"], 2); + + GL.ActiveTexture(TextureUnit.Texture11); + GL.Uniform1(shader["weightRamp1"], 11); + GL.BindTexture(TextureTarget.Texture2D, RenderTools.BoneWeightGradient.Id); + + GL.ActiveTexture(TextureUnit.Texture12); + GL.Uniform1(shader["weightRamp2"], 12); + GL.BindTexture(TextureTarget.Texture2D, RenderTools.BoneWeightGradient2.Id); + + + GL.ActiveTexture(TextureUnit.Texture10); + GL.Uniform1(shader["UVTestPattern"], 10); + GL.BindTexture(TextureTarget.Texture2D, RenderTools.uvTestPattern.RenderableTex.TexID); + } + + private static void SetTextureUniforms(STGenericMaterial mat, STGenericObject m, ShaderProgram shader) + { + SetDefaultTextureAttributes(mat, shader); + LoadDebugTextureMaps(shader); + + shader.SetInt("RedChannel", 0); + shader.SetInt("GreenChannel", 1); + shader.SetInt("BlueChannel", 2); + shader.SetInt("AlphaChannel", 3); + + LoadPBRMaps(shader); + + foreach (STGenericMatTexture matex in mat.TextureMaps) + { + if (matex.Type == STGenericMatTexture.TextureType.Diffuse) + { + shader.SetBoolToInt("HasDiffuse", true); + TextureUniform(shader, mat, true, "DiffuseMap", matex); + } + } + } + + private static void LoadPBRMaps(ShaderProgram shader) + { + GL.ActiveTexture(TextureUnit.Texture0 + 26); + RenderTools.specularPbr.Bind(); + shader.SetInt("specularIbl", 26); + // GL.GenerateMipmap(GenerateMipmapTarget.TextureCubeMap); + + // PBR IBL + GL.ActiveTexture(TextureUnit.Texture0 + 25); + RenderTools.diffusePbr.Bind(); + shader.SetInt("irradianceMap", 25); + + GL.ActiveTexture(TextureUnit.Texture0 + 27); + RenderTools.brdfPbr.Bind(); + shader.SetInt("brdfLUT", 27); + } + + private static void TextureUniform(ShaderProgram shader, STGenericMaterial mat, bool hasTex, string name, STGenericMatTexture mattex) + { + if (mattex.textureState == STGenericMatTexture.TextureState.Binded) + return; + + // Bind the texture and create the uniform if the material has the right textures. + if (hasTex) + { + GL.Uniform1(shader[name], BindTexture(mattex, shader)); + } + } + + public static int BindTexture(STGenericMatTexture tex, ShaderProgram shader) + { + GL.ActiveTexture(TextureUnit.Texture0 + tex.textureUnit + 1); + GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.RenderableTex.TexID); + + string activeTex = tex.Name; + + /* foreach (var bntx in TextureContainers) + { + if (TextureContainers.ContainsKey(activeTex)) + { + BindGLTexture(bntx, tex, shader, activeTex); + return tex.textureUnit + 1; + } + }*/ + + return tex.textureUnit + 1; + } + + private static void BindGLTexture(STGenericMatTexture tex, ShaderProgram shader, STGenericTexture texture) + { + if (tex.Type == STGenericMatTexture.TextureType.Diffuse) + { + shader.SetInt("RedChannel", (int)texture.RedChannel); + shader.SetInt("GreenChannel", (int)texture.GreenChannel); + shader.SetInt("BlueChannel", (int)texture.BlueChannel); + shader.SetInt("AlphaChannel", (int)texture.AlphaChannel); + } + + // GL.ActiveTexture(TextureUnit.Texture0 + texid); + GL.BindTexture(TextureTarget.Texture2D, texture.RenderableTex.TexID); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)STGenericMatTexture.wrapmode[tex.wrapModeS]); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)STGenericMatTexture.wrapmode[tex.wrapModeT]); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)STGenericMatTexture.minfilter[tex.minFilter]); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)STGenericMatTexture.magfilter[tex.magFilter]); + GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, 0.0f); + } + + private static void SetDefaultTextureAttributes(STGenericMaterial mat, ShaderProgram shader) + { + } + + private void SetRenderSettings(ShaderProgram shader) + { + shader.SetInt("renderType", (int)Runtime.viewportShading); + shader.SetInt("selectedBoneIndex", Runtime.SelectedBoneIndex); + shader.SetBoolToInt("renderVertColor", Runtime.renderVertColor); + } + + private void DrawModels(ShaderProgram shader, GL_ControlModern control) + { + shader.EnableVertexAttributes(); + foreach (STGenericObject shp in Meshes) + { + if (shp.Checked) + DrawModel(control, Skeleton, shp.GetMaterial(), shp, shader); + } + shader.DisableVertexAttributes(); + } + + private void SetVertexAttributes(STGenericObject m, ShaderProgram shader) + { + GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position); + GL.VertexAttribPointer(shader.GetAttribute("vPosition"), 3, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 0); //+12 + GL.VertexAttribPointer(shader.GetAttribute("vNormal"), 3, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 12); //+12 + GL.VertexAttribPointer(shader.GetAttribute("vTangent"), 3, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 24); //+12 + GL.VertexAttribPointer(shader.GetAttribute("vUV0"), 2, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 36); //+8 + GL.VertexAttribPointer(shader.GetAttribute("vColor"), 4, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 44); //+16 + GL.VertexAttribIPointer(shader.GetAttribute("vBone"), 4, VertexAttribIntegerType.Int, GenericRenderedObject.DisplayVertex.Size, new IntPtr(60)); //+16 + GL.VertexAttribPointer(shader.GetAttribute("vWeight"), 4, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 76);//+16 + GL.VertexAttribPointer(shader.GetAttribute("vUV1"), 2, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 92);//+8 + GL.VertexAttribPointer(shader.GetAttribute("vUV2"), 2, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 100);//+8 + GL.VertexAttribPointer(shader.GetAttribute("vBinormal"), 3, VertexAttribPointerType.Float, false, GenericRenderedObject.DisplayVertex.Size, 108); //+12 + GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements); + } + + private void DrawModel(GLControl control, STSkeleton Skeleton, STGenericMaterial Material, STGenericObject m, ShaderProgram shader) + { + if (m.PolygonGroups.Count > 0) + { + foreach (var group in m.PolygonGroups) + { + if (group.faces.Count <= 3) + return; + + SetUniforms(Material, shader, m); + SetUniformBlocks(Material, shader, m); + SetBoneUniforms(control, shader, Skeleton, m); + SetVertexAttributes(m, shader); + SetTextureUniforms(Material, m, shader); + + if (m.IsSelected) + { + DrawModelSelection(group, shader); + } + else + { + if (Runtime.RenderModels) + { + GL.DrawElements(PrimitiveType.Triangles, group.displayFaceSize, DrawElementsType.UnsignedInt, group.Offset); + } + } + } + } + else + { + if (m.lodMeshes.Count <= 0 || m.lodMeshes[m.DisplayLODIndex].faces.Count <= 3) + return; + + SetUniforms(Material, shader, m); + SetUniformBlocks(Material, shader, m); + SetBoneUniforms(control, shader, Skeleton, m); + SetVertexAttributes(m, shader); + SetTextureUniforms(Material, m, shader); + + if (m.IsSelected) + { + DrawModelSelection(m, shader); + } + else + { + if (Runtime.RenderModels) + { + GL.DrawElements(PrimitiveType.Triangles, m.lodMeshes[m.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, m.Offset); + } + } + } + + } + + + private static void DrawModelSelection(STGenericObject p, ShaderProgram shader) + { + GL.Uniform1(shader["colorOverride"], 1); + GL.PolygonMode(MaterialFace.Front, PolygonMode.Line); + GL.Enable(EnableCap.LineSmooth); + GL.LineWidth(1.3f); + GL.DrawElements(PrimitiveType.Triangles, p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset); + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); + GL.Uniform1(shader["colorOverride"], 0); + + GL.DrawElements(PrimitiveType.Triangles, p.lodMeshes[p.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, p.Offset); + } + + private static void DrawModelSelection(STGenericPolygonGroup p, ShaderProgram shader) + { + GL.Uniform1(shader["colorOverride"], 1); + GL.PolygonMode(MaterialFace.Front, PolygonMode.Line); + GL.Enable(EnableCap.LineSmooth); + GL.LineWidth(1.3f); + GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset); + GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); + GL.Uniform1(shader["colorOverride"], 0); + + GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset); + } + } +} diff --git a/Switch_Toolbox_Library/Rendering/GenericModelRenderer/GenericRenderedObject.cs b/Switch_Toolbox_Library/Rendering/GenericModelRenderer/GenericRenderedObject.cs new file mode 100644 index 00000000..2c74d84e --- /dev/null +++ b/Switch_Toolbox_Library/Rendering/GenericModelRenderer/GenericRenderedObject.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenTK; + +namespace Switch_Toolbox.Library.Rendering +{ + public class GenericRenderedObject : STGenericObject + { + public int[] display; + public int DisplayId; + + public struct DisplayVertex + { + // Used for rendering. + public Vector3 pos; + public Vector3 nrm; + public Vector3 tan; + public Vector2 uv; + public Vector4 col; + public Vector4 node; + public Vector4 weight; + public Vector2 uv2; + public Vector2 uv3; + public Vector3 binorm; + + public static int Size = 4 * (3 + 3 + 3 + 2 + 4 + 4 + 4 + 2 + 2 + 3); + } + + public virtual List CreateDisplayVertices() + { + display = new int[0]; + if (PolygonGroups.Count > 0) + { + List Faces = new List(); + + foreach (var group in PolygonGroups) + Faces.AddRange(group.GetDisplayFace()); + + display = Faces.ToArray(); + } + + if (lodMeshes.Count > 0) + { + display = lodMeshes[DisplayLODIndex].getDisplayFace().ToArray(); + } + + + List displayVertList = new List(); + + if (display.Length <= 3) + return displayVertList; + + foreach (Vertex v in vertices) + { + DisplayVertex displayVert = new DisplayVertex() + { + pos = v.pos, + nrm = v.nrm, + tan = v.tan.Xyz, + binorm = v.bitan.Xyz, + col = v.col, + uv = v.uv0, + uv2 = v.uv1, + uv3 = v.uv2, + node = new Vector4( + v.boneIds.Count > 0 ? v.boneIds[0] : -1, + v.boneIds.Count > 1 ? v.boneIds[1] : -1, + v.boneIds.Count > 2 ? v.boneIds[2] : -1, + v.boneIds.Count > 3 ? v.boneIds[3] : -1), + weight = new Vector4( + v.boneWeights.Count > 0 ? v.boneWeights[0] : 0, + v.boneWeights.Count > 1 ? v.boneWeights[1] : 0, + v.boneWeights.Count > 2 ? v.boneWeights[2] : 0, + v.boneWeights.Count > 3 ? v.boneWeights[3] : 0), + }; + + displayVertList.Add(displayVert); + } + + return displayVertList; + } + } + + +} diff --git a/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj b/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj index 81328421..03c64210 100644 --- a/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj +++ b/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj @@ -214,6 +214,8 @@ + + diff --git a/Toolbox/Lib/LibTennis.dll b/Toolbox/Lib/LibTennis.dll new file mode 100644 index 00000000..610d991b Binary files /dev/null and b/Toolbox/Lib/LibTennis.dll differ diff --git a/Toolbox/Toolbox.csproj b/Toolbox/Toolbox.csproj index 99fce86b..b5a5cf6e 100644 --- a/Toolbox/Toolbox.csproj +++ b/Toolbox/Toolbox.csproj @@ -386,6 +386,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest