[WIP] Added texture/Uv mapping from skinbox data

This commit is contained in:
miku-666
2023-10-20 21:50:52 +02:00
parent f2aa8a9324
commit d5906cac96
24 changed files with 744 additions and 594 deletions

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
//

View File

@@ -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);

View File

@@ -28,7 +28,7 @@
/// </summary>
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;
}
}

View File

@@ -45,7 +45,7 @@ namespace PckStudio.Internal
}
public static SkinBOX FromString(string value)
{
{
var arguments = value.Split(' ');
if (arguments.Length < 9)
{

View File

@@ -136,6 +136,7 @@
<ItemGroup>
<Compile Include="Classes\Utils\Ray.cs" />
<Compile Include="Extensions\PckFileDataExtensions.cs" />
<Compile Include="Extensions\System.Numerics.cs" />
<Compile Include="Extensions\TreeNodeExtensions.cs" />
<Compile Include="Forms\TestGL.cs">
<SubType>Form</SubType>
@@ -152,11 +153,20 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Rendering\Camera.cs" />
<Compile Include="Rendering\IndexBuffer.cs" />
<Compile Include="Rendering\RenderBuffer.cs" />
<Compile Include="Rendering\Renderer.cs" />
<Compile Include="Rendering\RenderGroup.cs" />
<Compile Include="Rendering\Shader.cs" />
<Compile Include="Rendering\SkinRenderer.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Rendering\SkinRenderer.Designer.cs">
<DependentUpon>SkinRenderer.cs</DependentUpon>
</Compile>
<Compile Include="Rendering\Texture2D.cs" />
<Compile Include="Rendering\Vertex.cs" />
<Compile Include="Rendering\TextureVertex.cs" />
<Compile Include="Rendering\VertexArray.cs" />
<Compile Include="Rendering\VertexBuffer.cs" />
<Compile Include="Rendering\VertexBufferLayout.cs" />
@@ -169,9 +179,6 @@
<Compile Include="Rendering\Renderer3D.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Rendering\Renderer3D.Designer.cs">
<DependentUpon>Renderer3D.cs</DependentUpon>
</Compile>
<Compile Include="ToolboxItems\ToolStripRadioButtonMenuItem.cs">
<SubType>Component</SubType>
</Compile>
@@ -629,7 +636,7 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\vertexShader.glsl" />
<None Include="Resources\shader\skinVertexShader.glsl" />
<None Include="Resources\entityData.json" />
<None Include="Resources\TexturePackIcon.png" />
<None Include="Resources\binka\binkawin.asi" />
@@ -682,7 +689,7 @@
<None Include="Resources\iconImageList\ENTITY MATERIALS ICON.png" />
<None Include="Resources\iconImageList\blank.png" />
<None Include="Resources\entities.png" />
<None Include="Resources\fragment.glsl" />
<None Include="Resources\shader\skinFragment.glsl" />
<Content Include="Resources\icons\file_delete.png" />
<Content Include="Resources\icons\file_empty.png" />
<None Include="Resources\icons\file_export.png" />

View File

@@ -334,22 +334,6 @@ namespace PckStudio.Properties {
}
}
/// <summary>
/// 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);
///};.
/// </summary>
public static string fragmentShader {
get {
return ResourceManager.GetString("fragmentShader", resourceCulture);
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@@ -570,6 +554,33 @@ namespace PckStudio.Properties {
}
}
/// <summary>
/// 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;
///};.
/// </summary>
public static string skinFragment {
get {
return ResourceManager.GetString("skinFragment", resourceCulture);
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@@ -580,6 +591,34 @@ namespace PckStudio.Properties {
}
}
/// <summary>
/// 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;
///};.
/// </summary>
public static string skinVertexShader {
get {
return ResourceManager.GetString("skinVertexShader", resourceCulture);
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@@ -781,22 +820,6 @@ namespace PckStudio.Properties {
}
}
/// <summary>
/// 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);
///};.
/// </summary>
public static string vertexShader {
get {
return ResourceManager.GetString("vertexShader", resourceCulture);
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View File

@@ -328,10 +328,10 @@
<data name="ProjectLogo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\..\ProjectLogo.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="vertexShader" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\vertexShader.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
<data name="skinFragment" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\shader\skinFragment.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="fragmentShader" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\fragment.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
<data name="skinVertexShader" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\shader\skinVertexShader.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
</root>

View File

@@ -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}";
}
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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<TextureVertex> vertices;
private List<uint> indices;
private uint indicesOffset;
internal RenderGroup(string name)
{
Name = name;
vertices = new List<TextureVertex>();
indices = new List<uint>();
indicesOffset = 0;
}
internal RenderBuffer GetRenderBuffer()
{
var vertexData = vertices.ToArray();
var buffer = new VertexBuffer<TextureVertex>(vertexData, vertexData.Length * TextureVertex.SizeInBytes);
var layout = new VertexBufferLayout();
layout.Add<float>(3);
layout.Add<float>(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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
/// <summary>
/// The visible Texture on the renderer
/// </summary>
/// <returns>The visible Texture</returns>
[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
}
/// <summary>
/// The rendered model
/// </summary>
/// <returns>The rendered model</returns>
[Description("The current player model")]
[Category("Appearance")]
public Models Model { get; set; }
private Vector2 _rotation = new Vector2();
/// <summary>
/// Rotation
/// </summary>
/// <returns>Rotation</returns>
[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<Vertex>(bodyVertexData, bodyVertexData.Length * vertexSize);
var layout = new VertexBufferLayout();
layout.Add<float>(3);
layout.Add<float>(4);
layout.Add<float>(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<Point> MousePoints = new List<Point>();
private List<Point> tmpMousePoints = new List<Point>();
public event TextureChangedEventHandler TextureChanged;
public delegate void TextureChangedEventHandler(object sender, bool IsLeft);
}
}

View File

@@ -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);

View File

@@ -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
}
}
}

View File

@@ -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
{
/// <summary>
/// The visible Texture on the renderer
/// </summary>
/// <returns>The visible Texture</returns>
[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<string, RenderGroup> 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<string, RenderGroup>(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<TextureVertex>(vertexData, vertexData.Length * TextureVertex.SizeInBytes);
var layout = new VertexBufferLayout();
layout.Add<float>(3);
layout.Add<float>(4);
layout.Add<float>(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;
}
}
}
}

View File

@@ -51,11 +51,6 @@ namespace PckStudio.Rendering
GL.BindTexture(TextureTarget.Texture2D, _id);
}
public void Bind()
{
Bind(0);
}
[Conditional("DEBUG")]
public void Unbind()
{

View File

@@ -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; }
}
}

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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;
};