diff --git a/File_Format_Library/FileFormats/Collision/KCL.cs b/File_Format_Library/FileFormats/Collision/KCL.cs index 2024b7a0..1b365930 100644 --- a/File_Format_Library/FileFormats/Collision/KCL.cs +++ b/File_Format_Library/FileFormats/Collision/KCL.cs @@ -71,7 +71,7 @@ namespace FirstPlugin } } - private DrawableContainer DrawableContainer = new DrawableContainer(); + public DrawableContainer DrawableContainer = new DrawableContainer(); public void Load(System.IO.Stream stream) { @@ -463,6 +463,10 @@ namespace FirstPlugin } } + public List GetKclModels() + { + return Renderer.models; + } private void Read(MarioKart.MK7.KCL kcl) { diff --git a/File_Format_Library/FileFormats/Texture/BNTX.cs b/File_Format_Library/FileFormats/Texture/BNTX.cs index cedcdcb2..6c2737bb 100644 --- a/File_Format_Library/FileFormats/Texture/BNTX.cs +++ b/File_Format_Library/FileFormats/Texture/BNTX.cs @@ -382,14 +382,21 @@ namespace FirstPlugin { long StartPos = reader.Position; + Console.WriteLine("StartPos " + StartPos); + uint TotalSize = (uint)reader.BaseStream.Length; + Console.WriteLine("TotalSize " + TotalSize); + //Get file size in header reader.SeekBegin(StartPos + 28); uint FileSize = reader.ReadUInt32(); + Console.WriteLine("FileSize " + FileSize); + //Create bntx for array BNTX bntx = new BNTX(); + bntx.IFileInfo = new IFileInfo(); bntx.Text = "Sheet " + Containers.Count; @@ -399,6 +406,8 @@ namespace FirstPlugin bntx.Load(new MemoryStream(Data)); Containers.Add(bntx); + Console.WriteLine("File Container " + bntx.Text + " " + StartPos); + reader.SeekBegin(StartPos + FileSize); if (TotalSize > FileSize) { @@ -1616,7 +1625,7 @@ namespace FirstPlugin public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0) { int target = 1; - if (Parent != null && Parent is BNTX) + if (Parent != null && Parent is BNTX && ((BNTX)Parent).BinaryTexFile != null) { bool IsNX = ((BNTX)Parent).BinaryTexFile.PlatformTarget == "NX "; if (!IsNX) diff --git a/File_Format_Library/File_Format_Library.csproj b/File_Format_Library/File_Format_Library.csproj index e248dafd..919fadcf 100644 --- a/File_Format_Library/File_Format_Library.csproj +++ b/File_Format_Library/File_Format_Library.csproj @@ -1,4 +1,4 @@ - + @@ -113,7 +113,8 @@ False ..\Toolbox\Lib\OpenTK.dll - + + False ..\Toolbox\Lib\OpenTK.GLControl.dll @@ -352,6 +353,7 @@ + Form @@ -646,6 +648,9 @@ SmoothNormalsMultiMeshForm.cs + + UserControl + Component @@ -1818,5 +1823,4 @@ - - + \ No newline at end of file diff --git a/File_Format_Library/File_Format_Library.csproj.user b/File_Format_Library/File_Format_Library.csproj.user index 64a5aae8..dee06e3e 100644 --- a/File_Format_Library/File_Format_Library.csproj.user +++ b/File_Format_Library/File_Format_Library.csproj.user @@ -3,4 +3,7 @@ true + + ProjectFiles + \ No newline at end of file diff --git a/File_Format_Library/GL/Custom2D/KCLRendering2D.cs b/File_Format_Library/GL/Custom2D/KCLRendering2D.cs new file mode 100644 index 00000000..a13a704c --- /dev/null +++ b/File_Format_Library/GL/Custom2D/KCLRendering2D.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenTK; +using OpenTK.Graphics; + +namespace FirstPlugin +{ + public class KCLRendering2D + { + public KCLRendering2D(KCL kcl) + { + + } + + public void Draw(Matrix4 modelViewMatrix) + { + + } + } +} diff --git a/File_Format_Library/GL/KCL_Render.cs b/File_Format_Library/GL/KCL_Render.cs index a91cab25..70314195 100644 --- a/File_Format_Library/GL/KCL_Render.cs +++ b/File_Format_Library/GL/KCL_Render.cs @@ -281,12 +281,14 @@ namespace FirstPlugin 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(KCL.KCLModel m, ShaderProgram shader, bool drawSelection = false) { if (m.faces.Count <= 3) @@ -314,6 +316,7 @@ namespace FirstPlugin } } } + private static void DrawModelSelection(KCL.KCLModel p, ShaderProgram shader) { //This part needs to be reworked for proper outline. Currently would make model disappear diff --git a/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.Designer.cs b/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.Designer.cs index f37183c0..63a244cc 100644 --- a/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.Designer.cs +++ b/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.Designer.cs @@ -28,30 +28,30 @@ /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); this.stPropertyGrid1 = new Toolbox.Library.Forms.STPropertyGrid(); this.leBtnRadio = new System.Windows.Forms.RadioButton(); this.beBtnRadio = new System.Windows.Forms.RadioButton(); - this.glControl2D1 = new Toolbox.Library.Forms.GLControl2D(); + this.mapCameraViewer1 = new MapCameraViewer(); + this.stContextMenuStrip1 = new Toolbox.Library.Forms.STContextMenuStrip(this.components); + this.loadKCLFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.stContextMenuStrip1.SuspendLayout(); this.SuspendLayout(); - this.Controls.Add(this.glControl2D1); - this.Controls.Add(this.beBtnRadio); - this.Controls.Add(this.leBtnRadio); - this.Controls.Add(this.stPropertyGrid1); // // stPropertyGrid1 // this.stPropertyGrid1.AutoScroll = true; - this.stPropertyGrid1.ShowHintDisplay = true; this.stPropertyGrid1.Dock = System.Windows.Forms.DockStyle.Right; - this.stPropertyGrid1.Location = new System.Drawing.Point(272, 25); + this.stPropertyGrid1.Location = new System.Drawing.Point(503, 0); this.stPropertyGrid1.Name = "stPropertyGrid1"; - this.stPropertyGrid1.Size = new System.Drawing.Size(298, 372); + this.stPropertyGrid1.ShowHintDisplay = true; + this.stPropertyGrid1.Size = new System.Drawing.Size(217, 437); this.stPropertyGrid1.TabIndex = 11; // // leBtnRadio // this.leBtnRadio.AutoSize = true; - this.leBtnRadio.Location = new System.Drawing.Point(154, 31); + this.leBtnRadio.Location = new System.Drawing.Point(85, 3); this.leBtnRadio.Name = "leBtnRadio"; this.leBtnRadio.Size = new System.Drawing.Size(83, 17); this.leBtnRadio.TabIndex = 13; @@ -62,7 +62,7 @@ // beBtnRadio // this.beBtnRadio.AutoSize = true; - this.beBtnRadio.Location = new System.Drawing.Point(72, 31); + this.beBtnRadio.Location = new System.Drawing.Point(3, 3); this.beBtnRadio.Name = "beBtnRadio"; this.beBtnRadio.Size = new System.Drawing.Size(76, 17); this.beBtnRadio.TabIndex = 14; @@ -71,25 +71,47 @@ this.beBtnRadio.UseVisualStyleBackColor = true; this.beBtnRadio.CheckedChanged += new System.EventHandler(this.beBtnRadio_CheckedChanged); // - // glControl2D1 + // mapCameraViewer1 // - this.glControl2D1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + this.mapCameraViewer1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.glControl2D1.BackColor = System.Drawing.Color.Black; - this.glControl2D1.Location = new System.Drawing.Point(3, 54); - this.glControl2D1.Name = "glControl2D1"; - this.glControl2D1.Size = new System.Drawing.Size(263, 343); - this.glControl2D1.TabIndex = 15; - this.glControl2D1.VSync = false; + this.mapCameraViewer1.Location = new System.Drawing.Point(3, 26); + this.mapCameraViewer1.Name = "mapCameraViewer1"; + this.mapCameraViewer1.Size = new System.Drawing.Size(494, 408); + this.mapCameraViewer1.TabIndex = 15; + this.mapCameraViewer1.UseGrid = true; + this.mapCameraViewer1.UseOrtho = true; + this.mapCameraViewer1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.mapCameraViewer1_MouseDown); + // + // stContextMenuStrip1 + // + this.stContextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.loadKCLFileToolStripMenuItem}); + this.stContextMenuStrip1.Name = "stContextMenuStrip1"; + this.stContextMenuStrip1.Size = new System.Drawing.Size(145, 26); + // + // loadKCLFileToolStripMenuItem + // + this.loadKCLFileToolStripMenuItem.Name = "loadKCLFileToolStripMenuItem"; + this.loadKCLFileToolStripMenuItem.Size = new System.Drawing.Size(144, 22); + this.loadKCLFileToolStripMenuItem.Text = "Load KCL File"; + this.loadKCLFileToolStripMenuItem.Click += new System.EventHandler(this.loadKCLFileToolStripMenuItem_Click); // // MK8MapCameraEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(576, 402); + this.Controls.Add(this.mapCameraViewer1); + this.Controls.Add(this.beBtnRadio); + this.Controls.Add(this.leBtnRadio); + this.Controls.Add(this.stPropertyGrid1); this.Name = "MK8MapCameraEditor"; + this.Size = new System.Drawing.Size(720, 437); + this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MK8MapCameraEditor_MouseDown); + this.stContextMenuStrip1.ResumeLayout(false); this.ResumeLayout(false); + this.PerformLayout(); } @@ -98,6 +120,8 @@ private Toolbox.Library.Forms.STPropertyGrid stPropertyGrid1; private System.Windows.Forms.RadioButton beBtnRadio; private System.Windows.Forms.RadioButton leBtnRadio; - private Toolbox.Library.Forms.GLControl2D glControl2D1; + private MapCameraViewer mapCameraViewer1; + private Toolbox.Library.Forms.STContextMenuStrip stContextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem loadKCLFileToolStripMenuItem; } } diff --git a/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.cs b/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.cs index 6beb563c..b84431a6 100644 --- a/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.cs +++ b/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.cs @@ -26,7 +26,7 @@ namespace FirstPlugin.Turbo InitializeComponent(); } - Course_MapCamera_bin activeCameraFile; + private Course_MapCamera_bin activeCameraFile; public void LoadFile(Course_MapCamera_bin mapCamera) { activeCameraFile = mapCamera; @@ -40,10 +40,7 @@ namespace FirstPlugin.Turbo stPropertyGrid1.LoadProperty(activeCameraFile.cameraData, OnPropertyChanged); - glControl2D1.AddCircle(new OpenTK.Vector2(cam.PositionX, cam.PositionZ)); - glControl2D1.AddCircle(new OpenTK.Vector2(cam.TargetX, cam.TargetZ)); - - glControl2D1.AddRectangle(cam.BoundingWidth, cam.BoundingHeight, new OpenTK.Vector2(cam.PositionX, cam.PositionZ)); + mapCameraViewer1.LoadCameraFile(mapCamera); } public void OnPropertyChanged() { } @@ -57,5 +54,33 @@ namespace FirstPlugin.Turbo { activeCameraFile.BigEndian = beBtnRadio.Checked; } + + private void mapCameraViewer1_MouseDown(object sender, MouseEventArgs e) + { + + } + + private void loadKCLFileToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = Utils.GetAllFilters(typeof(KCL)); + if (ofd.ShowDialog() == DialogResult.OK) + { + var fileFormat = Toolbox.Library.IO.STFileLoader.OpenFileFormat(ofd.FileName); + if (fileFormat != null && fileFormat is KCL) + { + var kcl = fileFormat as KCL; + mapCameraViewer1.LoadCollision(kcl); + } + } + } + + private void MK8MapCameraEditor_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + stContextMenuStrip1.Show(Cursor.Position); + } + } } } diff --git a/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.resx b/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.resx index 1af7de15..197ca22e 100644 --- a/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.resx +++ b/File_Format_Library/GUI/Editors/MK8TrackEditor/MK8MapCameraEditor.resx @@ -117,4 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file diff --git a/File_Format_Library/GUI/Editors/MK8TrackEditor/MapCameraViewer.cs b/File_Format_Library/GUI/Editors/MK8TrackEditor/MapCameraViewer.cs new file mode 100644 index 00000000..f9adb072 --- /dev/null +++ b/File_Format_Library/GUI/Editors/MK8TrackEditor/MapCameraViewer.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Toolbox.Library.Forms; +using OpenTK.Graphics.OpenGL; +using Toolbox.Library; +using System.Drawing; +using FirstPlugin.Turbo; +using OpenTK; + +namespace FirstPlugin.Turbo +{ + public class MapCameraViewer : Viewport2D + { + private KCL CollisionFile; + private KCLRendering2D KCLRender; + private Course_MapCamera_bin MapCamera; + + public void LoadCollision(KCL kcl) { + CollisionFile = kcl; + KCLRender = new KCLRendering2D(kcl); + } + + public void LoadCameraFile(Course_MapCamera_bin camera) { + MapCamera = camera; + } + + public override void RenderSceme() + { + if (MapCamera == null) return; + + GL.PushMatrix(); + + GL.Scale(0.1f, 0.1f ,1.0f); + + var cam = MapCamera.cameraData; + + if (CollisionFile != null) + DrawCollision(CollisionFile); + + Render2D.DrawRectangle(cam.BoundingWidth, cam.BoundingHeight, Color.White, true); + + Render2D.DrawCircle(new Vector2(cam.PositionX, cam.PositionY), Color.Red); + Render2D.DrawCircle(new Vector2(cam.TargetX, cam.TargetY), Color.Green); + + GL.PopMatrix(); + } + + private void DrawCollision(KCL kcl) { + KCLRender.Draw(Camera.ModelViewMatrix); + } + } +} diff --git a/File_Format_Library/Main.cs b/File_Format_Library/Main.cs index de86ed9e..0402d5d1 100644 --- a/File_Format_Library/Main.cs +++ b/File_Format_Library/Main.cs @@ -396,7 +396,7 @@ namespace FirstPlugin //Unfinished wip formats not ready for use if (Runtime.DEVELOPER_DEBUG_MODE) { - Formats.Add(typeof(XLINK)); + Formats.Add(typeof(XLINK)); Formats.Add(typeof(BFSAR)); Formats.Add(typeof(GFA)); Formats.Add(typeof(HyruleWarriors.G1M.G1M)); diff --git a/Switch_Toolbox_Library/OpenGL/GLShaderGeneric.cs b/Switch_Toolbox_Library/OpenGL/GLShaderGeneric.cs new file mode 100644 index 00000000..28d3cf3d --- /dev/null +++ b/Switch_Toolbox_Library/OpenGL/GLShaderGeneric.cs @@ -0,0 +1,208 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using System.Threading.Tasks; +using OpenTK.Graphics.OpenGL; +using OpenTK; + +namespace Toolbox.Library +{ + public class GLShaderGeneric : IDisposable + { + public bool Compiled = false; + + public int program; + private int vertexShaderID; + private int fragmentShaderID; + + private Dictionary attributes = new Dictionary(); + private Dictionary uniforms = new Dictionary(); + private int activeAttributeCount; + + public void LoadShaders() + { + program = CompileShaders(); + } + + public void Enable() + { + GL.UseProgram(program); + } + + public void Disable() + { + GL.UseProgram(0); + } + + public void Dispose() + { + GL.DeleteProgram(program); + } + + private string vertexShader; + private string fragShader; + private string geomShader; + + public virtual string VertexShader + { + get { return vertexShader; } + set { vertexShader = value; } + } + + public virtual string FragmentShader + { + get { return fragShader; } + set { fragShader = value; } + } + + public virtual string GeometryShader + { + get { return geomShader; } + set { geomShader = value; } + } + + public void SetVec4(string name, Vector4 value) + { + if (uniforms.ContainsKey(name)) + GL.Uniform4(uniforms[name], value); + } + + public void SetVec2(string name, Vector2 value) + { + if (uniforms.ContainsKey(name)) + GL.Uniform2(uniforms[name], value); + } + + public void SetFloat(string name, float value) + { + if (uniforms.ContainsKey(name)) + GL.Uniform1(uniforms[name], value); + } + + public void SetInt(string name, int value) + { + if (uniforms.ContainsKey(name)) + GL.Uniform1(uniforms[name], value); + } + + public void SetBool(string name, bool value) + { + int intValue = value == true ? 1 : 0; + + if (uniforms.ContainsKey(name)) + GL.Uniform1(uniforms[name], intValue); + } + + public void SetColor(string name, Color color) + { + if (uniforms.ContainsKey(name)) + GL.Uniform4(uniforms[name], color); + } + + public void SetMatrix(string name, ref Matrix4 value) + { + if (uniforms.ContainsKey(name)) + GL.UniformMatrix4(uniforms[name], false, ref value); + } + + public int this[string name] + { + get { return uniforms[name]; } + } + + private void LoadAttributes(int program) + { + attributes.Clear(); + + GL.GetProgram(program, GetProgramParameterName.ActiveAttributes, out activeAttributeCount); + for (int i = 0; i < activeAttributeCount; i++) + { + int size = 0; + ActiveAttribType type; + + string name = GL.GetActiveAttrib(program, i, out size, out type); + int location = GL.GetAttribLocation(program, name); + + // Overwrite existing vertex attributes. + attributes[name] = location; + } + } + + public void EnableVertexAttributes() + { + foreach (KeyValuePair attrib in attributes) + GL.EnableVertexAttribArray(attrib.Value); + } + + public void DisableVertexAttributes() + { + foreach (KeyValuePair attrib in attributes) + GL.DisableVertexAttribArray(attrib.Value); + } + + public int GetAttribute(string name) + { + if (string.IsNullOrEmpty(name) || !attributes.ContainsKey(name)) + return -1; + else + return attributes[name]; + } + + private void LoadUniorms(int program) + { + uniforms.Clear(); + + GL.GetProgram(program, GetProgramParameterName.ActiveUniforms, out activeAttributeCount); + for (int i = 0; i < activeAttributeCount; i++) + { + int size = 0; + ActiveUniformType type; + string name = GL.GetActiveUniform(program, i, out size, out type); + int location = GL.GetUniformLocation(program, name); + + // Overwrite existing vertex attributes. + uniforms[name] = location; + } + } + + public void Compile() + { + program = CompileShaders(); + + LoadAttributes(program); + LoadUniorms(program); + OnCompiled(); + + Compiled = true; + } + + public virtual void OnCompiled() { } + + private int CompileShaders() + { + vertexShaderID = GL.CreateShader(ShaderType.VertexShader); + GL.ShaderSource(vertexShaderID, VertexShader); + GL.CompileShader(vertexShaderID); + + fragmentShaderID = GL.CreateShader(ShaderType.FragmentShader); + GL.ShaderSource(fragmentShaderID, FragmentShader); + GL.CompileShader(fragmentShaderID); + + var program = GL.CreateProgram(); + GL.AttachShader(program, vertexShaderID); + GL.AttachShader(program, fragmentShaderID); + GL.LinkProgram(program); + + var info = GL.GetProgramInfoLog(program); + if (!string.IsNullOrWhiteSpace(info)) + Console.WriteLine($"GL.LinkProgram had info log: {info}"); + + GL.DetachShader(program, vertexShaderID); + GL.DetachShader(program, fragmentShaderID); + GL.DeleteShader(vertexShaderID); + GL.DeleteShader(fragmentShaderID); + return program; + } + } +} diff --git a/Switch_Toolbox_Library/OpenGL/Render2D.cs b/Switch_Toolbox_Library/OpenGL/Render2D.cs new file mode 100644 index 00000000..0a49a091 --- /dev/null +++ b/Switch_Toolbox_Library/OpenGL/Render2D.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenTK.Graphics.OpenGL; +using OpenTK; +using System.Drawing; +using Toolbox.Library.IO; + +namespace Toolbox.Library +{ + public class Render2D + { + public static void DrawRectangle(float width, float height, Vector3 translate, Vector3 rotate, Vector3 scale) + { + GL.PushMatrix(); + + GL.Scale(scale); + GL.Rotate(rotate.X, new Vector3(1, 0, 0)); + GL.Rotate(rotate.Y, new Vector3(0, 1, 0)); + GL.Rotate(rotate.Z, new Vector3(0, 0, 1)); + GL.Translate(translate); + + DrawRectangle(width, height, Color.White, false); + + GL.PopMatrix(); + } + + public static void DrawCircle(Vector2 Position, Color color) + { + GL.PushMatrix(); + GL.Translate(Position.X, Position.Y, 0); + GL.Scale(300,300,1); + + GL.Color4(color); + GL.Begin(PrimitiveType.LineLoop); + for (int i = 0; i <= 300; i++) + { + double angle = 2 * Math.PI * i / 300; + double x = Math.Cos(angle); + double y = Math.Sin(angle); + GL.Vertex2(x, y); + } + GL.End(); + + GL.PopMatrix(); + } + + public static void DrawRectangle(float width, float height, Color color, bool wireframe) + { + if (wireframe) + { + GL.Begin(PrimitiveType.LineLoop); + GL.LineWidth(1); + GL.Color4(color); + GL.Vertex2(-width, -height); + GL.Vertex2(width, -height); + GL.Vertex2(width, height); + GL.Vertex2(-width, height); + GL.End(); + + GL.PopAttrib(); + } + else + { + GL.Begin(PrimitiveType.Quads); + GL.Color4(color); + GL.TexCoord2(-1, -1); + GL.Vertex2(-width, -height); + GL.TexCoord2(0, -1); + GL.Vertex2(width, -height); + GL.TexCoord2(0, 0); + GL.Vertex2(width, height); + GL.TexCoord2(-1, 0); + GL.Vertex2(-width, height); + GL.End(); + } + } + + public static void DrawGrid(Color color) + { + var size = 40; + var amount = 300; + + GL.LineWidth(0.001f); + GL.Color3(color.Darken(20)); + GL.Begin(PrimitiveType.Lines); + + int squareGridCounter = 0; + for (var i = -amount; i <= amount; i++) + { + if (squareGridCounter > 5) + { + squareGridCounter = 0; + GL.LineWidth(33f); + } + else + { + GL.LineWidth(0.001f); + } + + GL.Vertex2(new Vector2(-amount * size, i * size)); + GL.Vertex2(new Vector2(amount * size, i * size)); + GL.Vertex2(new Vector2(i * size, -amount * size)); + GL.Vertex2(new Vector2(i * size, amount * size)); + + squareGridCounter++; + } + GL.End(); + GL.Color3(Color.Transparent); + GL.PopAttrib(); + } + } +} diff --git a/Switch_Toolbox_Library/OpenGL/Viewport2D.cs b/Switch_Toolbox_Library/OpenGL/Viewport2D.cs new file mode 100644 index 00000000..a9b7fa3c --- /dev/null +++ b/Switch_Toolbox_Library/OpenGL/Viewport2D.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using OpenTK; +using OpenTK.Graphics.OpenGL; +using Toolbox.Library; + +namespace Toolbox.Library.Forms +{ + public class Viewport2D : UserControl + { + public virtual bool UseOrtho { get; set; } = false; + public virtual bool UseGrid { get; set; } = true; + + public Camera2D Camera = new Camera2D(); + + public class Camera2D + { + public Matrix4 ViewMatrix = Matrix4.Identity; + public Matrix4 ModelMatrix = Matrix4.Identity; + + public Matrix4 ModelViewMatrix + { + get + { + return ModelMatrix * ViewMatrix; + } + } + + public float Zoom = 1; + public Vector2 Position; + } + + private GLControl glControl1; + private Color BackgroundColor = Color.FromArgb(40, 40, 40); + + public Viewport2D() + { + glControl1 = new GLControl(); + glControl1.Dock = DockStyle.Fill; + glControl1.MouseDown += glControl1_MouseDown; + glControl1.MouseUp += glControl1_MouseUp; + glControl1.MouseMove += glControl1_MouseMove; + glControl1.Paint += glControl1_Paint; + glControl1.Resize += glControl1_Resize; + Controls.Add(glControl1); + } + + + public void UpdateViewport() { + glControl1.Invalidate(); + } + + private void glControl1_Paint(object sender, PaintEventArgs e) + { + if (!Runtime.OpenTKInitialized) + return; + + glControl1.Context.MakeCurrent(glControl1.WindowInfo); + + RenderEditor(); + SetupScene(); + } + + private void RenderEditor() + { + glControl1.MakeCurrent(); + + GL.Viewport(0, 0, glControl1.Width, glControl1.Height); + GL.MatrixMode(MatrixMode.Projection); + GL.LoadIdentity(); + if (UseOrtho) + { + float halfW = glControl1.Width / 2.0f, halfH = glControl1.Height / 2.0f; + var orthoMatrix = Matrix4.CreateOrthographic(halfW, halfH, -10000, 10000); + GL.LoadMatrix(ref orthoMatrix); + GL.MatrixMode(MatrixMode.Modelview); + Camera.ViewMatrix = orthoMatrix; + } + else + { + var cameraPosition = new Vector3(Camera.Position.X, Camera.Position.Y, -(Camera.Zoom * 500)); + + var perspectiveMatrix = Matrix4.CreateRotationY(90) * Matrix4.CreateTranslation(cameraPosition) * Matrix4.CreatePerspectiveFieldOfView(1.3f, glControl1.Width / glControl1.Height, 0.01f, 100000); + GL.LoadMatrix(ref perspectiveMatrix); + GL.MatrixMode(MatrixMode.Modelview); + Camera.ViewMatrix = perspectiveMatrix; + } + + GL.ClearColor(BackgroundColor); + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + + if (UseOrtho) + { + GL.PushMatrix(); + GL.Scale(Camera.Zoom, Camera.Zoom, 1); + GL.Translate(Camera.Position.X, Camera.Position.Y, 0); + + Matrix4 scaleMat = Matrix4.CreateScale(Camera.Zoom, Camera.Zoom, 1); + Matrix4 transMat = Matrix4.CreateTranslation(Camera.Position.X, -Camera.Position.Y, 0); + + Camera.ModelMatrix = scaleMat * transMat; + } + } + + private void SetupScene() + { + GL.Enable(EnableCap.Blend); + GL.Enable(EnableCap.AlphaTest); + GL.AlphaFunc(AlphaFunction.Always, 0f); + GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); + GL.Enable(EnableCap.ColorMaterial); + GL.Enable(EnableCap.Texture2D); + GL.BindTexture(TextureTarget.Texture2D, 0); + GL.BlendEquation(BlendEquationMode.FuncAdd); + + if (UseGrid) + Render2D.DrawGrid(BackgroundColor); + + RenderSceme(); + + if (UseOrtho) + GL.PopMatrix(); + + GL.UseProgram(0); + glControl1.SwapBuffers(); + } + + public virtual void RenderSceme() + { + + } + + private Point originMouse; + private bool mouseCameraDown; + + private void glControl1_MouseDown(object sender, MouseEventArgs e) + { + if (Control.ModifierKeys == Keys.Shift && e.Button == MouseButtons.Left || + e.Button == MouseButtons.Middle) + { + originMouse = e.Location; + mouseCameraDown = true; + glControl1.Invalidate(); + } + } + + private void glControl1_MouseUp(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Middle) + { + mouseCameraDown = false; + } + } + + private void glControl1_MouseMove(object sender, MouseEventArgs e) + { + if (mouseCameraDown) + { + var pos = new Vector2(e.Location.X - originMouse.X, e.Location.Y - originMouse.Y); + Camera.Position.X += pos.X; + Camera.Position.Y += pos.Y; + + originMouse = e.Location; + + glControl1.Invalidate(); + } + } + + private void glControl1_Resize(object sender, EventArgs e) + { + glControl1.Invalidate(); + } + + protected override void OnMouseWheel(MouseEventArgs e) + { + base.OnMouseWheel(e); + if (UseOrtho) + { + if (e.Delta > 0 && Camera.Zoom > 0) + Camera.Zoom += 0.1f; + if (e.Delta < 0 && Camera.Zoom < 100 && Camera.Zoom > 0.1) + Camera.Zoom -= 0.1f; + } + else + { + if (e.Delta > 0 && Camera.Zoom > 0.1) + Camera.Zoom -= 0.1f; + if (e.Delta < 0 && Camera.Zoom < 100 && Camera.Zoom > 0) + Camera.Zoom += 0.1f; + } + + glControl1.Invalidate(); + } + } +} diff --git a/Switch_Toolbox_Library/Toolbox_Library.csproj b/Switch_Toolbox_Library/Toolbox_Library.csproj index cf0f3dc9..bce4ef82 100644 --- a/Switch_Toolbox_Library/Toolbox_Library.csproj +++ b/Switch_Toolbox_Library/Toolbox_Library.csproj @@ -392,6 +392,12 @@ + + + + UserControl + + diff --git a/Toolbox/Lib/SARCExt.dll b/Toolbox/Lib/SARCExt.dll index 627c86cd..e998f86b 100644 Binary files a/Toolbox/Lib/SARCExt.dll and b/Toolbox/Lib/SARCExt.dll differ diff --git a/Toolbox/Lib/SARCExt.pdb b/Toolbox/Lib/SARCExt.pdb index 822cc2c9..c0175513 100644 Binary files a/Toolbox/Lib/SARCExt.pdb and b/Toolbox/Lib/SARCExt.pdb differ diff --git a/Toolbox/Shader/Drawing2D/KCL.frag b/Toolbox/Shader/Drawing2D/KCL.frag new file mode 100644 index 00000000..c593fbff --- /dev/null +++ b/Toolbox/Shader/Drawing2D/KCL.frag @@ -0,0 +1,13 @@ +#version 330 + +in vec3 normal; +in vec3 color; +in vec3 position; + +out vec4 FragColor; + +void main() +{ + vec3 displayNormal = (normal.xyz * 0.5) + 0.5; + FragColor = vec4(displayNormal.rgb,1); +} diff --git a/Toolbox/Shader/Drawing2D/KCL.vert b/Toolbox/Shader/Drawing2D/KCL.vert new file mode 100644 index 00000000..1f762afa --- /dev/null +++ b/Toolbox/Shader/Drawing2D/KCL.vert @@ -0,0 +1,21 @@ +#version 330 + +in vec3 vPosition; +in vec3 vNormal; +in vec3 vColor; + +out vec3 normal; +out vec3 color; +out vec3 position; + +uniform mat4 modelViewMatrix; +uniform mat4 modelMatrix; + +void main() +{ + normal = vNormal; + color = vColor; + position = vPosition; + + gl_Position = modelMatrix * modelViewMatrix * vec4(vPosition.xyz, 1.0); +} \ No newline at end of file diff --git a/Toolbox/Toolbox.csproj b/Toolbox/Toolbox.csproj index 773fdfde..81c360c6 100644 --- a/Toolbox/Toolbox.csproj +++ b/Toolbox/Toolbox.csproj @@ -227,6 +227,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/UpgradeLog.htm b/UpgradeLog.htm new file mode 100644 index 00000000..a3ef1fbb Binary files /dev/null and b/UpgradeLog.htm differ