From a9eec9a3ee843acbb42eae09edc2213a75ec25b3 Mon Sep 17 00:00:00 2001 From: miku-666 <74728189+NessieHax@users.noreply.github.com> Date: Wed, 1 Nov 2023 10:17:50 +0100 Subject: [PATCH] Updated vertex positioning --- .../Forms/Skins-And-Textures/SkinPreview.cs | 2 +- .../generateModel.Designer.cs | 26 +- .../Forms/Skins-And-Textures/generateModel.cs | 132 +------ PCK-Studio/PckStudio.csproj | 1 + PCK-Studio/Rendering/CubeRenderGroup.cs | 86 ++++ PCK-Studio/Rendering/IndexBuffer.cs | 28 +- PCK-Studio/Rendering/RenderGroup.cs | 112 +----- PCK-Studio/Rendering/Renderer3D.cs | 2 +- PCK-Studio/Rendering/SkinRenderer.cs | 373 ++++++++++-------- PCK-Studio/Rendering/VertexBufferLayout.cs | 3 +- 10 files changed, 359 insertions(+), 406 deletions(-) create mode 100644 PCK-Studio/Rendering/CubeRenderGroup.cs diff --git a/PCK-Studio/Forms/Skins-And-Textures/SkinPreview.cs b/PCK-Studio/Forms/Skins-And-Textures/SkinPreview.cs index 4334f2ca..76984fcb 100644 --- a/PCK-Studio/Forms/Skins-And-Textures/SkinPreview.cs +++ b/PCK-Studio/Forms/Skins-And-Textures/SkinPreview.cs @@ -1,9 +1,9 @@ using System; +using System.Linq; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using PckStudio.Internal; -using PckStudio.Rendering; namespace PckStudio.Forms { diff --git a/PCK-Studio/Forms/Skins-And-Textures/generateModel.Designer.cs b/PCK-Studio/Forms/Skins-And-Textures/generateModel.Designer.cs index 3384a257..e6e161c7 100644 --- a/PCK-Studio/Forms/Skins-And-Textures/generateModel.Designer.cs +++ b/PCK-Studio/Forms/Skins-And-Textures/generateModel.Designer.cs @@ -42,8 +42,6 @@ this.changeColorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.buttonDone = new System.Windows.Forms.Button(); this.labelView = new System.Windows.Forms.Label(); - this.rotateRightBtn = new System.Windows.Forms.Button(); - this.rotateLeftBtn = new System.Windows.Forms.Button(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.tabBody = new System.Windows.Forms.TabControl(); this.tabArmor = new System.Windows.Forms.TabPage(); @@ -85,7 +83,7 @@ this.U = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.V = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.listViewBoxes = new System.Windows.Forms.ListView(); - this.renderer3D1 = new PckStudio.Rendering.Renderer3D(); + this.renderer3D1 = new PckStudio.Rendering.SkinRenderer(); this.uvPictureBox = new PckStudio.ToolboxItems.InterpolationPictureBox(); label6 = new System.Windows.Forms.Label(); label5 = new System.Windows.Forms.Label(); @@ -188,22 +186,6 @@ this.labelView.ForeColor = System.Drawing.Color.White; this.labelView.Name = "labelView"; // - // rotateRightBtn - // - resources.ApplyResources(this.rotateRightBtn, "rotateRightBtn"); - this.rotateRightBtn.ForeColor = System.Drawing.Color.White; - this.rotateRightBtn.Name = "rotateRightBtn"; - this.rotateRightBtn.UseVisualStyleBackColor = true; - this.rotateRightBtn.Click += new System.EventHandler(this.rotateRightBtn_Click); - // - // rotateLeftBtn - // - resources.ApplyResources(this.rotateLeftBtn, "rotateLeftBtn"); - this.rotateLeftBtn.ForeColor = System.Drawing.Color.White; - this.rotateLeftBtn.Name = "rotateLeftBtn"; - this.rotateLeftBtn.UseVisualStyleBackColor = true; - this.rotateLeftBtn.Click += new System.EventHandler(this.rotateLeftBtn_Click); - // // groupBox1 // this.groupBox1.Controls.Add(this.tabBody); @@ -582,8 +564,6 @@ this.Controls.Add(this.buttonIMPORT); this.Controls.Add(this.groupBox1); this.Controls.Add(label7); - this.Controls.Add(this.rotateLeftBtn); - this.Controls.Add(this.rotateRightBtn); this.Controls.Add(this.labelView); this.Controls.Add(this.buttonDone); this.Controls.Add(label3); @@ -642,8 +622,6 @@ private System.Windows.Forms.TextBox offsetHead; private System.Windows.Forms.Label label12; private System.Windows.Forms.TabPage tabArmor; - private System.Windows.Forms.Button rotateLeftBtn; - private System.Windows.Forms.Button rotateRightBtn; private System.Windows.Forms.Label labelView; private MetroFramework.Controls.MetroButton buttonTemplate; private MetroFramework.Controls.MetroCheckBox generateTextureCheckBox; @@ -667,6 +645,6 @@ private System.Windows.Forms.ColumnHeader U; private System.Windows.Forms.ColumnHeader V; private System.Windows.Forms.ListView listViewBoxes; - private Rendering.Renderer3D renderer3D1; + private Rendering.SkinRenderer renderer3D1; } } \ No newline at end of file diff --git a/PCK-Studio/Forms/Skins-And-Textures/generateModel.cs b/PCK-Studio/Forms/Skins-And-Textures/generateModel.cs index e28b468e..9cf03907 100644 --- a/PCK-Studio/Forms/Skins-And-Textures/generateModel.cs +++ b/PCK-Studio/Forms/Skins-And-Textures/generateModel.cs @@ -20,27 +20,13 @@ using System.Text; namespace PckStudio.Forms { - [Obsolete] + //[Obsolete] public partial class generateModel : MetroForm { - [Obsolete("We don't need a full control to get an image")] - private PictureBox skinPreview = new PictureBox(); - private Image _previewImage; public Image PreviewImage => _previewImage; - private ViewDirection direction = ViewDirection.front; - - private enum ViewDirection - { - front, - right, - back, - left, - } - private PckFileData _file; - private SkinANIM _ANIM; private static Color _backgroundColor = Color.FromArgb(0xff, 0x50, 0x50, 0x50); private static GraphicsConfig _graphicsConfig = new GraphicsConfig() @@ -128,18 +114,19 @@ namespace PckStudio.Forms public generateModel(PckFileData file) { - MessageBox.Show(this, "This feature is now considered deprecated and will no longer recieve updates. A better alternative is currently under development. Use at your own risk.", "Deprecated Feature", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + //MessageBox.Show(this, "This feature is now considered deprecated and will no longer recieve updates. A better alternative is currently under development. Use at your own risk.", "Deprecated Feature", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); InitializeComponent(); _file = file; - if (file.Size > 0) + if (_file.Size > 0) { - uvPictureBox.Image = file.GetTexture(); + uvPictureBox.Image = renderer3D1.Texture = _file.GetTexture() as Bitmap; } comboParent.Items.Clear(); comboParent.Items.AddRange(ValidModelBoxTypes); LoadData(file.Properties); } + private static readonly Regex sWhitespace = new Regex(@"\s+"); public static string ReplaceWhitespace(string input, string replacement) { @@ -148,15 +135,8 @@ namespace PckStudio.Forms private void LoadData(PckFileProperties properties) { - comboParent.Enabled = properties.GetProperties("BOX").All(kv => { - var box = SkinBOX.FromString(kv.Value); - if (ValidModelBoxTypes.Contains(box.Type)) - { - modelBoxes.Add(box); - return true; - } - return false; - }); + renderer3D1.ANIM = properties.GetPropertyValue("ANIM", SkinANIM.FromString); + renderer3D1.ModelData.AddRange(properties.GetProperties("BOX").Select(kv => SkinBOX.FromString(kv.Value))); properties.GetProperties("OFFSET").All(kv => { string[] offset = ReplaceWhitespace(kv.Value, ",").TrimEnd('\n', '\r', ' ').Split(','); if (offset.Length < 3) @@ -173,9 +153,7 @@ namespace PckStudio.Forms return false; }); - _ANIM = properties.GetPropertyValue("ANIM", SkinANIM.FromString); UpdateListView(); - Rerender(); } //Rename model part/item @@ -184,14 +162,6 @@ namespace PckStudio.Forms listViewBoxes.SelectedItems[0].BeginEdit(); } - private void Rerender([CallerMemberName] string caller = default!) - { - Debug.WriteLine($"Call from {caller}", category: nameof(Rerender)); - Render(this, EventArgs.Empty); - if (generateTextureCheckBox.Checked) - GenerateUVTextureMap(); - } - private void Render(object sender, EventArgs e) { //buttonTemplate.Enabled = listViewBoxes.Items.Count == 0; @@ -875,14 +845,12 @@ namespace PckStudio.Forms if (Screen.PrimaryScreen.Bounds.Height >= 780 && Screen.PrimaryScreen.Bounds.Width >= 1080) { return; } - Rerender(); } private void createToolStripMenuItem_Click(object sender, EventArgs e) { modelBoxes.Add(SkinBOX.Empty); UpdateListView(); - Rerender(); } private void listView1_SelectedIndexChanged(object sender, EventArgs e) @@ -903,11 +871,9 @@ namespace PckStudio.Forms SizeZUpDown.Value = (decimal)part.Size.Z; TextureXUpDown.Value = (decimal)part.UV.X; TextureYUpDown.Value = (decimal)part.UV.Y; - Rerender(); } } - //Changes Item Model Class private void comboParent_SelectedIndexChanged(object sender, EventArgs e) { @@ -926,7 +892,6 @@ namespace PckStudio.Forms TextureXUpDown.Enabled = true; TextureYUpDown.Enabled = true; } - Rerender(); } private void SizeXUpDown_ValueChanged(object sender, EventArgs e) @@ -937,7 +902,6 @@ namespace PckStudio.Forms part.Size.X = (float)SizeXUpDown.Value; } UpdateListView(); - Rerender(); } private void SizeYUpDown_ValueChanged(object sender, EventArgs e) @@ -948,7 +912,6 @@ namespace PckStudio.Forms part.Size.Y = (float)SizeYUpDown.Value; } UpdateListView(); - Rerender(); } private void SizeZUpDown_ValueChanged(object sender, EventArgs e) @@ -959,7 +922,6 @@ namespace PckStudio.Forms part.Size.Z = (float)SizeZUpDown.Value; } UpdateListView(); - Rerender(); } private void PosXUpDown_ValueChanged(object sender, EventArgs e) @@ -970,10 +932,8 @@ namespace PckStudio.Forms part.Pos.X = (float)PosXUpDown.Value; } UpdateListView(); - Rerender(); } - private void PosYUpDown_ValueChanged(object sender, EventArgs e) { if (listViewBoxes.SelectedItems.Count != 0 && @@ -982,10 +942,8 @@ namespace PckStudio.Forms part.Pos.Y = (float)PosYUpDown.Value; } UpdateListView(); - Rerender(); } - private void PosZUpDown_ValueChanged(object sender, EventArgs e) { if (listViewBoxes.SelectedItems.Count != 0 && @@ -994,30 +952,8 @@ namespace PckStudio.Forms part.Pos.Z = (float)PosZUpDown.Value; } UpdateListView(); - Rerender(); } - private void rotateRightBtn_Click(object sender, EventArgs e) - { - if (direction == ViewDirection.front) - direction = ViewDirection.left; - else - --direction; - labelView.Text = $"View: {direction}"; - Rerender(); - } - - private void rotateLeftBtn_Click(object sender, EventArgs e) - { - if (direction == ViewDirection.left) - direction = ViewDirection.front; - else - ++direction; - labelView.Text = $"View: {direction}"; - Rerender(); - } - - //Sets Texture X-Offset private void TextureXUpDown_ValueChanged(object sender, EventArgs e) { @@ -1027,10 +963,8 @@ namespace PckStudio.Forms part.UV.X = (int)TextureXUpDown.Value; } UpdateListView(); - Rerender(); } - //Sets texture Y-Offset private void TextureYUpDown_ValueChanged(object sender, EventArgs e) { @@ -1040,10 +974,8 @@ namespace PckStudio.Forms part.UV.Y = (int)TextureYUpDown.Value; } UpdateListView(); - Rerender(); } - //Export Current Skin Texture private void buttonEXPORT_Click(object sender, EventArgs e) { @@ -1056,7 +988,6 @@ namespace PckStudio.Forms } } - //Imports Skin Texture private void buttonIMPORT_Click(object sender, EventArgs e) { @@ -1077,7 +1008,6 @@ namespace PckStudio.Forms graphics.DrawImage(img, 0, 0, img.Width, img.Height); } uvPictureBox.Invalidate(); - Rerender(); } else { @@ -1094,45 +1024,28 @@ namespace PckStudio.Forms { _file.Properties.Add("BOX", part); } - - //Bitmap bitmap2 = new Bitmap(64, 64); - //using (Graphics graphics = Graphics.FromImage(bitmap2)) - //{ - // graphics.ApplyConfig(_graphicsConfig); - // graphics.DrawImage(uvPictureBox.Image, 0, 0, 64, 64); - //} Close(); } - // Renders model after texture change - private void texturePreview_BackgroundImageChanged(object sender, EventArgs e) - { - Rerender(); - } - // Trigger Dialog to select model part/item color private void listView1_DoubleClick(object sender, EventArgs e) { ColorDialog colorDialog = new ColorDialog(); if (colorDialog.ShowDialog() == DialogResult.OK) listViewBoxes.SelectedItems[0].ForeColor = colorDialog.Color; - Rerender(); } - //Re-renders head with updated x-offset private void offsetHead_TextChanged(object sender, EventArgs e) { - Rerender(); + } - //Re-renders body with updated x-offset private void offsetBody_TextAlignChanged(object sender, EventArgs e) { - Rerender(); - } + } //Loads in model template(Steve) private void buttonTemplate_Click(object sender, EventArgs e) @@ -1145,7 +1058,6 @@ namespace PckStudio.Forms modelBoxes.Add(SkinBOX.FromString("LEG1 -2 0 -2 4 12 4 0 16 0 1 0")); comboParent.Enabled = true; UpdateListView(); - Rerender(); } private void UpdateListView() @@ -1189,7 +1101,6 @@ namespace PckStudio.Forms File.WriteAllText(saveFileDialog.FileName, contents); } - // Imports model from csm file private void buttonImportModel_Click(object sender, EventArgs e) { @@ -1220,7 +1131,6 @@ namespace PckStudio.Forms } comboParent.Enabled = true; UpdateListView(); - Rerender(); } private void cloneToolStripMenuItem_Click(object sender, EventArgs e) @@ -1252,7 +1162,6 @@ namespace PckStudio.Forms if (listViewBoxes.SelectedItems[0] == null) return; listViewBoxes.SelectedItems[0].Remove(); - Rerender(); } private void changeColorToolStripMenuItem_Click(object sender, EventArgs e) @@ -1260,37 +1169,36 @@ namespace PckStudio.Forms ColorDialog colorDialog = new ColorDialog(); if (colorDialog.ShowDialog() == DialogResult.OK) listViewBoxes.SelectedItems[0].ForeColor = colorDialog.Color; - Rerender(); } //Re-renders tool with updated x-offset private void offsetTool_TextChanged(object sender, EventArgs e) { - Rerender(); + } //Re-renders helmet with updated x-offset private void offsetHelmet_TextChanged(object sender, EventArgs e) { - Rerender(); + } //Re-renders pants with updated x-offset private void offsetPants_TextChanged(object sender, EventArgs e) { - Rerender(); + } //Re-renders leggings with updated x-offset private void offsetLeggings_TextChanged(object sender, EventArgs e) { - Rerender(); + } //Re-renders boots with updated x-offset private void offsetBoots_TextChanged(object sender, EventArgs e) { - Rerender(); + } //Item Selection @@ -1328,13 +1236,13 @@ namespace PckStudio.Forms TextureXUpDown.Enabled = false; TextureYUpDown.Enabled = false; comboParent.Enabled = false; - Rerender(); + } //currently scrapped private void generateModel_FormClosing(object sender, FormClosingEventArgs e) - {/* - if (MessageBox.Show("You done here?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) + { + /*if (MessageBox.Show("You done here?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) { e.Cancel = true; return; @@ -1350,13 +1258,13 @@ namespace PckStudio.Forms { if (modelBoxes.Remove(part)) listViewBoxes.SelectedItems[0].Remove(); - Rerender(); + } } private void generateModel_SizeChanged(object sender, EventArgs e) { - Rerender(); + } // TODO @@ -1416,7 +1324,7 @@ namespace PckStudio.Forms } } } - Rerender(); + } [Obsolete("Just whyyyyy")] diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index e0ad7924..ef939342 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -149,6 +149,7 @@ Resources.resx + diff --git a/PCK-Studio/Rendering/CubeRenderGroup.cs b/PCK-Studio/Rendering/CubeRenderGroup.cs new file mode 100644 index 00000000..2bedf328 --- /dev/null +++ b/PCK-Studio/Rendering/CubeRenderGroup.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenTK; +using OpenTK.Graphics.OpenGL; +using PckStudio.Extensions; +using PckStudio.Internal; + +namespace PckStudio.Rendering +{ + internal class CubeRenderGroup : RenderGroup + { + private const int vertexCountPerCube = 16; + + internal CubeRenderGroup(string name) + : base(name, new VertexBufferLayout().Add(3).Add(2), PrimitiveType.Quads) + { + } + + internal void AddSkinBox(SkinBOX skinBox) + { + AddCube(skinBox.Pos.ToOpenTKVector(), skinBox.Size.ToOpenTKVector(), skinBox.UV.ToOpenTKVector(), skinBox.Scale, skinBox.Mirror); + } + + internal void AddCube(Vector3 position, Vector3 size, Vector2 uv, float scale = 0f, bool mirror = false) + { + var vertexData = GetCubeVertexData(position, size, uv, scale, mirror); + + vertices.AddRange(vertexData); + + var indexStorage = new uint[] { + // Face 1 (Front) + 0, 1, 2, 3, + // Face 2 (Back) + 4, 5, 6, 7, + // Face 3 (Right) + 4, 8, 9, 7, + // Face 4 (Left) + 1, 5, 6, 2, + // Face 5 (Top) + 10, 11, 4, 5, + // Face 6 (Bottom) + 12, 13, 14, 15 + }; + indices.AddRange(indexStorage.Select(n => n + indicesOffset)); + indicesOffset += vertexCountPerCube; + } + + internal void ReplaceCube(int index, Vector3 position, Vector3 size, Vector2 uv, float scale = 0f, bool mirror = false) + { + if (index * vertexCountPerCube > vertices.Count || index < 0) + throw new IndexOutOfRangeException(); + + vertices.InsertRange(index * vertexCountPerCube, GetCubeVertexData(position, size, uv, scale, mirror)); + } + + // TODO: add mirroring support + private TextureVertex[] GetCubeVertexData(Vector3 position, Vector3 size, Vector2 uv, float scale, bool mirror) + { + return new TextureVertex[] + { + new TextureVertex(new Vector3(position.X , size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z)), + new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z)), + new TextureVertex(new Vector3(size.X + position.X, position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z + size.Y)), + new TextureVertex(new Vector3(position.X , position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z + size.Y)), + + new TextureVertex(new Vector3(position.X , size.Y + position.Y, -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y + size.Z)), + new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z)), + new TextureVertex(new Vector3(size.X + position.X, position.Y , -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z + size.Y)), + new TextureVertex(new Vector3(position.X , position.Y , -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y)), + + new TextureVertex(new Vector3(position.X , size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X, uv.Y + size.Z)), + new TextureVertex(new Vector3(position.X , position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X, uv.Y + size.Z + size.Y)), + new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y)), + new TextureVertex(new Vector3(position.X , size.Y + position.Y, -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y)), + + new TextureVertex(new Vector3(size.X + position.X, position.Y , -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X * 2, uv.Y)), + new TextureVertex(new Vector3(position.X , position.Y , -position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y)), + new TextureVertex(new Vector3(position.X , position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z)), + new TextureVertex(new Vector3(size.X + position.X, position.Y , -(size.Z + position.Z)) * (scale + 1f), new Vector2(uv.X + size.Z + size.X * 2, uv.Y + size.Z)), + }; + } + } +} diff --git a/PCK-Studio/Rendering/IndexBuffer.cs b/PCK-Studio/Rendering/IndexBuffer.cs index 40c0c097..ee4d5321 100644 --- a/PCK-Studio/Rendering/IndexBuffer.cs +++ b/PCK-Studio/Rendering/IndexBuffer.cs @@ -11,17 +11,33 @@ namespace PckStudio.Rendering internal class IndexBuffer : IDisposable { private int _id; - private int _count; + private List _indecies; public IndexBuffer(params uint[] indecies) { - _id = GL.GenBuffer(); - _count = indecies.Length; - Bind(); - GL.BufferData(BufferTarget.ElementArrayBuffer, indecies.Length * sizeof(uint), indecies, BufferUsageHint.StaticDraw); + _indecies = new List(indecies); } - public int GetCount() => _count; + /// + /// Creates and attaches created index buffer + /// + /// + /// + public static IndexBuffer Create(params uint[] indecies) + { + var ib = new IndexBuffer(indecies); + ib.Attach(); + return ib; + } + + public void Attach() + { + _id = GL.GenBuffer(); + Bind(); + GL.BufferData(BufferTarget.ElementArrayBuffer, _indecies.Count * sizeof(uint), _indecies.ToArray(), BufferUsageHint.StaticDraw); + } + + public int GetCount() => _indecies.Count; public void Bind() { diff --git a/PCK-Studio/Rendering/RenderGroup.cs b/PCK-Studio/Rendering/RenderGroup.cs index 62d559d6..1bc7eab1 100644 --- a/PCK-Studio/Rendering/RenderGroup.cs +++ b/PCK-Studio/Rendering/RenderGroup.cs @@ -1,125 +1,51 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using OpenTK; +using System.Runtime.InteropServices; using OpenTK.Graphics.OpenGL; -using PckStudio.Extensions; -using PckStudio.Internal; namespace PckStudio.Rendering { - internal class RenderGroup + internal class RenderGroup where T : struct { internal string Name { get; } - private List vertices; - private List indices; - private uint indicesOffset; + internal static int SizeInBytes = Marshal.SizeOf(); + + protected List vertices; + protected List indices; + protected uint indicesOffset; + private VertexArray vertexArray; - private VertexBuffer vertexBuffer; + private VertexBuffer vertexBuffer; private IndexBuffer indexBuffer; - private readonly VertexBufferLayout layout; + private readonly VertexBufferLayout _layout; private readonly PrimitiveType drawType; - private const int vertexCountPerBox = 16; - internal RenderGroup(string name, PrimitiveType type = PrimitiveType.Quads) + internal RenderGroup(string name, VertexBufferLayout layout, PrimitiveType type) { Name = name; drawType = type; - vertices = new List(10); - indices = new List(10); indicesOffset = 0; - layout = new VertexBufferLayout(); - layout.Add(3); - layout.Add(2); + vertices = new List(10); + indices = new List(10); + _layout = layout; } internal RenderBuffer GetRenderBuffer() { - //vertexArray?.Dispose(); indexBuffer?.Dispose(); vertexBuffer.Dispose(); - - var vertexData = vertices.ToArray(); - vertexBuffer = new VertexBuffer(vertexData, vertexData.Length * TextureVertex.SizeInBytes); - vertexArray ??= new VertexArray(); - vertexArray.AddBuffer(vertexBuffer, layout); + var vertexData = vertices.ToArray(); + vertexBuffer = new VertexBuffer(vertexData, vertexData.Length * SizeInBytes); - indexBuffer = new IndexBuffer(indices.ToArray()); + vertexArray.AddBuffer(vertexBuffer, _layout); + + indexBuffer = IndexBuffer.Create(indices.ToArray()); return new RenderBuffer(vertexArray, indexBuffer, drawType); } - - // TODO: add mirroring support - internal void AddBox(SkinBOX skinBox) - { - AddBox(skinBox.Pos.ToOpenTKVector(), skinBox.Size.ToOpenTKVector(), skinBox.UV.ToOpenTKVector(), skinBox.Scale); - } - - - internal void AddBox(Vector3 position, Vector3 size, Vector2 uv, float scale = 0f) - { - var vertexData = GetCubeVertexData(position, size, uv, scale); - - vertices.AddRange(vertexData); - - var indexStorage = new uint[] { - 0 + indicesOffset, 1 + indicesOffset, 2 + indicesOffset, 3 + indicesOffset, // Face 1 (Front) - 4 + indicesOffset, 5 + indicesOffset, 6 + indicesOffset, 7 + indicesOffset, // Face 2 (Back) - 0 + indicesOffset, 8 + indicesOffset, 9 + indicesOffset, 3 + indicesOffset, // Face 3 (Left) - 1 + indicesOffset, 5 + indicesOffset, 6 + indicesOffset, 2 + indicesOffset, // Face 4 (Right) - 0 + indicesOffset, 1 + indicesOffset, 10 + indicesOffset, 11 + indicesOffset, // Face 5 (Top) - 13 + indicesOffset, 12 + indicesOffset, 14 + indicesOffset, 15 + indicesOffset // Face 6 (Bottom) - }; - indicesOffset += vertexCountPerBox; - indices.AddRange(indexStorage); - } - - internal void ReplaceBox(int index, Vector3 position, Vector3 size, Vector2 uv, float scale = 0f) - { - if (index * vertexCountPerBox > vertices.Count || index < 0) - throw new IndexOutOfRangeException(); - - vertices.InsertRange(index * vertexCountPerBox, GetCubeVertexData(position, size, uv, scale)); - } - - private TextureVertex[] GetCubeVertexData(Vector3 position, Vector3 size, Vector2 uv, float scale) - { - return new TextureVertex[] - { - new TextureVertex(new Vector3(position.X , size.Y + position.Y, size.Z + position.Z) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y + size.Z)), - new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, size.Z + position.Z) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z)), - new TextureVertex(new Vector3(size.X + position.X, position.Y , size.Z + position.Z) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z + size.Y)), - new TextureVertex(new Vector3(position.X , position.Y , size.Z + position.Z) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y)), - - new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z)), - new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z)), - new TextureVertex(new Vector3(size.X + position.X, position.Y , position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z + size.Y)), - new TextureVertex(new Vector3(position.X , position.Y , position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z + size.Y)), - - new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X, uv.Y + size.Z)), - new TextureVertex(new Vector3(position.X , position.Y , position.Z ) * (scale + 1f), new Vector2(uv.X, uv.Y + size.Z + size.Y)), - new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z + size.X, uv.Y)), - new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z ) * (scale + 1f), new Vector2(uv.X + size.Z, uv.Y)), - - new TextureVertex( - new Vector3(position.X , position.Y , size.Z + position.Z) * (scale + 1f), - new Vector2(uv.X + size.Z + size.X, uv.Y)), - new TextureVertex( - new Vector3(size.X + position.X, position.Y , size.Z + position.Z) * (scale + 1f), - new Vector2(uv.X + size.Z + size.X * 2, uv.Y)), - new TextureVertex( - new Vector3(position.X , position.Y , position.Z ) * (scale + 1f), - new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z)), - new TextureVertex( - new Vector3(size.X + position.X, position.Y , position.Z ) * (scale + 1f), - new Vector2(uv.X + size.Z + size.X * 2, uv.Y + size.Z)), - }; - } } } \ No newline at end of file diff --git a/PCK-Studio/Rendering/Renderer3D.cs b/PCK-Studio/Rendering/Renderer3D.cs index 3ded20f9..95af604a 100644 --- a/PCK-Studio/Rendering/Renderer3D.cs +++ b/PCK-Studio/Rendering/Renderer3D.cs @@ -38,7 +38,7 @@ namespace PckStudio.Rendering public Renderer3D() { VSync = true; - camera = new PerspectiveCamera(Vector2.Zero, 1f, Vector2.Zero, 30f); + camera = new PerspectiveCamera(Vector3.UnitZ, Vector2.Zero, 30f); } } } diff --git a/PCK-Studio/Rendering/SkinRenderer.cs b/PCK-Studio/Rendering/SkinRenderer.cs index 0931a486..5c7f362e 100644 --- a/PCK-Studio/Rendering/SkinRenderer.cs +++ b/PCK-Studio/Rendering/SkinRenderer.cs @@ -14,6 +14,8 @@ using System.Drawing; using System.Runtime.InteropServices; using PckStudio.Properties; using PckStudio.Forms.Editor; +using System.Windows.Media.Imaging; +using System.Xml.Linq; namespace PckStudio.Rendering { @@ -25,24 +27,7 @@ namespace PckStudio.Rendering /// The visible Texture [Description("The current Texture")] [Category("Appearance")] - public Bitmap Texture - { - get => _texture; - set - { - if (value is null) - return; - - if (HasValidContext && skinShader is not null) - { - var texture = new Texture2D(value); - texture.Bind(0); - skinShader.SetUniform1("u_Texture", 0); - Refresh(); - } - _texture = value; - } - } + public Bitmap Texture { get; set; } [Description("Anim flags for special effects applied to the skin")] [Category("Appearance")] @@ -62,13 +47,12 @@ namespace PckStudio.Rendering [Description("The offset from the orignal point (for zoom)")] [Category("Appearance")] - public Vector2 LookAngle + public Vector2 CameraTarget { get => camera.Position; set => camera.LookAt(value); } - private void GLDebugMessage(DebugSource source, DebugType type, int id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam) { string msg = Marshal.PtrToStringAnsi(message, length); @@ -90,12 +74,25 @@ namespace PckStudio.Rendering } } - private Bitmap _texture; - private Vector2 TextureScaleValue = new Vector2(1f / 64); + private Vector2 UvTranslation = new Vector2(1f / 64); private const float OverlayScale = 0.1f; private bool IsLeftMouseDown; private bool IsRightMouseDown; + + private Bitmap RenderTexture + { + set + { + if (HasValidContext && skinShader is not null) + { + var texture = new Texture2D(value); + texture.Bind(0); + skinShader.SetUniform1("u_Texture", 0); + Refresh(); + } + } + } private bool IsMouseHidden { get => !Cursor.IsVisible(); @@ -115,61 +112,46 @@ namespace PckStudio.Rendering private Shader skinShader; private SkinANIM _anim; - private Dictionary defaultRenderGroups; - private Dictionary additionalModelRenderGroups; + private Dictionary additionalModelRenderGroups; + private CubeRenderGroup head; + private CubeRenderGroup headOverlay; + private CubeRenderGroup body; + private CubeRenderGroup bodyOverlay; + private CubeRenderGroup rightArm; + private CubeRenderGroup rightArmOverlay; + private CubeRenderGroup leftArm; + private CubeRenderGroup leftArmOverlay; + private CubeRenderGroup rightLeg; + private CubeRenderGroup rightLegOverlay; + private CubeRenderGroup leftLeg; + private CubeRenderGroup leftLegOverlay; + private float animationRot; private float animationRotStep = 1f; - public SkinRenderer() + public SkinRenderer() : base() { InitializeComponent(); InitializeCamera(); + InitializeSkinData(); _anim = new SkinANIM(); // use backing field to not raise OnANIMUpdate - defaultRenderGroups = new Dictionary(6) + additionalModelRenderGroups = new Dictionary(6) { - { "HEAD", new RenderGroup("HEAD") }, - { "BODY", new RenderGroup("BODY") }, - { "ARM0", new RenderGroup("ARM0") }, - { "ARM1", new RenderGroup("ARM1") }, - { "LEG0", new RenderGroup("LEG0") }, - { "LEG1", new RenderGroup("LEG1") }, - - { "HEADWEAR", new RenderGroup("HEADWEAR") }, - { "JACKET", new RenderGroup("JACKET")}, - { "SLEEVE0", new RenderGroup("SLEEVE0")}, - { "SLEEVE1", new RenderGroup("SLEEVE1")}, - { "LEGGING0", new RenderGroup("LEGGING0")}, - { "LEGGING1", new RenderGroup("LEGGING1")}, - - //{ "PANTS0", new RenderGroup("PANTS0")}, - //{ "PANTS1", new RenderGroup("PANTS1")}, - //{ "WAIST", new RenderGroup("WAIST")}, - //{ "SOCK0", new RenderGroup("SOCK0")}, - //{ "SOCK1", new RenderGroup("SOCK1")}, - //{ "BOOT0", new RenderGroup("BOOT0")}, - //{ "BOOT1", new RenderGroup("BOOT1")}, - //{ "ARMARMOR1", new RenderGroup("ARMARMOR1")}, - //{ "ARMARMOR0", new RenderGroup("ARMARMOR0")}, - //{ "BODYARMOR", new RenderGroup("BODYARMOR")}, - //{ "BELT", new RenderGroup("BELT")}, - }; - additionalModelRenderGroups = new Dictionary(6) - { - { "HEAD", new RenderGroup("HEAD") }, - { "BODY", new RenderGroup("BODY") }, - { "ARM0", new RenderGroup("ARM0") }, - { "ARM1", new RenderGroup("ARM1") }, - { "LEG0", new RenderGroup("LEG0") }, - { "LEG1", new RenderGroup("LEG1") }, + { "HEAD", new CubeRenderGroup("HEAD") }, + { "BODY", new CubeRenderGroup("BODY") }, + { "ARM0", new CubeRenderGroup("ARM0") }, + { "ARM1", new CubeRenderGroup("ARM1") }, + { "LEG0", new CubeRenderGroup("LEG0") }, + { "LEG1", new CubeRenderGroup("LEG1") }, - { "HEADWEAR", new RenderGroup("HEADWEAR") }, - { "JACKET", new RenderGroup("JACKET")}, - { "SLEEVE0", new RenderGroup("SLEEVE0")}, - { "SLEEVE1", new RenderGroup("SLEEVE1")}, - { "LEGGING0", new RenderGroup("LEGGING0")}, - { "LEGGING1", new RenderGroup("LEGGING1")}, + { "HEADWEAR", new CubeRenderGroup("HEADWEAR") }, + { "JACKET" , new CubeRenderGroup("JACKET")}, + { "SLEEVE0" , new CubeRenderGroup("SLEEVE0")}, + { "SLEEVE1" , new CubeRenderGroup("SLEEVE1")}, + { "PANTS0" , new CubeRenderGroup("PANTS0")}, + { "PANTS1" , new CubeRenderGroup("PANTS1")}, }; } @@ -183,6 +165,45 @@ namespace PckStudio.Rendering }; } + private void InitializeSkinData() + { + head = new CubeRenderGroup("Head"); + head.AddCube(new(-4, -8, -4), new(8, 8, 8), new(0, 0)); + + headOverlay = new CubeRenderGroup("Head overlay"); + headOverlay.AddCube(new(-4, -8, -4), new(8, 8, 8), new(32, 0), scale: OverlayScale); + + body = new CubeRenderGroup("Body"); + body.AddCube(new(-4, 0, -2), new(8, 12, 4), new(16, 16)); + + bodyOverlay = new CubeRenderGroup("Body overlay"); + bodyOverlay.AddCube(new(-4, 0, -2), new(8, 12, 4), new(16, 32), scale: OverlayScale); + + rightArm = new CubeRenderGroup("Right arm"); + rightArm.AddCube(new(-3, -2, -2), new(4, 12, 4), new(40, 16)); + + rightArmOverlay = new CubeRenderGroup("Right arm overlay"); + rightArmOverlay.AddCube(new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale); + + leftArm = new CubeRenderGroup("Left arm"); + leftArm.AddCube(new(-1, -2, -2), new(4, 12, 4), new(32, 48)); + + leftArmOverlay = new CubeRenderGroup("Left arm overlay"); + leftArmOverlay.AddCube(new(-1, -2, -2), new(4, 12, 4), new(48, 48), scale: OverlayScale); + + rightLeg = new CubeRenderGroup("Right leg"); + rightLeg.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 16)); + + rightLegOverlay = new CubeRenderGroup("Right leg overlay"); + rightLegOverlay.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 32), scale: OverlayScale); + + leftLeg = new CubeRenderGroup("Left leg"); + leftLeg.AddCube(new(-2, 0, -2), new(4, 12, 4), new(16, 48)); + + leftLegOverlay = new CubeRenderGroup("Left leg overlay"); + leftLegOverlay.AddCube(new(-2, 0, -2), new(4, 12, 4), new(0, 48), scale: OverlayScale); + } + protected override void OnLoad(EventArgs e) { base.OnLoad(e); @@ -197,40 +218,9 @@ namespace PckStudio.Rendering skinShader = Shader.Create(Resources.skinVertexShader, Resources.skinFragment); skinShader.Bind(); - if (_texture is null) - { - Texture = Resources.classic_template; - if (Texture.Size == new Size(64, 64)) - { - ANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true); - } - } + Texture ??= Resources.classic_template; - var headbox = new SkinBOX("HEAD", new(-4, -8, -4), new(8, 8, 8), new( 0, 0)); - var headoverlaybox = new SkinBOX("HEADWEAR", new(-4, -8, -4), new(8, 8, 8), new(32, 0), scale: OverlayScale); - var bodybox = new SkinBOX("BODY", new(-4, 0, -2), new(8, 12, 4), new(16, 16)); - var bodyoverlaybox = new SkinBOX("JACKET", new(-4, 0, -2), new(8, 12, 4), new(16, 32), scale: OverlayScale); - var arm0box = new SkinBOX("ARM0", new(-3, -2, -2), new(4, 12, 4), new(40, 16)); - var arm1box = new SkinBOX("ARM1", new(-1, -2, -2), new(4, 12, 4), new(32, 48)); - var arm0overlaybox = new SkinBOX("SLEEVE0", new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale); - var arm1overlaybox = new SkinBOX("SLEEVE1", new(-1, -2, -2), new(4, 12, 4), new(48, 48), scale: OverlayScale); - var leg0box = new SkinBOX("LEG0", new(-2, 0, -2), new(4, 12, 4), new( 0, 16)); - var leg0overlaybox = new SkinBOX("LEGGING0", new(-2, 0, -2), new(4, 12, 4), new( 0, 32), scale: OverlayScale); - var leg1box = new SkinBOX("LEG1", new(-2, 0, -2), new(4, 12, 4), new(16, 48)); - var leg1overlaybox = new SkinBOX("LEGGING1", new(-2, 0, -2), new(4, 12, 4), new( 0, 48), scale: OverlayScale); - - AddToGroup(headbox); - AddToGroup(headoverlaybox); - AddToGroup(bodybox); - AddToGroup(bodyoverlaybox); - AddToGroup(arm0box); - AddToGroup(arm0overlaybox); - AddToGroup(arm1box); - AddToGroup(arm1overlaybox); - AddToGroup(leg0box); - AddToGroup(leg0overlaybox); - AddToGroup(leg1box); - AddToGroup(leg1overlaybox); + RenderTexture = Texture; foreach (var item in ModelData) { @@ -240,20 +230,22 @@ namespace PckStudio.Rendering GLErrorCheck(); } + public void Reload() + { + additionalModelRenderGroups.Clear(); + foreach (var item in ModelData) + { + AddCustomModelPart(item); + } + Refresh(); + } + private void AddCustomModelPart(SkinBOX skinBox) { if (!additionalModelRenderGroups.ContainsKey(skinBox.Type)) throw new KeyNotFoundException(skinBox.Type); - additionalModelRenderGroups[skinBox.Type].AddBox(skinBox); - } - - private void AddToGroup(SkinBOX skinBox) - { - if (!defaultRenderGroups.ContainsKey(skinBox.Type)) - throw new KeyNotFoundException(skinBox.Type); - - defaultRenderGroups[skinBox.Type].AddBox(skinBox); + additionalModelRenderGroups[skinBox.Type].AddSkinBox(skinBox); } [Conditional("DEBUG")] @@ -276,7 +268,7 @@ namespace PckStudio.Rendering break; case Keys.R: GlobalModelRotation = Vector2.Zero; - LookAngle = Vector2.Zero; + CameraTarget = Vector2.Zero; Refresh(); return true; case Keys.F1: @@ -286,11 +278,14 @@ namespace PckStudio.Rendering }; if (fileDialog.ShowDialog() == DialogResult.OK) { - Texture = Image.FromFile(fileDialog.FileName) as Bitmap; + RenderTexture = Texture = Image.FromFile(fileDialog.FileName) as Bitmap; } return true; case Keys.F3: - + foreach (var item in ModelData) + { + Debug.WriteLine(item); + } return true; case Keys.A: { @@ -312,23 +307,23 @@ namespace PckStudio.Rendering if (slim || ANIM.GetFlag(SkinAnimFlag.RESOLUTION_64x64)) { int slimValue = slim ? 3 : 4; - TextureScaleValue = new Vector2(1f / 64); - defaultRenderGroups["ARM0"].ReplaceBox(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 16)); - defaultRenderGroups["ARM1"].ReplaceBox(0, new(-1, -2, -2), new(slimValue, 12, 4), new(32, 48)); - defaultRenderGroups["SLEEVE0"].ReplaceBox(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 32), scale: OverlayScale); - defaultRenderGroups["SLEEVE1"].ReplaceBox(0, new(-1, -2, -2), new(slimValue, 12, 4), new(48, 48), scale: OverlayScale); + UvTranslation = new Vector2(1f / 64); + rightArm.ReplaceCube(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 16)); + rightArmOverlay.ReplaceCube(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 32), scale: OverlayScale); + leftArm.ReplaceCube(0, new(-1, -2, -2), new(slimValue, 12, 4), new(32, 48)); + leftArmOverlay.ReplaceCube(0, new(-1, -2, -2), new(slimValue, 12, 4), new(48, 48), scale: OverlayScale); - defaultRenderGroups["LEG0"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16)); - defaultRenderGroups["LEG1"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(16, 48)); + rightLeg.ReplaceCube(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16)); + leftLeg.ReplaceCube(0, new(-2, 0, -2), new(4, 12, 4), new(16, 48)); return; } - TextureScaleValue = new Vector2(1f / 64, 1f / 32); - defaultRenderGroups["ARM0"].ReplaceBox(0, new(-3, -2, -2), new(4, 12, 4), new(40, 16)); - defaultRenderGroups["ARM1"].ReplaceBox(0, new(-1, -2, -2), new(4, 12, 4), new(40, 16)); - defaultRenderGroups["LEG0"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16)); - defaultRenderGroups["LEG1"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16)); - defaultRenderGroups["SLEEVE0"].ReplaceBox(0, new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale); - defaultRenderGroups["SLEEVE1"].ReplaceBox(0, new(-1, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale); + UvTranslation = new Vector2(1f / 64, 1f / 32); + rightArm.ReplaceCube(0, new(-3, -2, -2), new(4, 12, 4), new(40, 16)); + leftArm.ReplaceCube(0, new(-1, -2, -2), new(4, 12, 4), new(40, 16)); + rightLeg.ReplaceCube(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16)); + leftLeg.ReplaceCube(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16)); + rightArmOverlay.ReplaceCube(0, new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale); + leftArmOverlay.ReplaceCube(0, new(-1, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale); } protected override void OnPaint(PaintEventArgs e) @@ -345,7 +340,7 @@ namespace PckStudio.Rendering var viewProjection = camera.GetViewProjection(); skinShader.SetUniformMat4("u_ViewProjection", ref viewProjection); - skinShader.SetUniform2("u_TexScale", TextureScaleValue); + skinShader.SetUniform2("u_TexScale", UvTranslation); GL.Viewport(Size); @@ -356,7 +351,6 @@ namespace PckStudio.Rendering GL.Enable(EnableCap.Texture2D); // Enable textures GL.Enable(EnableCap.DepthTest); // Enable correct Z Drawings GL.DepthFunc(DepthFunction.Lequal); // Enable correct Z Drawings - GL.Disable(EnableCap.AlphaTest); // Disable transparent GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); @@ -364,20 +358,45 @@ namespace PckStudio.Rendering GL.Enable(EnableCap.AlphaTest); // Enable transparent GL.AlphaFunc(AlphaFunction.Greater, 0.4f); - Matrix4 modelRotationMatrix = Matrix4.CreateFromAxisAngle(new Vector3(-1f, 0f, 0f), MathHelper.DegreesToRadians(GlobalModelRotation.X)) - * Matrix4.CreateFromAxisAngle(new Vector3(0f, 1f, 0f), MathHelper.DegreesToRadians(GlobalModelRotation.Y)); - - - RenderSkinPartIf("HEAD" , !ANIM.GetFlag(SkinAnimFlag.HEAD_DISABLED), new Vector3(0f, 16f, 0f), modelRotationMatrix); - RenderSkinPartIf("HEADWEAR", !ANIM.GetFlag(SkinAnimFlag.HEAD_OVERLAY_DISABLED), new Vector3(0f, 16f + OverlayScale, 0f), modelRotationMatrix); + Matrix4 modelMatrix = + Matrix4.CreateFromAxisAngle(-Vector3.UnitX, MathHelper.DegreesToRadians(GlobalModelRotation.X)) + * Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(GlobalModelRotation.Y)); - RenderSkinPartIf("BODY" , !ANIM.GetFlag(SkinAnimFlag.BODY_DISABLED), new Vector3(0f, -4f, 0f), modelRotationMatrix); - RenderSkinPartIf("JACKET", !ANIM.GetFlag(SkinAnimFlag.BODY_OVERLAY_DISABLED), new Vector3(0f, -4f + OverlayScale, 0f), modelRotationMatrix); + RenderSkin(modelMatrix); +#if true + RenderAdditionalModelData("HEAD", new Vector3(0f, 0f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelMatrix); + RenderAdditionalModelData("BODY", new Vector3(0f, -4f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelMatrix); + //RenderAdditionalModelData("ARM0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); + //RenderAdditionalModelData("ARM1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); + //RenderAdditionalModelData("LEG0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); + //RenderAdditionalModelData("LEG1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); +#endif + SwapBuffers(); + } + + private void RenderSkin(Matrix4 modelMatrix) + { + if (!ANIM.GetFlag(SkinAnimFlag.HEAD_DISABLED)) + { + RenderSkinPart(head.GetRenderBuffer(), new Vector3(0f, 16f, 0f), modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.HEAD_OVERLAY_DISABLED)) + { + RenderSkinPart(headOverlay.GetRenderBuffer(), new Vector3(0f, 16f + OverlayScale, 0f), modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.BODY_DISABLED)) + { + RenderSkinPart(body.GetRenderBuffer(), new Vector3(0f, -4f, 0f), modelMatrix); + } + + bool slimModel = ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL); var extraRightRotation = Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(animationRot)); - var extraLeftRotation = Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(-animationRot)); - var translationRight = new Vector3(ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL) ? -4f : -5f, -2f, 0f); - var translationLeft = new Vector3(5f, -2f, 0f); + var extraLeftRotation = Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(-animationRot)); + var translationRight = new Vector3(slimModel ? -4f : -5f, -2f, 0f); + var translationLeft = new Vector3(5f, -2f, 0f); if (ANIM.GetFlag(SkinAnimFlag.ZOMBIE_ARMS)) { extraRightRotation *= Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(-90f)); @@ -385,43 +404,61 @@ namespace PckStudio.Rendering translationRight.Yz = translationLeft.Yz = new Vector2(-8f, 6f); } - RenderSkinPartIf("ARM0" , !ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED) , translationRight, extraRightRotation * modelRotationMatrix); - RenderSkinPartIf("SLEEVE0", !ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED), translationRight, extraRightRotation * modelRotationMatrix); - - RenderSkinPartIf("ARM1" , !ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED) , translationLeft , extraLeftRotation * modelRotationMatrix); - RenderSkinPartIf("SLEEVE1", !ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED) , translationLeft , extraLeftRotation * modelRotationMatrix); - - RenderSkinPartIf("LEG0" , !ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED) , new Vector3(-2f, -16f, 0f), modelRotationMatrix); - RenderSkinPartIf("LEGGING0", !ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_OVERLAY_DISABLED), new Vector3(-2f, -16f, 0f), modelRotationMatrix); - - RenderSkinPartIf("LEG1" , !ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED) , new Vector3( 2f, -16f, 0f), modelRotationMatrix); - RenderSkinPartIf("LEGGING1", !ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_OVERLAY_DISABLED) , new Vector3( 2f, -16f, 0f), modelRotationMatrix); - -#if flase - RenderAdditionalModelData("HEAD", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); - RenderAdditionalModelData("BODY", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); - RenderAdditionalModelData("ARM0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); - RenderAdditionalModelData("ARM1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); - RenderAdditionalModelData("LEG0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); - RenderAdditionalModelData("LEG1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix); -#endif - SwapBuffers(); - } - - private void RenderSkinPartIf(string name, bool condition, Vector3 translation, Matrix4 rotation) - { - if (condition) + if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED)) { - RenderSkinPart(name, translation, rotation); + RenderSkinPart(rightArm.GetRenderBuffer(), translationRight, extraRightRotation * modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED)) + { + RenderSkinPart(leftArm.GetRenderBuffer(), translationLeft, extraLeftRotation * modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED)) + { + RenderSkinPart(rightLeg.GetRenderBuffer(), new Vector3(-2f, -16f, 0f), modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED)) + { + RenderSkinPart(leftLeg.GetRenderBuffer(), new Vector3(2f, -16f, 0f), modelMatrix); + } + + if (ANIM.GetFlag(SkinAnimFlag.RESOLUTION_64x64) || slimModel) + { + if (!ANIM.GetFlag(SkinAnimFlag.BODY_OVERLAY_DISABLED)) + { + RenderSkinPart(bodyOverlay.GetRenderBuffer(), new Vector3(0f, -4f + OverlayScale, 0f), modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED)) + { + RenderSkinPart(rightArmOverlay.GetRenderBuffer(), translationRight, extraRightRotation * modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED)) + { + RenderSkinPart(leftArmOverlay.GetRenderBuffer(), translationLeft, extraLeftRotation * modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_OVERLAY_DISABLED)) + { + RenderSkinPart(rightLegOverlay.GetRenderBuffer(), new Vector3(-2f, -16f, 0f), modelMatrix); + } + + if (!ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_OVERLAY_DISABLED)) + { + RenderSkinPart(leftLegOverlay.GetRenderBuffer(), new Vector3(2f, -16f, 0f), modelMatrix); + } } } - private void RenderSkinPart(string name, Vector3 translation, Matrix4 rotation) + private void RenderSkinPart(RenderBuffer buffer, Vector3 translation, Matrix4 rotation) { var transform = Matrix4.CreateTranslation(translation); var model = transform * rotation; skinShader.SetUniformMat4("u_Model", ref model); - Renderer.Draw(skinShader, defaultRenderGroups[name].GetRenderBuffer()); + Renderer.Draw(skinShader, buffer); } private void RenderAdditionalModelData(string name, Vector3 translation, Matrix4 rotation) @@ -508,7 +545,7 @@ namespace PckStudio.Rendering { float deltaX = -(Cursor.Position.X - MouseLoc.X) * 0.05f / (float)MathHelper.DegreesToRadians(camera.Fov); float deltaY = (Cursor.Position.Y - MouseLoc.Y) * 0.05f / (float)MathHelper.DegreesToRadians(camera.Fov); - LookAngle += new Vector2(deltaX, deltaY); + CameraTarget += new Vector2(deltaX, deltaY); Refresh(); Cursor.Position = new Point((int)Math.Round(Screen.PrimaryScreen.Bounds.Width / 2d), (int)Math.Round(Screen.PrimaryScreen.Bounds.Height / 2d)); MouseLoc = Cursor.Position; diff --git a/PCK-Studio/Rendering/VertexBufferLayout.cs b/PCK-Studio/Rendering/VertexBufferLayout.cs index c9f902ac..b5f9261c 100644 --- a/PCK-Studio/Rendering/VertexBufferLayout.cs +++ b/PCK-Studio/Rendering/VertexBufferLayout.cs @@ -50,7 +50,7 @@ namespace PckStudio.Rendering return elements.AsReadOnly(); } - public void Add(int count) + public VertexBufferLayout Add(int count) { if (typeof(T).Equals(typeof(float))) { @@ -67,6 +67,7 @@ namespace PckStudio.Rendering elements.Add(new VertexBufferElement(VertexAttribPointerType.UnsignedInt, count, false)); stride += count * VertexBufferElement.GetStrideSize(VertexAttribPointerType.UnsignedInt); } + return this; } internal int GetStride()