diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj
index 66b4c602..cd7f3d5e 100644
--- a/PCK-Studio/PckStudio.csproj
+++ b/PCK-Studio/PckStudio.csproj
@@ -150,12 +150,12 @@
True
Resources.resx
-
+
+
-
@@ -167,9 +167,11 @@
SkinRenderer.cs
-
+
+
+
diff --git a/PCK-Studio/Rendering/Camera.cs b/PCK-Studio/Rendering/Camera/Camera.cs
similarity index 93%
rename from PCK-Studio/Rendering/Camera.cs
rename to PCK-Studio/Rendering/Camera/Camera.cs
index 35aee8d7..5283847d 100644
--- a/PCK-Studio/Rendering/Camera.cs
+++ b/PCK-Studio/Rendering/Camera/Camera.cs
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
using System.Windows.Media.Media3D;
using OpenTK;
-namespace PckStudio.Rendering
+namespace PckStudio.Rendering.Camera
{
internal abstract class Camera
{
diff --git a/PCK-Studio/Rendering/PerspectiveCamera.cs b/PCK-Studio/Rendering/Camera/PerspectiveCamera.cs
similarity index 89%
rename from PCK-Studio/Rendering/PerspectiveCamera.cs
rename to PCK-Studio/Rendering/Camera/PerspectiveCamera.cs
index 3f9f54bc..1f905624 100644
--- a/PCK-Studio/Rendering/PerspectiveCamera.cs
+++ b/PCK-Studio/Rendering/Camera/PerspectiveCamera.cs
@@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using OpenTK;
-namespace PckStudio.Rendering
+namespace PckStudio.Rendering.Camera
{
internal class PerspectiveCamera : Camera
{
@@ -21,6 +21,8 @@ namespace PckStudio.Rendering
set => _position.Xy = value;
}
+ public Vector3 WorldPosition => _position;
+
public Vector2 Rotation
{
get => _rotation;
@@ -31,6 +33,9 @@ namespace PckStudio.Rendering
}
}
+ public Vector3 Orientation => -Vector3.UnitZ;
+
+ public Vector3 Up = Vector3.UnitY;
public float MinimumFov { get; set; } = 30f;
public float MaximumFov { get; set; } = 120f;
public float Fov
@@ -55,7 +60,6 @@ namespace PckStudio.Rendering
private Vector3 _position;
private Vector2 _rotation;
- private Vector3 _target;
internal override Matrix4 GetViewProjection()
@@ -65,12 +69,11 @@ namespace PckStudio.Rendering
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;
+ viewMatrix = Matrix4.LookAt(_position, _position + Orientation, Up) * rotation;
}
internal override void Update(float aspect)
@@ -82,7 +85,6 @@ namespace PckStudio.Rendering
internal void LookAt(Vector2 pos)
{
- _target = new Vector3(pos);
Position = pos;
}
diff --git a/PCK-Studio/Rendering/Renderer3D.cs b/PCK-Studio/Rendering/Renderer3D.cs
index 95af604a..b8efa99c 100644
--- a/PCK-Studio/Rendering/Renderer3D.cs
+++ b/PCK-Studio/Rendering/Renderer3D.cs
@@ -28,6 +28,7 @@ https://github.com/KareemMAX/Minecraft-Skiner/blob/master/src/Minecraft%20skiner
using System;
using System.Windows.Forms;
using OpenTK;
+using PckStudio.Rendering.Camera;
namespace PckStudio.Rendering
{
diff --git a/PCK-Studio/Rendering/SkinRenderer.cs b/PCK-Studio/Rendering/SkinRenderer.cs
index 08f67572..e29ed60b 100644
--- a/PCK-Studio/Rendering/SkinRenderer.cs
+++ b/PCK-Studio/Rendering/SkinRenderer.cs
@@ -31,6 +31,8 @@ using PckStudio.Forms.Editor;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Drawing.Imaging;
+using PckStudio.Rendering.Camera;
+using PckStudio.Rendering.Texture;
namespace PckStudio.Rendering
{
diff --git a/PCK-Studio/Rendering/Texture/CubeTexture.cs b/PCK-Studio/Rendering/Texture/CubeTexture.cs
new file mode 100644
index 00000000..48c03a19
--- /dev/null
+++ b/PCK-Studio/Rendering/Texture/CubeTexture.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OpenTK.Graphics.OpenGL;
+using PckStudio.Extensions;
+
+namespace PckStudio.Rendering.Texture
+{
+ internal class CubeTexture : Texture
+ {
+ public CubeTexture(Image cubeTexture)
+ : base(TextureTarget.TextureCubeMap)
+ {
+ Bind();
+
+ GL.GenerateMipmap(GenerateMipmapTarget.TextureCubeMap);
+
+ SetTexParameter(TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
+ SetTexParameter(TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
+
+ SetTexParameter(TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
+ SetTexParameter(TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
+ SetTexParameter(TextureParameterName.TextureWrapR, (int)TextureWrapMode.ClampToEdge);
+
+ int heightPerFace = cubeTexture.Height / 3;
+ int widthPerFace = cubeTexture.Width / 4;
+
+ Size faceSize = new Size(widthPerFace, heightPerFace);
+
+ Image[] faces = new Image[6];
+
+ Point rightFace = new Point(widthPerFace * 2, heightPerFace * 1);
+ faces[0] = cubeTexture.GetArea(new Rectangle(rightFace, faceSize));
+
+ Point lefttFace = new Point(widthPerFace * 0, heightPerFace * 1);
+ faces[1] = cubeTexture.GetArea(new Rectangle(lefttFace, faceSize));
+
+ Point topFace = new Point(widthPerFace * 1, heightPerFace * 0);
+ faces[2] = cubeTexture.GetArea(new Rectangle(topFace, faceSize));
+
+ Point bottomFace = new Point(widthPerFace * 1, heightPerFace * 2);
+ faces[3] = cubeTexture.GetArea(new Rectangle(bottomFace, faceSize));
+
+ Point frontFace = new Point(widthPerFace * 1, heightPerFace * 1);
+ faces[4] = cubeTexture.GetArea(new Rectangle(frontFace, faceSize));
+
+ Point backFace = new Point(widthPerFace * 3, heightPerFace * 1);
+ faces[5] = cubeTexture.GetArea(new Rectangle(backFace, faceSize));
+
+ for(int i = 0; i < 6; i++)
+ {
+ var texture = new Bitmap(faces[i]);
+ BitmapData data = texture.LockBits(new Rectangle(Point.Empty, texture.Size), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ GL.TexImage2D(TextureTarget.TextureCubeMapPositiveX + i, 0, PixelInternalFormat.Rgb8, widthPerFace, heightPerFace, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
+ }
+ }
+ }
+}
diff --git a/PCK-Studio/Rendering/Texture/Texture.cs b/PCK-Studio/Rendering/Texture/Texture.cs
new file mode 100644
index 00000000..a0fc7b6f
--- /dev/null
+++ b/PCK-Studio/Rendering/Texture/Texture.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json.Linq;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+
+namespace PckStudio.Rendering.Texture
+{
+ internal class Texture
+ {
+ protected readonly int _id;
+
+ protected TextureTarget Target;
+
+ protected Texture(TextureTarget target)
+ {
+ _id = GL.GenTexture();
+ Target = target;
+ }
+
+ public void Bind()
+ {
+ GL.BindTexture(Target, _id);
+ }
+
+ public void Bind(int slot)
+ {
+ Debug.Assert(slot >= 0 || slot < 32, "Slot is out of range");
+ slot = MathHelper.Clamp(slot, 0, 31);
+ Bind();
+ GL.ActiveTexture(TextureUnit.Texture0 + slot);
+ }
+
+ public void Unbind()
+ {
+ GL.BindTexture(Target, 0);
+ }
+
+ public void SetTexParameter(TextureParameterName parameterName, int value)
+ {
+ GL.TexParameter(Target, parameterName, value);
+ Debug.WriteLineIf(GL.GetError() != ErrorCode.NoError, $"{Target}: {parameterName} = {value}");
+ }
+ }
+}
diff --git a/PCK-Studio/Rendering/Texture/Texture2D.cs b/PCK-Studio/Rendering/Texture/Texture2D.cs
new file mode 100644
index 00000000..387b42d3
--- /dev/null
+++ b/PCK-Studio/Rendering/Texture/Texture2D.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Imaging;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+
+namespace PckStudio.Rendering.Texture
+{
+ internal class Texture2D : Texture
+ {
+ public Texture2D(string filepath)
+ : this(Image.FromFile(filepath))
+ {
+
+ }
+
+ public Texture2D(Image image)
+ : this(new Bitmap(image))
+ {
+
+ }
+
+ public Texture2D(Image image, int slot)
+ : this(new Bitmap(image), slot)
+ {
+
+ }
+
+ private Texture2D(Bitmap bitmap, int slot = 0)
+ : base(TextureTarget.Texture2D)
+ {
+ Bind(slot);
+
+ GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
+
+ SetTexParameter(TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
+ SetTexParameter(TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
+
+ SetTexParameter(TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
+ SetTexParameter(TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
+
+ var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, bitmap.Width, bitmap.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
+ bitmap.UnlockBits(data);
+
+ Unbind();
+ }
+
+ public void Dispose()
+ {
+ Unbind();
+ GL.DeleteTexture(_id);
+ }
+
+ public static implicit operator Texture2D(Bitmap image) => new Texture2D(image);
+ }
+}
diff --git a/PCK-Studio/Rendering/Texture2D.cs b/PCK-Studio/Rendering/Texture2D.cs
deleted file mode 100644
index 0112d9e8..00000000
--- a/PCK-Studio/Rendering/Texture2D.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Drawing;
-using System.Drawing.Imaging;
-using OpenTK;
-using OpenTK.Graphics.OpenGL;
-
-namespace PckStudio.Rendering
-{
- internal class Texture2D : IDisposable
- {
- private int _id;
-
- public Texture2D(string filepath)
- : this(Image.FromFile(filepath))
- {
-
- }
-
- public Texture2D(Image image)
- : this(new Bitmap(image))
- {
-
- }
-
- private Texture2D(Bitmap bitmap)
- {
- _id = GL.GenTexture();
- GL.BindTexture(TextureTarget.Texture2D, _id);
-
- GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
-
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
-
- var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
- GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, bitmap.Width, bitmap.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
- bitmap.UnlockBits(data);
-
- GL.BindTexture(TextureTarget.Texture2D, 0);
- }
-
- public void Bind(int slot)
- {
- Debug.Assert(slot >= 0 || slot < 32, "Slot is out of range");
- slot = MathHelper.Clamp(slot, 0, 31);
- GL.ActiveTexture(TextureUnit.Texture0 + slot);
- GL.BindTexture(TextureTarget.Texture2D, _id);
- }
-
- [Conditional("DEBUG")]
- public void Unbind()
- {
- GL.BindTexture(TextureTarget.Texture2D, 0);
- }
-
- public void Dispose()
- {
- Unbind();
- GL.DeleteTexture(_id);
- }
-
- }
-}