diff --git a/PCK-Studio/Extensions/System.Numerics.cs b/PCK-Studio/Extensions/System.Numerics.cs
new file mode 100644
index 00000000..80520983
--- /dev/null
+++ b/PCK-Studio/Extensions/System.Numerics.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PckStudio.Extensions
+{
+ internal static class NumericsExtensions
+ {
+ internal static OpenTK.Vector3 ToOpenTKVector(this System.Numerics.Vector3 vector3)
+ {
+ return new OpenTK.Vector3(vector3.X, vector3.Y, vector3.Z);
+ }
+
+ internal static OpenTK.Vector2 ToOpenTKVector(this System.Numerics.Vector2 vector3)
+ {
+ return new OpenTK.Vector2(vector3.X, vector3.Y);
+ }
+ }
+}
diff --git a/PCK-Studio/Forms/Skins-And-Textures/SkinPreview.cs b/PCK-Studio/Forms/Skins-And-Textures/SkinPreview.cs
index c0ee08a3..5a2370a5 100644
--- a/PCK-Studio/Forms/Skins-And-Textures/SkinPreview.cs
+++ b/PCK-Studio/Forms/Skins-And-Textures/SkinPreview.cs
@@ -14,7 +14,6 @@ namespace PckStudio.Forms
{
InitializeComponent();
Texture = texture;
- ModelView.Model = anim.GetFlag(SkinAnimFlag.SLIM_MODEL) ? Renderer3D.Models.Alex : Renderer3D.Models.Steve;
//ModelView.ShowHead = !anim.GetFlag(SkinAnimFlag.HEAD_DISABLED);
//ModelView.ShowHeadOverlay = !anim.GetFlag(SkinAnimFlag.HEAD_OVERLAY_DISABLED);
@@ -36,7 +35,7 @@ namespace PckStudio.Forms
public void RenderModel(Image source)
{
- ModelView.Texture = source as Bitmap;
+ //ModelView.Texture = source as Bitmap;
}
}
}
diff --git a/PCK-Studio/Forms/Skins-And-Textures/generateModel.Designer.cs b/PCK-Studio/Forms/Skins-And-Textures/generateModel.Designer.cs
index 477cd96c..3384a257 100644
--- a/PCK-Studio/Forms/Skins-And-Textures/generateModel.Designer.cs
+++ b/PCK-Studio/Forms/Skins-And-Textures/generateModel.Designer.cs
@@ -542,14 +542,8 @@
//
resources.ApplyResources(this.renderer3D1, "renderer3D1");
this.renderer3D1.BackColor = System.Drawing.Color.DarkGray;
- this.renderer3D1.CameraDistance = 72F;
- this.renderer3D1.LookAngle = ((OpenTK.Vector2)(resources.GetObject("renderer3D1.LookAngle")));
- this.renderer3D1.Model = PckStudio.Rendering.Renderer3D.Models.Steve;
this.renderer3D1.Name = "renderer3D1";
- this.renderer3D1.Rotation = ((OpenTK.Vector2)(resources.GetObject("renderer3D1.Rotation")));
- this.renderer3D1.Texture = null;
this.renderer3D1.VSync = true;
- this.renderer3D1.FieldOfView = 1D;
//
// uvPictureBox
//
diff --git a/PCK-Studio/Forms/Skins-And-Textures/generateModel.cs b/PCK-Studio/Forms/Skins-And-Textures/generateModel.cs
index f3b04435..e28b468e 100644
--- a/PCK-Studio/Forms/Skins-And-Textures/generateModel.cs
+++ b/PCK-Studio/Forms/Skins-And-Textures/generateModel.cs
@@ -134,7 +134,7 @@ namespace PckStudio.Forms
_file = file;
if (file.Size > 0)
{
- uvPictureBox.Image = renderer3D1.Texture = file.GetTexture() as Bitmap;
+ uvPictureBox.Image = file.GetTexture();
}
comboParent.Items.Clear();
comboParent.Items.AddRange(ValidModelBoxTypes);
diff --git a/PCK-Studio/Forms/TestGL.Designer.cs b/PCK-Studio/Forms/TestGL.Designer.cs
index 22c2192e..deb69f0c 100644
--- a/PCK-Studio/Forms/TestGL.Designer.cs
+++ b/PCK-Studio/Forms/TestGL.Designer.cs
@@ -28,7 +28,7 @@
///
private void InitializeComponent()
{
- this.renderer3D1 = new PckStudio.Rendering.Renderer3D();
+ this.renderer3D1 = new PckStudio.Rendering.SkinRenderer();
this.SuspendLayout();
//
// renderer3D1
@@ -36,12 +36,9 @@
this.renderer3D1.BackColor = System.Drawing.Color.Gray;
this.renderer3D1.Dock = System.Windows.Forms.DockStyle.Fill;
this.renderer3D1.Location = new System.Drawing.Point(0, 0);
- this.renderer3D1.Model = PckStudio.Rendering.Renderer3D.Models.Steve;
this.renderer3D1.Name = "renderer3D1";
this.renderer3D1.Size = new System.Drawing.Size(426, 428);
- this.renderer3D1.Texture = global::PckStudio.Properties.Resources.classic_template;
this.renderer3D1.TabIndex = 8;
- this.renderer3D1.FieldOfView = 1D;
//
// TestGL
//
@@ -58,6 +55,6 @@
#endregion
- private PckStudio.Rendering.Renderer3D renderer3D1;
+ private PckStudio.Rendering.SkinRenderer renderer3D1;
}
}
\ No newline at end of file
diff --git a/PCK-Studio/Internal/SkinBOX.cs b/PCK-Studio/Internal/SkinBOX.cs
index 5f7c743f..8a88e28e 100644
--- a/PCK-Studio/Internal/SkinBOX.cs
+++ b/PCK-Studio/Internal/SkinBOX.cs
@@ -45,7 +45,7 @@ namespace PckStudio.Internal
}
public static SkinBOX FromString(string value)
- {
+ {
var arguments = value.Split(' ');
if (arguments.Length < 9)
{
diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj
index 671a47cd..6c612deb 100644
--- a/PCK-Studio/PckStudio.csproj
+++ b/PCK-Studio/PckStudio.csproj
@@ -136,6 +136,7 @@
+
Form
@@ -152,11 +153,20 @@
True
Resources.resx
+
+
+
+
+ UserControl
+
+
+ SkinRenderer.cs
+
-
+
@@ -169,9 +179,6 @@
UserControl
-
- Renderer3D.cs
-
Component
@@ -629,7 +636,7 @@
-
+
@@ -682,7 +689,7 @@
-
+
diff --git a/PCK-Studio/Properties/Resources.Designer.cs b/PCK-Studio/Properties/Resources.Designer.cs
index 1ebfa5ea..ba5d465b 100644
--- a/PCK-Studio/Properties/Resources.Designer.cs
+++ b/PCK-Studio/Properties/Resources.Designer.cs
@@ -334,22 +334,6 @@ namespace PckStudio.Properties {
}
}
- ///
- /// Looks up a localized string similar to #version 330 core
- ///
- ///layout(location = 0) out vec4 color;
- ///
- ///void main()
- ///{
- /// color = vec4(1.0, 0.0, 0.0, 1.0);
- ///};.
- ///
- public static string fragmentShader {
- get {
- return ResourceManager.GetString("fragmentShader", resourceCulture);
- }
- }
-
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
@@ -570,6 +554,33 @@ namespace PckStudio.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to #version 330 core
+ ///
+ ///layout(location = 0) out vec4 color;
+ ///
+ ///uniform sampler2D u_Texture;
+ ///
+ ///in vec2 v_TexCoord;
+ ///in vec4 v_VertexPos;
+ ///in vec4 v_Color;
+ ///
+ ///void main()
+ ///{
+ /// vec4 texColor = texture(u_Texture, v_TexCoord);
+ /// // color = vec4(v_VertexPos.xyz, 1.0);
+ /// // color = vec4(v_TexCoord, 0.0, 1.0) * vec4(v_VertexPos.xyz, 1.0);
+ /// // color = vec4(v_TexCoord, 0.0, 1.0);
+ /// color = v_Color;
+ /// color = texColor;
+ ///};.
+ ///
+ public static string skinFragment {
+ get {
+ return ResourceManager.GetString("skinFragment", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
@@ -580,6 +591,34 @@ namespace PckStudio.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to #version 330 core
+ ///
+ ///layout(location = 0) in vec4 vertexPosition;
+ ///layout(location = 1) in vec4 color;
+ ///layout(location = 2) in vec2 texCoord;
+ ///
+ ///uniform mat4 u_ViewProjection;
+ ///uniform mat4 u_Model;
+ ///
+ ///out vec2 v_TexCoord;
+ ///out vec4 v_VertexPos;
+ ///out vec4 v_Color;
+ ///
+ ///void main()
+ ///{
+ /// v_TexCoord = texCoord;
+ /// v_Color = color;
+ /// v_VertexPos = vertexPosition;
+ /// gl_Position = u_ViewProjection * u_Model * vertexPosition;
+ ///};.
+ ///
+ public static string skinVertexShader {
+ get {
+ return ResourceManager.GetString("skinVertexShader", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
@@ -781,22 +820,6 @@ namespace PckStudio.Properties {
}
}
- ///
- /// Looks up a localized string similar to #version 330 core
- ///
- ///layout(location = 0) in vec2 position;
- ///
- ///void main()
- ///{
- /// gl_Position = vec4(position.xy, 0.0, 0.0);
- ///};.
- ///
- public static string vertexShader {
- get {
- return ResourceManager.GetString("vertexShader", resourceCulture);
- }
- }
-
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
diff --git a/PCK-Studio/Properties/Resources.resx b/PCK-Studio/Properties/Resources.resx
index 59fcd348..5e50a571 100644
--- a/PCK-Studio/Properties/Resources.resx
+++ b/PCK-Studio/Properties/Resources.resx
@@ -328,10 +328,10 @@
..\..\ProjectLogo.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
- ..\Resources\vertexShader.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252
+
+ ..\Resources\shader\skinFragment.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252
-
- ..\Resources\fragment.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252
+
+ ..\Resources\shader\skinVertexShader.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252
\ No newline at end of file
diff --git a/PCK-Studio/Rendering/Camera.cs b/PCK-Studio/Rendering/Camera.cs
new file mode 100644
index 00000000..a29cdd60
--- /dev/null
+++ b/PCK-Studio/Rendering/Camera.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Media3D;
+using OpenTK;
+
+namespace PckStudio.Rendering
+{
+ internal class Camera
+ {
+ public float Distance
+ {
+ get => _position.Z;
+ set
+ {
+ _position.Z = value;
+ }
+ }
+
+ public Vector2 Position
+ {
+ get => _position.Xy;
+ set
+ {
+ _position.Xy = value;
+ }
+ }
+
+ public Vector2 Rotation
+ {
+ get => _rotation;
+ set
+ {
+ _rotation.X = MathHelper.Clamp(value.X, -180f, 180f);
+ _rotation.Y = MathHelper.Clamp(value.Y, -180f, 180f);
+ }
+ }
+
+ public float MinimumFov { get; set; } = 30f;
+ public float MaximumFov { get; set; } = 120f;
+ public float Fov
+ {
+ get => fov;
+ set => fov = MathHelper.Clamp(value, MinimumFov, MaximumFov);
+ }
+
+ private Matrix4 viewProjection;
+ private Matrix4 viewMatrix;
+ private float fov;
+
+ private Vector3 _position;
+ private Vector2 _rotation;
+ private Vector3 _target;
+
+ public Camera(Vector2 position, float distance, Vector2 rotation, float fov)
+ {
+ _position = new Vector3(position) { Z = distance };
+ _target = new Vector3(position);
+ Rotation = rotation;
+ Fov = fov;
+ }
+
+ internal Matrix4 GetViewProjection()
+ {
+ return viewProjection;
+ }
+
+ private void UpdateView()
+ {
+ var up = Vector3.UnitY;
+
+ Matrix4 rotation = Matrix4.CreateFromAxisAngle(new Vector3(-1f, 0f, 0f), MathHelper.DegreesToRadians(Rotation.X))
+ * Matrix4.CreateFromAxisAngle(new Vector3(0f, 1f, 0f), MathHelper.DegreesToRadians(Rotation.Y));
+
+ viewMatrix = Matrix4.LookAt(_position, _target, up) * rotation;
+ }
+
+ internal void Update(float aspect)
+ {
+ UpdateView();
+ var projection = Matrix4.CreatePerspectiveFieldOfView((float)MathHelper.DegreesToRadians(Fov), aspect, 1f, 100f);
+ viewProjection = viewMatrix * projection;
+ }
+
+ internal void LookAt(Vector2 pos)
+ {
+ _target = new Vector3(pos);
+ Position = pos;
+ }
+
+ public override string ToString()
+ {
+ return $"FOV: {Fov}\nPosition: {Position}\nRotation: {Rotation}";
+ }
+ }
+}
diff --git a/PCK-Studio/Rendering/IndexBuffer.cs b/PCK-Studio/Rendering/IndexBuffer.cs
index a9ce629a..dcf877e2 100644
--- a/PCK-Studio/Rendering/IndexBuffer.cs
+++ b/PCK-Studio/Rendering/IndexBuffer.cs
@@ -16,8 +16,8 @@ namespace PckStudio.Rendering
public IndexBuffer(params uint[] indecies)
{
_id = GL.GenBuffer();
- Bind();
_count = indecies.Length;
+ Bind();
GL.BufferData(BufferTarget.ElementArrayBuffer, indecies.Length * sizeof(uint), indecies, BufferUsageHint.StaticDraw);
}
diff --git a/PCK-Studio/Rendering/RenderBuffer.cs b/PCK-Studio/Rendering/RenderBuffer.cs
new file mode 100644
index 00000000..5b53ce77
--- /dev/null
+++ b/PCK-Studio/Rendering/RenderBuffer.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OpenTK.Graphics.OpenGL;
+
+namespace PckStudio.Rendering
+{
+ internal class RenderBuffer
+ {
+ internal readonly VertexArray VertexArray;
+ internal readonly IndexBuffer IndexBuffer;
+ internal readonly PrimitiveType PrimitiveType;
+
+ public RenderBuffer(VertexArray vertexArray, IndexBuffer indexBuffer, PrimitiveType primitiveType)
+ {
+ VertexArray = vertexArray;
+ IndexBuffer = indexBuffer;
+ PrimitiveType = primitiveType;
+ }
+ }
+}
diff --git a/PCK-Studio/Rendering/RenderGroup.cs b/PCK-Studio/Rendering/RenderGroup.cs
new file mode 100644
index 00000000..2825af4e
--- /dev/null
+++ b/PCK-Studio/Rendering/RenderGroup.cs
@@ -0,0 +1,90 @@
+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 RenderGroup
+ {
+ internal readonly string Name;
+
+ private List vertices;
+ private List indices;
+
+ private uint indicesOffset;
+
+ internal RenderGroup(string name)
+ {
+ Name = name;
+ vertices = new List();
+ indices = new List();
+ indicesOffset = 0;
+ }
+
+ internal RenderBuffer GetRenderBuffer()
+ {
+ var vertexData = vertices.ToArray();
+ var buffer = new VertexBuffer(vertexData, vertexData.Length * TextureVertex.SizeInBytes);
+ var layout = new VertexBufferLayout();
+ layout.Add(3);
+ layout.Add(2);
+
+ var vertexArray = new VertexArray();
+
+ vertexArray.AddBuffer(buffer, layout);
+
+ var indexBuffer = new IndexBuffer(indices.ToArray());
+
+ return new RenderBuffer(vertexArray, indexBuffer, PrimitiveType.Quads);
+ }
+
+ internal void AddBox(SkinBOX skinBOX, Vector2 textureScale)
+ {
+ var position = skinBOX.Pos.ToOpenTKVector();
+ var size = skinBOX.Size.ToOpenTKVector();
+ var uv = skinBOX.UV.ToOpenTKVector();
+
+ var vertexData = new TextureVertex[]
+ {
+ new TextureVertex(new Vector3(position.X , size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z) * textureScale),
+ new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z) * textureScale),
+ new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z + size.Y) * textureScale),
+ new TextureVertex(new Vector3(position.X , position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y) * textureScale),
+
+ new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z) * textureScale),
+ new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z) * textureScale),
+ new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z + size.Y) * textureScale),
+ new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z + size.Y) * textureScale),
+
+ new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X, uv.Y + size.Z) * textureScale),
+ new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X, uv.Y + size.Z + size.Y) * textureScale),
+ new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y) * textureScale),
+ new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z, uv.Y) * textureScale),
+
+ new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y) * textureScale),
+ new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * 2, uv.Y) * textureScale),
+ new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X * 2, uv.Y + size.Z) * textureScale),
+ new TextureVertex(new Vector3(position.X , position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z) * textureScale),
+ };
+
+ 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)
+ 12 + indicesOffset, 13 + indicesOffset, 14 + indicesOffset, 15 + indicesOffset// Face 6 (Bottom)
+ };
+ indicesOffset += (uint)indexStorage.Length;
+ indices.AddRange(indexStorage);
+ }
+ }
+}
diff --git a/PCK-Studio/Rendering/Renderer.cs b/PCK-Studio/Rendering/Renderer.cs
index 85e6c37b..ba943f37 100644
--- a/PCK-Studio/Rendering/Renderer.cs
+++ b/PCK-Studio/Rendering/Renderer.cs
@@ -9,12 +9,12 @@ namespace PckStudio.Rendering
{
internal static class Renderer
{
- public static void Draw(Shader shader, VertexArray va, IndexBuffer ib, PrimitiveType type)
+ public static void Draw(Shader shader, RenderBuffer renderBuffer)
{
shader.Bind();
- va.Bind();
- ib.Bind();
- GL.DrawElements(type, ib.GetCount(), DrawElementsType.UnsignedInt, 0);
+ renderBuffer.VertexArray.Bind();
+ renderBuffer.IndexBuffer.Bind();
+ GL.DrawElements(renderBuffer.PrimitiveType, renderBuffer.IndexBuffer.GetCount(), DrawElementsType.UnsignedInt, 0);
}
}
}
diff --git a/PCK-Studio/Rendering/Renderer3D.cs b/PCK-Studio/Rendering/Renderer3D.cs
index f9443b2c..1653c917 100644
--- a/PCK-Studio/Rendering/Renderer3D.cs
+++ b/PCK-Studio/Rendering/Renderer3D.cs
@@ -26,468 +26,20 @@ https://github.com/KareemMAX/Minecraft-Skiner/blob/master/src/Minecraft%20skiner
*/
using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.Linq;
using System.Windows.Forms;
-using PckStudio.Classes.Utils;
-using Microsoft.VisualBasic;
using OpenTK;
-using OpenTK.Graphics.OpenGL;
-using System.Diagnostics;
-using PckStudio.Properties;
-using System.Runtime.InteropServices;
-using PckStudio.Extensions;
-using Newtonsoft.Json.Linq;
namespace PckStudio.Rendering
{
- public partial class Renderer3D : GLControl
+ internal class Renderer3D : GLControl
{
- private Bitmap _texture;
- ///
- /// The visible Texture on the renderer
- ///
- /// The visible Texture
- [Description("The current Texture")]
- [Category("Appearance")]
- public Bitmap Texture
- {
- get => _texture;
- set
- {
- if (shader is not null)
- {
- var texture = new Texture2D(value);
- texture.Bind(1);
- shader.SetUniform1("u_Texture", 1);
- Refresh();
- }
- TextureScaleValue = new Vector2(1f / value.Width, 1f / value.Height);
- _texture = value;
- }
- }
-
- public enum Models
- {
- Steve,
- Alex
- }
- ///
- /// The rendered model
- ///
- /// The rendered model
- [Description("The current player model")]
- [Category("Appearance")]
- public Models Model { get; set; }
-
-
- private Vector2 _rotation = new Vector2();
- ///
- /// Rotation
- ///
- /// Rotation
- [Description("The rotation of the camera")]
- [Category("Appearance")]
- public Vector2 Rotation
- {
- get => _rotation;
- set
- {
- value.X = MathHelper.Clamp(value.X, -90f, 90f);
- value.Y = MathHelper.Clamp(value.Y, -180f, 180f);
- _rotation = value;
- }
- }
-
- private double _fieldOfViewRadians = MinFOV;
-
- private const double MinFOVDegrees = 30d;
- private const double MaxFOVDegrees = 90d;
-
- private static double MinFOV = MathHelper.DegreesToRadians(MinFOVDegrees);
- private static double MaxFOV = MathHelper.DegreesToRadians(MaxFOVDegrees);
-
- [Description("The Field of View value (in Radians)")]
- private double FieldOfViewRadians
- {
- get => _fieldOfViewRadians;
- set => _fieldOfViewRadians = MathHelper.Clamp(value, MinFOV, MaxFOV);
- }
-
- [Description("The Field of View (in Degrees)")]
- [Category("Appearance")]
- public double FieldOfView
- {
- get => MathHelper.RadiansToDegrees(_fieldOfViewRadians);
- set => FieldOfViewRadians = MathHelper.DegreesToRadians(MathHelper.Clamp(value, MinFOVDegrees, MaxFOVDegrees));
- }
-
- private Vector2 _lookAngle = Vector2.Zero;
- [Description("The offset from the orignal point (for zoom)")]
- [Category("Appearance")]
- public Vector2 LookAngle
- {
- get => _lookAngle;
- set
- {
- value.X = MathHelper.Clamp(value.X, -8f, 8f);
- value.Y = MathHelper.Clamp(value.Y, -16f, 16f);
- _lookAngle = value;
- }
- }
-
- public float CameraDistance { get; set; } = 18f;
-
- private Matrix4 projection;
-
- private Matrix4 view;
-
- private Vector2 TextureScaleValue = new Vector2(1f / 64);
-
- private void GLDebugMessage(DebugSource source, DebugType type, int id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam)
- {
- string msg = Marshal.PtrToStringAnsi(message, length);
- Debug.WriteLine(source);
- Debug.WriteLine(type);
- Debug.WriteLine(severity);
- Debug.WriteLine(id);
- Debug.WriteLine(msg);
- }
-
- private Shader shader;
-
- private VertexArray vertexArray;
- private IndexBuffer indexBuffer;
- private Matrix4 mvp;
-
- private bool IsMouseDown;
- private bool IsRightMouseDown;
- private bool IsMouseHidden;
- private Point PreviousMouseLocation;
- private Point MouseLoc;
-
- private Ray LastRay;
- private Vector3 GlobalCameraPos;
+ protected Camera camera;
public Renderer3D()
{
- InitializeComponent();
+ VSync = true;
+ camera = new Camera(Vector2.Zero, 1f, Vector2.Zero, 30f);
}
-
- protected override void OnLoad(EventArgs e)
- {
- base.OnLoad(e);
- if (DesignMode)
- return;
-
- MakeCurrent();
-
- GL.DebugMessageCallback(GLDebugMessage, IntPtr.Zero);
-
- Trace.TraceInformation(GL.GetString(StringName.Version));
-
- shader = Shader.Create(Resources.vertexShader, Resources.fragmentShader);
- shader.Bind();
-
- Texture = Resources.slim_template;
- var bodyVertexData = new Vertex[]
- {
- // Face 1
- new Vertex(new Vector3(-4, 8, 2), Color.Red, new Vector2(TextureScaleValue.X * 20f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3( 4, 8, 2), Color.Red, new Vector2(TextureScaleValue.X * 28f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3( 4, -4, 2), Color.Red, new Vector2(TextureScaleValue.X * 28f, TextureScaleValue.Y * 32f)),
- new Vertex(new Vector3(-4, -4, 2), Color.Red, new Vector2(TextureScaleValue.X * 20f, TextureScaleValue.Y * 32f)),
-
- // Face 2
- new Vertex(new Vector3(-4, 8, -2), Color.Red, new Vector2(TextureScaleValue.X * 40f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3( 4, 8, -2), Color.Red, new Vector2(TextureScaleValue.X * 32f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3( 4, -4, -2), Color.Red, new Vector2(TextureScaleValue.X * 32f, TextureScaleValue.Y * 32f)),
- new Vertex(new Vector3(-4, -4, -2), Color.Red, new Vector2(TextureScaleValue.X * 40f, TextureScaleValue.Y * 32f)),
-
- // Face 3
- new Vertex(new Vector3(-4, 8, 2), Color.Red, new Vector2(TextureScaleValue.X * 20f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3(-4, 8, -2), Color.Red, new Vector2(TextureScaleValue.X * 16f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3(-4, -4, -2), Color.Red, new Vector2(TextureScaleValue.X * 16f, TextureScaleValue.Y * 32f)),
- new Vertex(new Vector3(-4, -4, 2), Color.Red, new Vector2(TextureScaleValue.X * 20f, TextureScaleValue.Y * 32f)),
-
- // Face 4
- new Vertex(new Vector3( 4, 8, 2), Color.Red, new Vector2(TextureScaleValue.X * 28f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3( 4, 8, -2), Color.Red, new Vector2(TextureScaleValue.X * 32f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3( 4, -4, -2), Color.Red, new Vector2(TextureScaleValue.X * 32f, TextureScaleValue.Y * 32f)),
- new Vertex(new Vector3( 4, -4, 2), Color.Red, new Vector2(TextureScaleValue.X * 28f, TextureScaleValue.Y * 32f)),
-
- // Face 5
- new Vertex(new Vector3(-4, 8, 2), Color.Red, new Vector2(TextureScaleValue.X * 20f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3( 4, 8, 2), Color.Red, new Vector2(TextureScaleValue.X * 28f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3( 4, 8, -2), Color.Red, new Vector2(TextureScaleValue.X * 28f, TextureScaleValue.Y * 16f)),
- new Vertex(new Vector3(-4, 8, -2), Color.Red, new Vector2(TextureScaleValue.X * 20f, TextureScaleValue.Y * 16f)),
-
- // Face 6
- new Vertex(new Vector3(-4, -4, -2), Color.Red, new Vector2(TextureScaleValue.X * 28f, TextureScaleValue.Y * 16f)),
- new Vertex(new Vector3( 4, -4, -2), Color.Red, new Vector2(TextureScaleValue.X * 36f, TextureScaleValue.Y * 16f)),
- new Vertex(new Vector3( 4, -4, 2), Color.Red, new Vector2(TextureScaleValue.X * 36f, TextureScaleValue.Y * 20f)),
- new Vertex(new Vector3(-4, -4, 2), Color.Red, new Vector2(TextureScaleValue.X * 28f, TextureScaleValue.Y * 20f)),
- };
-
- indexBuffer = new IndexBuffer(
- 0, 1, 2, 3,
- 4, 5, 6, 7,
- 8, 9, 10, 11,
- 12, 13, 14, 15,
- 16, 17, 18, 19,
- 20, 21, 22, 23
- );
-
- vertexArray = new VertexArray();
-
- int vertexSize = Marshal.SizeOf(typeof(Vertex));
-
- var buffer = new VertexBuffer(bodyVertexData, bodyVertexData.Length * vertexSize);
- var layout = new VertexBufferLayout();
- layout.Add(3);
- layout.Add(4);
- layout.Add(2);
-
- vertexArray.AddBuffer(buffer, layout);
-
- GLErrorCheck();
- }
-
- [Conditional("DEBUG")]
- private void GLErrorCheck()
- {
- var error = GL.GetError();
- Debug.Assert(error == ErrorCode.NoError, error.ToString());
- }
-
- private void UpdateView()
- {
- var camera = new Vector3(LookAngle) { Z = CameraDistance };
-
- var target = new Vector3(LookAngle);
-
- var up = new Vector3(0, 1f, 1f);
-
- view = Matrix4.LookAt(camera, target, up);
- }
-
- private void UpdateProjection()
- {
- projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.Pow(FieldOfViewRadians, -1), Width / (float)Height, 1f, 100f);
- }
-
- private void DrawBox(Vector3 scale, Vector3 position, Vector2 uv)
- {
- float[] Corner1 = { position.X, position.Y, position.Z };
- float[] Corner2 = { position.X + scale.X, position.Y, position.Z };
- float[] Corner3 = { position.X, position.Y + scale.Y, position.Z };
- float[] Corner4 = { position.X, position.Y, position.Z + scale.Z };
- float[] Corner5 = { position.X + scale.X, position.Y + scale.Y, position.Z };
- float[] Corner6 = { position.X, position.Y + scale.Y, position.Z + scale.Z };
- float[] Corner7 = { position.X + scale.X, position.Y, position.Z + scale.Z };
- float[] Corner8 = { position.X + scale.X, position.Y + scale.Y, position.Z + scale.Z };
-
- GL.Color3(Color.Red);
- // Face 1
- GL.Vertex3(Corner1);
- GL.Vertex3(Corner3);
- GL.Vertex3(Corner5);
- GL.Vertex3(Corner2);
- // Face 2
- GL.Vertex3(Corner1);
- GL.Vertex3(Corner4);
- GL.Vertex3(Corner7);
- GL.Vertex3(Corner2);
- // Face 3
- GL.Vertex3(Corner1);
- GL.Vertex3(Corner4);
- GL.Vertex3(Corner6);
- GL.Vertex3(Corner3);
- // Face 4
- GL.TexCoord2(uv.X, TextureScaleValue.Y * 8d);
- GL.Vertex3(Corner4);
- GL.TexCoord2(TextureScaleValue.X * 16d, TextureScaleValue.Y * 8d);
- GL.Vertex3(Corner7);
- GL.TexCoord2(TextureScaleValue.X * 16d, TextureScaleValue.Y * 16d);
- GL.Vertex3(Corner8);
- GL.TexCoord2(TextureScaleValue.X * 8d, TextureScaleValue.Y * 16d);
- GL.Vertex3(Corner6);
- // Face 5
- GL.Vertex3(Corner8);
- GL.Vertex3(Corner6);
- GL.Vertex3(Corner3);
- GL.Vertex3(Corner5);
- // Face 6
- GL.Vertex3(Corner2);
- GL.Vertex3(Corner7);
- GL.Vertex3(Corner8);
- GL.Vertex3(Corner5);
- }
-
- protected override void OnPaint(PaintEventArgs e)
- {
- if (DesignMode)
- {
- base.OnPaint(e);
- return;
- }
-
- UpdateProjection();
- UpdateView();
-
- MakeCurrent();
- GL.Viewport(Size);
-
- Matrix4 transform = Matrix4.Identity;
- Matrix4 scale = Matrix4.Identity;
- Matrix4 rot = Matrix4.CreateFromAxisAngle(new Vector3(-1f, 0f, 0f), MathHelper.DegreesToRadians(Rotation.X))
- + Matrix4.CreateFromAxisAngle(new Vector3(0f, 1f, 0f), MathHelper.DegreesToRadians(Rotation.Y));
-
- var model = transform * rot * scale;
-
- mvp = model * view * projection;
-
-#if DEBUG
- debugLabel.Text = $"Rotation: {Rotation}\nFOV: {FieldOfView}\nView:\n{view}\nProjection:\n{projection}\nMVP:\n{mvp}";
-#endif
-
- shader.SetUniformMat4("u_MVP", ref mvp);
-
- GL.Enable(EnableCap.Texture2D); // Enable textures
- //GL.Enable(EnableCap.DepthTest); // Enable correct Z Drawings
- //GL.DepthFunc(DepthFunction.Less); // Enable correct Z Drawings
- GL.Disable(EnableCap.Blend); // Disable transparent
- GL.Disable(EnableCap.AlphaTest); // Disable transparent
-
- GL.ClearColor(BackColor);
- GL.Clear(ClearBufferMask.ColorBufferBit);
- GL.Clear(ClearBufferMask.DepthBufferBit);
-
- //GL.Enable(EnableCap.Blend);
- //GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
-
- //GL.Enable(EnableCap.AlphaTest); // Enable transparent
- //GL.AlphaFunc(AlphaFunction.Greater, 0.4f);
-
- Renderer.Draw(shader, vertexArray, indexBuffer, PrimitiveType.Quads);
-
- SwapBuffers();
- return;
-
- GL.Disable(EnableCap.AlphaTest); // Disable transparent
- }
-
-#if DEBUG
- protected override bool ProcessDialogKey(Keys keyData)
- {
- switch (keyData)
- {
- case Keys.Escape:
- debugLabel.Visible = !debugLabel.Visible;
- return true;
- case Keys.R:
- Rotation = Vector2.Zero;
- Refresh();
- return true;
- case Keys.F1:
- var fileDialog = new OpenFileDialog()
- {
- Filter = "texture|*.png",
- };
- if (fileDialog.ShowDialog() == DialogResult.OK)
- {
- Texture = Image.FromFile(fileDialog.FileName) as Bitmap;
- }
- return true;
- }
- return base.ProcessDialogKey(keyData);
- }
-#endif
-
- protected override void OnMouseDown(MouseEventArgs e)
- {
- if (!IsMouseDown && e.Button == MouseButtons.Left)
- {
- // If the ray didn't hit the model then rotate the model
- PreviousMouseLocation = Cursor.Position; // Store the old mouse position to reset it when the action is over
- if (!IsMouseHidden) // Hide the mouse
- {
- Cursor.Hide();
- IsMouseHidden = true;
- }
- MouseLoc = Cursor.Position; // Store the current mouse position to use it for the rotate action
- IsMouseDown = true;
- }
- else if (!IsRightMouseDown && e.Button == MouseButtons.Right)
- {
- PreviousMouseLocation = Cursor.Position; // Store the old mouse position to reset it when the action is over
- if (!IsMouseHidden) // Hide the mouse
- {
- Cursor.Hide();
- IsMouseHidden = true;
- }
- MouseLoc = Cursor.Position; // Store the current mouse position to use it for the move action
- IsRightMouseDown = true;
- }
- }
-
- protected override void OnMouseUp(MouseEventArgs e)
- {
- if (IsMouseHidden)
- {
- Cursor.Position = PreviousMouseLocation;
- IsMouseDown = IsMouseHidden = IsRightMouseDown = false;
- Cursor.Show();
- }
- }
-
- private void Move_Tick(object sender, EventArgs e)
- {
- // Rotate the model
- if (IsMouseDown)
- {
- float rotationYDelta = (float)Math.Round((Cursor.Position.X - MouseLoc.X) * 0.5f);
- float rotationXDelta = (float)Math.Round(-(Cursor.Position.Y - MouseLoc.Y) * 0.5f);
- Rotation += new Vector2(rotationXDelta, rotationYDelta);
- Refresh();
- Cursor.Position = new Point((int)Math.Round(Screen.PrimaryScreen.Bounds.Width / 2d), (int)Math.Round(Screen.PrimaryScreen.Bounds.Height / 2d));
- MouseLoc = Cursor.Position;
- return;
- }
- // Move the model
- if (IsRightMouseDown)
- {
- float deltaX = -(Cursor.Position.X - MouseLoc.X) * 0.05f / (float)FieldOfViewRadians;
- float deltaY = (Cursor.Position.Y - MouseLoc.Y) * 0.05f / (float)FieldOfViewRadians;
- LookAngle += 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;
- }
- }
-
- protected override void OnMouseWheel(MouseEventArgs e)
- {
- FieldOfViewRadians += e.Delta * 0.005d;
- Refresh();
- base.OnMouseWheel(e);
- }
-
- private Vector3 GetCameraPosition(Matrix4 view)
- {
- return Matrix4.Invert(view).ExtractTranslation();
- }
-
- private List MousePoints = new List();
- private List tmpMousePoints = new List();
-
- public event TextureChangedEventHandler TextureChanged;
-
- public delegate void TextureChangedEventHandler(object sender, bool IsLeft);
}
}
diff --git a/PCK-Studio/Rendering/Shader.cs b/PCK-Studio/Rendering/Shader.cs
index 3e32aa43..52f22d6b 100644
--- a/PCK-Studio/Rendering/Shader.cs
+++ b/PCK-Studio/Rendering/Shader.cs
@@ -96,7 +96,7 @@ namespace PckStudio.Rendering
GL.LinkProgram(programId);
GL.ValidateProgram(programId);
- Trace.TraceInformation(GL.GetProgramInfoLog(programId));
+ Debug.WriteLine(GL.GetProgramInfoLog(programId), category: nameof(Shader));
GL.DeleteShader(vertexShader);
GL.DeleteShader(fragmentShader);
diff --git a/PCK-Studio/Rendering/Renderer3D.Designer.cs b/PCK-Studio/Rendering/SkinRenderer.Designer.cs
similarity index 51%
rename from PCK-Studio/Rendering/Renderer3D.Designer.cs
rename to PCK-Studio/Rendering/SkinRenderer.Designer.cs
index ddd4450b..a930ab2f 100644
--- a/PCK-Studio/Rendering/Renderer3D.Designer.cs
+++ b/PCK-Studio/Rendering/SkinRenderer.Designer.cs
@@ -1,9 +1,13 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
namespace PckStudio.Rendering
{
- public partial class Renderer3D
+ internal partial class SkinRenderer
{
[DebuggerNonUserCode()]
protected override void Dispose(bool disposing)
@@ -35,42 +39,14 @@ namespace PckStudio.Rendering
moveTimer.Tick += new EventHandler(Move_Tick);
SuspendLayout();
//
- // timMove
+ // moveTimer
//
moveTimer.Enabled = true;
- moveTimer.Interval = 20;
-#if DEBUG
- //
- // debugLabel
- //
- debugLabel = new System.Windows.Forms.Label();
- debugLabel.Enabled = true;
- debugLabel.Visible = false;
- debugLabel.AutoSize = true;
- debugLabel.Location = new System.Drawing.Point(0, 0);
- debugLabel.BackColor = System.Drawing.Color.Transparent;
- Controls.Add(debugLabel);;
-#endif
- //
- // Renderer3D
- //
- Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
- BackColor = System.Drawing.Color.LightGray;
- Location = new System.Drawing.Point(0, 0);
- Size = new System.Drawing.Size(150, 150);
- TabIndex = 0;
- VSync = true;
- AutoScaleDimensions = new System.Drawing.SizeF(6.0f, 13.0f);
- AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ moveTimer.Interval = 10;
Name = "Renderer3D";
ResumeLayout(false);
-
}
private System.Windows.Forms.Timer moveTimer;
-#if DEBUG
- private System.Windows.Forms.Label debugLabel;
-#endif
-
}
-}
\ No newline at end of file
+}
diff --git a/PCK-Studio/Rendering/SkinRenderer.cs b/PCK-Studio/Rendering/SkinRenderer.cs
new file mode 100644
index 00000000..00990b1b
--- /dev/null
+++ b/PCK-Studio/Rendering/SkinRenderer.cs
@@ -0,0 +1,385 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OpenTK;
+using PckStudio.Internal;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab;
+using System.Windows.Media.Media3D;
+using PckStudio.Extensions;
+using OpenTK.Graphics.OpenGL;
+using System.Windows.Forms;
+using System.ComponentModel;
+using System.Drawing;
+using System.Runtime.InteropServices;
+using PckStudio.Properties;
+
+namespace PckStudio.Rendering
+{
+ internal partial class SkinRenderer : Renderer3D
+ {
+ ///
+ /// The visible Texture on the renderer
+ ///
+ /// The visible Texture
+ [Description("The current Texture")]
+ [Category("Appearance")]
+ public Bitmap Texture
+ {
+ get => _texture;
+ set
+ {
+ if (skinShader is not null)
+ {
+ var texture = new Texture2D(value);
+ texture.Bind(0);
+ skinShader.SetUniform1("u_Texture", 0);
+ Refresh();
+ }
+ TextureScaleValue = new Vector2(1f / value.Width, 1f / value.Height);
+ _texture = value;
+ }
+ }
+
+ private Vector2 _lookAngle = Vector2.Zero;
+ [Description("The offset from the orignal point (for zoom)")]
+ [Category("Appearance")]
+ public Vector2 LookAngle
+ {
+ get => _lookAngle;
+ set
+ {
+ _lookAngle = value;
+ camera.LookAt(value);
+ }
+ }
+
+ private Vector2 TextureScaleValue = new Vector2(1f / 64);
+
+ private void GLDebugMessage(DebugSource source, DebugType type, int id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam)
+ {
+ string msg = Marshal.PtrToStringAnsi(message, length);
+ Debug.WriteLine(source);
+ Debug.WriteLine(type);
+ Debug.WriteLine(severity);
+ Debug.WriteLine(id);
+ Debug.WriteLine(msg);
+ }
+
+ private Vector2 _modelRotation;
+ private Vector2 modelRotation
+ {
+ get => _modelRotation;
+ set
+ {
+ _modelRotation.X = MathHelper.Clamp(value.X, -5f, 5f);
+ _modelRotation.Y = MathHelper.Clamp(value.Y, -180f, 180f);
+ }
+ }
+
+ private bool IsMouseDown;
+ private bool IsRightMouseDown;
+ private bool IsMouseHidden;
+ private Point PreviousMouseLocation;
+ private Point MouseLoc;
+ private Shader skinShader;
+
+ private Dictionary renderGroups;
+
+ private Bitmap _texture;
+
+ public SkinRenderer()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
+ if (DesignMode)
+ return;
+ MakeCurrent();
+
+ camera = new Camera(new Vector2(0f, 1f), 36f, Vector2.Zero, 60f);
+
+ camera.MinimumFov = 30f;
+ camera.MaximumFov = 90f;
+
+ camera.LookAt(new Vector2(0f, 5f));
+
+ GL.DebugMessageCallback(GLDebugMessage, IntPtr.Zero);
+
+ Trace.TraceInformation(GL.GetString(StringName.Version));
+
+ skinShader = Shader.Create(Resources.skinVertexShader, Resources.skinFragment);
+ skinShader.Bind();
+
+ Texture = Resources.slim_template;
+
+ renderGroups = 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") }
+ };
+
+ var headbox = new SkinBOX("HEAD", new(-4, -8, -4), new(8, 8, 8), new( 0, 0));
+ var bodybox = new SkinBOX("BODY", new(-4, 0, -2), new(8, 12, 4), new(16, 16));
+ 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 leg0box = new SkinBOX("LEG0", new(-2, 0, -2), new(4, 12, 4), new( 0, 16));
+ var leg1box = new SkinBOX("LEG1", new(-2, 0, -2), new(4, 12, 4), new(16, 48));
+
+ AddGroup(headbox, TextureScaleValue);
+ AddGroup(bodybox, TextureScaleValue);
+ AddGroup(arm0box, TextureScaleValue);
+ AddGroup(arm1box, TextureScaleValue);
+ AddGroup(leg0box, TextureScaleValue);
+ AddGroup(leg1box, TextureScaleValue);
+
+ GLErrorCheck();
+ }
+
+ private void AddGroup(SkinBOX skinBox, Vector2 textureScaleValue)
+ {
+ if (!renderGroups.ContainsKey(skinBox.Type))
+ throw new KeyNotFoundException(skinBox.Type);
+
+ renderGroups[skinBox.Type].AddBox(skinBox, textureScaleValue);
+ }
+
+ [Conditional("DEBUG")]
+ private void GLErrorCheck()
+ {
+ var error = GL.GetError();
+ Debug.Assert(error == ErrorCode.NoError, error.ToString());
+ }
+
+ private RenderBuffer GetBox3D(SkinBOX skinBOX)
+ {
+ return GetBox3D(skinBOX.Pos.ToOpenTKVector(), skinBOX.Size.ToOpenTKVector(), skinBOX.UV.ToOpenTKVector());
+ }
+
+ private RenderBuffer GetBox3D(Vector3 position, Vector3 size, Vector2 uv)
+ {
+ var vertexData = new TextureVertex[]
+ {
+ new TextureVertex(new Vector3(position.X , size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z) * TextureScaleValue),
+ new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z) * TextureScaleValue),
+ new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z + size.Y) * TextureScaleValue),
+ new TextureVertex(new Vector3(position.X , position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y) * TextureScaleValue),
+
+ new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z) * TextureScaleValue),
+ new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z) * TextureScaleValue),
+ new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z + size.Y) * TextureScaleValue),
+ new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z + size.Y) * TextureScaleValue),
+
+ new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X, uv.Y + size.Z) * TextureScaleValue),
+ new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X, uv.Y + size.Z + size.Y) * TextureScaleValue),
+ new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y) * TextureScaleValue),
+ new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z, uv.Y) * TextureScaleValue),
+
+ new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y) * TextureScaleValue),
+ new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * 2, uv.Y) * TextureScaleValue),
+ new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X * 2, uv.Y + size.Z) * TextureScaleValue),
+ new TextureVertex(new Vector3(position.X , position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z) * TextureScaleValue),
+ };
+
+ var indexBuffer = new IndexBuffer(
+ 0, 1, 2, 3, // Face 1 (Front)
+ 4, 5, 6, 7, // Face 2 (Back)
+ 0, 8, 9, 3, // Face 3 (Left)
+ 1, 5, 6, 2, // Face 4 (Right)
+ 0, 1, 10, 11, // Face 5(Top)
+ 12, 13, 14, 15 // Face 6 (Bottom)
+ );
+
+ var buffer = new VertexBuffer(vertexData, vertexData.Length * TextureVertex.SizeInBytes);
+ var layout = new VertexBufferLayout();
+ layout.Add(3);
+ layout.Add(4);
+ layout.Add(2);
+
+ var vertexArray = new VertexArray();
+
+ vertexArray.AddBuffer(buffer, layout);
+
+ return new RenderBuffer(vertexArray, indexBuffer, PrimitiveType.Quads);
+ }
+
+ private Matrix4 GetModelFromSkinBOX(SkinBOX skinBox)
+ {
+ return Matrix4.CreateTranslation(skinBox.Pos.ToOpenTKVector()) * Matrix4.CreateScale(skinBox.Scale);
+ }
+
+ protected override bool ProcessDialogKey(Keys keyData)
+ {
+ switch (keyData)
+ {
+ case Keys.R:
+ modelRotation = Vector2.Zero;
+ LookAngle = Vector2.Zero;
+ Refresh();
+ return true;
+ case Keys.F1:
+ var fileDialog = new OpenFileDialog()
+ {
+ Filter = "texture|*.png",
+ };
+ if (fileDialog.ShowDialog() == DialogResult.OK)
+ {
+ Texture = Image.FromFile(fileDialog.FileName) as Bitmap;
+ }
+ return true;
+ }
+ return base.ProcessDialogKey(keyData);
+ }
+
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ base.OnPaint(e);
+ if (DesignMode)
+ {
+ return;
+ }
+
+ MakeCurrent();
+
+ camera.Update(Size.Width / (float)Size.Height);
+
+ var viewProjection = camera.GetViewProjection();
+ skinShader.SetUniformMat4("u_ViewProjection", ref viewProjection);
+
+ GL.Viewport(Size);
+
+ GL.ClearColor(BackColor);
+ GL.Clear(ClearBufferMask.ColorBufferBit);
+ GL.Clear(ClearBufferMask.DepthBufferBit);
+
+ 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);
+
+ GL.Enable(EnableCap.AlphaTest); // Enable transparent
+ GL.AlphaFunc(AlphaFunction.Greater, 0.4f);
+
+ Matrix4 transform = Matrix4.CreateTranslation(new Vector3(0f, 16f, 0f));
+ Matrix4 rotation = Matrix4.CreateFromAxisAngle(new Vector3(-1f, 0f, 0f), MathHelper.DegreesToRadians(modelRotation.X))
+ * Matrix4.CreateFromAxisAngle(new Vector3(0f, 1f, 0f), MathHelper.DegreesToRadians(modelRotation.Y));
+
+ var model = transform * rotation;
+
+ skinShader.SetUniformMat4("u_Model", ref model);
+ Renderer.Draw(skinShader, renderGroups["HEAD"].GetRenderBuffer());
+
+ transform = Matrix4.CreateTranslation(new Vector3(0f, -4f, 0f));
+ model = transform * rotation;
+
+ skinShader.SetUniformMat4("u_Model", ref model);
+ Renderer.Draw(skinShader, renderGroups["BODY"].GetRenderBuffer());
+
+ transform = Matrix4.CreateTranslation(new Vector3(-5f, -2f, 0f));
+ model = transform * rotation;
+
+ skinShader.SetUniformMat4("u_Model", ref model);
+ Renderer.Draw(skinShader, renderGroups["ARM0"].GetRenderBuffer());
+
+ transform = Matrix4.CreateTranslation(new Vector3(5f, -2f, 0f));
+ model = transform * rotation;
+
+ skinShader.SetUniformMat4("u_Model", ref model);
+ Renderer.Draw(skinShader, renderGroups["ARM1"].GetRenderBuffer());
+
+ transform = Matrix4.CreateTranslation(new Vector3(-2f, -16f, 0f));
+ model = transform * rotation;
+
+ skinShader.SetUniformMat4("u_Model", ref model);
+ Renderer.Draw(skinShader, renderGroups["LEG0"].GetRenderBuffer());
+
+ transform = Matrix4.CreateTranslation(new Vector3(2f, -16f, 0f));
+ model = transform * rotation;
+
+ skinShader.SetUniformMat4("u_Model", ref model);
+ Renderer.Draw(skinShader, renderGroups["LEG1"].GetRenderBuffer());
+
+ SwapBuffers();
+ }
+
+ protected override void OnMouseWheel(MouseEventArgs e)
+ {
+ camera.Fov -= e.Delta / System.Windows.Input.Mouse.MouseWheelDeltaForOneLine;
+ Refresh();
+ }
+
+ protected override void OnMouseDown(MouseEventArgs e)
+ {
+ if (!IsMouseDown && e.Button == MouseButtons.Left)
+ {
+ // If the ray didn't hit the model then rotate the model
+ PreviousMouseLocation = Cursor.Position; // Store the old mouse position to reset it when the action is over
+ if (!IsMouseHidden) // Hide the mouse
+ {
+ Cursor.Hide();
+ IsMouseHidden = true;
+ }
+ MouseLoc = Cursor.Position; // Store the current mouse position to use it for the rotate action
+ IsMouseDown = true;
+ }
+ else if (!IsRightMouseDown && e.Button == MouseButtons.Right)
+ {
+ PreviousMouseLocation = Cursor.Position; // Store the old mouse position to reset it when the action is over
+ if (!IsMouseHidden) // Hide the mouse
+ {
+ Cursor.Hide();
+ IsMouseHidden = true;
+ }
+ MouseLoc = Cursor.Position; // Store the current mouse position to use it for the move action
+ IsRightMouseDown = true;
+ }
+ }
+
+ protected override void OnMouseUp(MouseEventArgs e)
+ {
+ if (IsMouseHidden)
+ {
+ Cursor.Position = PreviousMouseLocation;
+ IsMouseDown = IsMouseHidden = IsRightMouseDown = false;
+ Cursor.Show();
+ }
+ }
+
+ private void Move_Tick(object sender, EventArgs e)
+ {
+ // Rotate the model
+ if (IsMouseDown)
+ {
+ float rotationYDelta = (float)Math.Round((Cursor.Position.X - MouseLoc.X) * 0.5f);
+ float rotationXDelta = (float)Math.Round(-(Cursor.Position.Y - MouseLoc.Y) * 0.5f);
+ modelRotation += new Vector2(rotationXDelta, rotationYDelta);
+ Refresh();
+ Cursor.Position = new Point((int)Math.Round(Screen.PrimaryScreen.Bounds.Width / 2d), (int)Math.Round(Screen.PrimaryScreen.Bounds.Height / 2d));
+ MouseLoc = Cursor.Position;
+ return;
+ }
+ // Move the model
+ if (IsRightMouseDown)
+ {
+ 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);
+ 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/Texture2D.cs b/PCK-Studio/Rendering/Texture2D.cs
index ffdfa784..2016c10b 100644
--- a/PCK-Studio/Rendering/Texture2D.cs
+++ b/PCK-Studio/Rendering/Texture2D.cs
@@ -51,11 +51,6 @@ namespace PckStudio.Rendering
GL.BindTexture(TextureTarget.Texture2D, _id);
}
- public void Bind()
- {
- Bind(0);
- }
-
[Conditional("DEBUG")]
public void Unbind()
{
diff --git a/PCK-Studio/Rendering/Vertex.cs b/PCK-Studio/Rendering/TextureVertex.cs
similarity index 73%
rename from PCK-Studio/Rendering/Vertex.cs
rename to PCK-Studio/Rendering/TextureVertex.cs
index 8880a23f..682db8bf 100644
--- a/PCK-Studio/Rendering/Vertex.cs
+++ b/PCK-Studio/Rendering/TextureVertex.cs
@@ -11,17 +11,17 @@ using OpenTK.Graphics;
namespace PckStudio.Rendering
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
- internal struct Vertex
+ internal struct TextureVertex
{
- public Vertex(Vector3 position, Color4 color, Vector2 texPosition)
+ public static int SizeInBytes = Marshal.SizeOf(typeof(TextureVertex));
+
+ public TextureVertex(Vector3 position, Vector2 texPosition)
{
Position = position;
- Color = color;
TexPosition = texPosition;
}
internal Vector3 Position { get; set; }
- internal Color4 Color { get; set; }
internal Vector2 TexPosition { get; set; }
}
}
diff --git a/PCK-Studio/Resources/fragment.glsl b/PCK-Studio/Resources/fragment.glsl
deleted file mode 100644
index 0e178897..00000000
--- a/PCK-Studio/Resources/fragment.glsl
+++ /dev/null
@@ -1,19 +0,0 @@
-#version 330 core
-
-layout(location = 0) out vec4 color;
-
-uniform sampler2D u_Texture;
-
-in vec2 v_TexCoord;
-in vec4 v_VertexPos;
-in vec4 v_Color;
-
-void main()
-{
- vec4 texColor = texture(u_Texture, v_TexCoord);
- // color = vec4(v_VertexPos.xyz, 1.0);
- // color = vec4(v_TexCoord, 0.0, 1.0) * vec4(v_VertexPos.xyz, 1.0);
- // color = v_Color;
- // color = vec4(v_TexCoord, 0.0, 1.0);
- color = texColor;
-};
\ No newline at end of file
diff --git a/PCK-Studio/Resources/shader/skinFragment.glsl b/PCK-Studio/Resources/shader/skinFragment.glsl
new file mode 100644
index 00000000..fdd6d42c
--- /dev/null
+++ b/PCK-Studio/Resources/shader/skinFragment.glsl
@@ -0,0 +1,13 @@
+#version 330 core
+
+layout(location = 0) out vec4 color;
+
+uniform sampler2D u_Texture;
+
+in vec2 v_TexCoord;
+
+void main()
+{
+ vec4 texColor = texture(u_Texture, v_TexCoord);
+ color = texColor;
+};
\ No newline at end of file
diff --git a/PCK-Studio/Resources/shader/skinVertexShader.glsl b/PCK-Studio/Resources/shader/skinVertexShader.glsl
new file mode 100644
index 00000000..4bc46529
--- /dev/null
+++ b/PCK-Studio/Resources/shader/skinVertexShader.glsl
@@ -0,0 +1,15 @@
+#version 330 core
+
+layout(location = 0) in vec4 vertexPosition;
+layout(location = 1) in vec2 texCoord;
+
+uniform mat4 u_ViewProjection;
+uniform mat4 u_Model;
+
+out vec2 v_TexCoord;
+
+void main()
+{
+ v_TexCoord = texCoord;
+ gl_Position = u_ViewProjection * u_Model * vertexPosition;
+};
\ No newline at end of file
diff --git a/PCK-Studio/Resources/vertexShader.glsl b/PCK-Studio/Resources/vertexShader.glsl
deleted file mode 100644
index 439dc0d1..00000000
--- a/PCK-Studio/Resources/vertexShader.glsl
+++ /dev/null
@@ -1,19 +0,0 @@
-#version 330 core
-
-layout(location = 0) in vec4 vertexPosition;
-layout(location = 1) in vec4 color;
-layout(location = 2) in vec2 texCoord;
-
-uniform mat4 u_MVP;
-
-out vec2 v_TexCoord;
-out vec4 v_VertexPos;
-out vec4 v_Color;
-
-void main()
-{
- v_TexCoord = texCoord;
- v_Color = color;
- v_VertexPos = vertexPosition;
- gl_Position = u_MVP * vertexPosition;
-};
\ No newline at end of file