mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-26 06:20:24 +00:00
More additions and fixes.
Added GMX rendering (note explodes atm) Fixed mario tennis aces/ultra compression (now uses external dll from Simon) Fixed a bug where file sizes for IArchives (TMPK and ME01) would not adjust on save. casuing corrupted file data.
This commit is contained in:
parent
d157fa4c84
commit
ab80051646
22 changed files with 734 additions and 322 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<STGenericObject.LOD_Mesh>();
|
||||
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<int>() { 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<int>() { 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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<STGenericTexture>(), ((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<DisplayVertex> CreateDisplayVertices()
|
||||
{
|
||||
display = lodMeshes[DisplayLODIndex].getDisplayFace().ToArray();
|
||||
|
||||
List<DisplayVertex> displayVertList = new List<DisplayVertex>();
|
||||
|
||||
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<ushort> SelectedTypes = new List<ushort>();
|
||||
|
||||
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<MeshWrapper> Meshes = new List<MeshWrapper>();
|
||||
|
||||
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<DisplayVertex> Vs = new List<DisplayVertex>();
|
||||
List<int> Ds = new List<int>();
|
||||
foreach (var m in Meshes)
|
||||
{
|
||||
m.Offset = poffset * 4;
|
||||
List<DisplayVertex> 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<DisplayVertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Length * DisplayVertex.Size), Vertices, BufferUsageHint.StaticDraw);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
|
||||
GL.BufferData<int>(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<Node> LowerNodes = new List<Node>();
|
||||
|
||||
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<MeshWrapper.LOD_Mesh>();
|
||||
var msh = new MeshWrapper.LOD_Mesh();
|
||||
meshNode.lodMeshes = new List<GenericRenderedObject.LOD_Mesh>();
|
||||
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<MeshWrapper.LOD_Mesh>();
|
||||
var submsh = new MeshWrapper.LOD_Mesh();
|
||||
subMeshNode.lodMeshes = new List<GenericRenderedObject.LOD_Mesh>();
|
||||
var submsh = new GenericRenderedObject.LOD_Mesh();
|
||||
submsh.PrimitiveType = STPolygonType.Triangle;
|
||||
submsh.FirstVertex = 0;
|
||||
submsh.faces = subMesh.Faces;
|
||||
|
|
14
Switch_FileFormatsMain/GL/GMX_Renderer.cs
Normal file
14
Switch_FileFormatsMain/GL/GMX_Renderer.cs
Normal file
|
@ -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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -265,6 +265,7 @@
|
|||
<Compile Include="FileFormats\XLINK\XLINK.cs" />
|
||||
<Compile Include="GL\BCRES_Render.cs" />
|
||||
<Compile Include="GL\GFBMDL_Render.cs" />
|
||||
<Compile Include="GL\GMX_Renderer.cs" />
|
||||
<Compile Include="GL\Helpers\DepthGLControl.cs" />
|
||||
<Compile Include="GL\ShaderData\AglShaderOdyssey.cs" />
|
||||
<Compile Include="GL\ShaderData\AglShaderTurbo.cs" />
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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];
|
||||
|
|
|
@ -29,6 +29,11 @@ namespace Switch_Toolbox.Library
|
|||
|
||||
}
|
||||
|
||||
public virtual STGenericMaterial GetMaterial()
|
||||
{
|
||||
return new STGenericMaterial();
|
||||
}
|
||||
|
||||
public List<STGenericPolygonGroup> PolygonGroups = new List<STGenericPolygonGroup>();
|
||||
|
||||
public bool HasPos;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace Switch_Toolbox.Library
|
|||
public void SaveFileFormat()
|
||||
{
|
||||
if (FileFormat != null && FileFormat.CanSave)
|
||||
_fileData = FileFormat.Save();
|
||||
FileData = FileFormat.Save();
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
|
|
|
@ -15,5 +15,6 @@ namespace Switch_Toolbox.Library
|
|||
Lz4,
|
||||
Lz4f,
|
||||
Zstb,
|
||||
MarioTennisCustom,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<GenericRenderedObject> Meshes = new List<GenericRenderedObject>();
|
||||
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<GenericRenderedObject.DisplayVertex> Vs = new List<GenericRenderedObject.DisplayVertex>();
|
||||
List<int> Ds = new List<int>();
|
||||
|
||||
foreach (GenericRenderedObject shape in Meshes)
|
||||
{
|
||||
List<GenericRenderedObject.DisplayVertex> 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<GenericRenderedObject.DisplayVertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Length * GenericRenderedObject.DisplayVertex.Size), Vertices, BufferUsageHint.StaticDraw);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
|
||||
GL.BufferData<int>(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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<DisplayVertex> CreateDisplayVertices()
|
||||
{
|
||||
display = new int[0];
|
||||
if (PolygonGroups.Count > 0)
|
||||
{
|
||||
List<int> Faces = new List<int>();
|
||||
|
||||
foreach (var group in PolygonGroups)
|
||||
Faces.AddRange(group.GetDisplayFace());
|
||||
|
||||
display = Faces.ToArray();
|
||||
}
|
||||
|
||||
if (lodMeshes.Count > 0)
|
||||
{
|
||||
display = lodMeshes[DisplayLODIndex].getDisplayFace().ToArray();
|
||||
}
|
||||
|
||||
|
||||
List<DisplayVertex> displayVertList = new List<DisplayVertex>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -214,6 +214,8 @@
|
|||
<Compile Include="Compression\STLibraryCompression.cs" />
|
||||
<Compile Include="Compression\ZCMP.cs" />
|
||||
<Compile Include="Config.cs" />
|
||||
<Compile Include="Rendering\GenericModelRenderer\GenericModelRenderer.cs" />
|
||||
<Compile Include="Rendering\GenericModelRenderer\GenericRenderedObject.cs" />
|
||||
<Compile Include="Security\Cryptography\crc32.cs" />
|
||||
<Compile Include="DrawableContainer.cs" />
|
||||
<Compile Include="FileFormats\3DS\ETC1.cs" />
|
||||
|
|
BIN
Toolbox/Lib/LibTennis.dll
Normal file
BIN
Toolbox/Lib/LibTennis.dll
Normal file
Binary file not shown.
|
@ -386,6 +386,9 @@
|
|||
<Content Include="Lib\LibHac.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Lib\LibTennis.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Lib\Licenses\Assimp COPYRIGHT.txt" />
|
||||
<Content Include="Lib\Licenses\ImageBox COPYRIGHT.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
|
Loading…
Reference in a new issue