From e02d739144b44b2fcf1452c2c1ae126fac0a40a2 Mon Sep 17 00:00:00 2001 From: miku-666 <74728189+NessieHax@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:42:23 +0100 Subject: [PATCH] SkinRenderer - Fixed out of bound mapped UVs via geometry shader --- PCK-Studio/PckStudio.csproj | 1 + PCK-Studio/Properties/Resources.Designer.cs | 42 ++++++- PCK-Studio/Properties/Resources.resx | 3 + PCK-Studio/Rendering/CubeData.cs | 106 ++++++------------ PCK-Studio/Rendering/CubeRenderGroup.cs | 38 +------ PCK-Studio/Rendering/IndexBuffer.cs | 10 +- PCK-Studio/Rendering/RenderGroup.cs | 6 +- PCK-Studio/Rendering/Shader.cs | 13 ++- PCK-Studio/Rendering/SkinRenderer.Designer.cs | 17 --- PCK-Studio/Rendering/SkinRenderer.cs | 15 ++- PCK-Studio/Rendering/SkinRenderer.resx | 8 +- PCK-Studio/Rendering/Texture/Texture2D.cs | 6 +- .../Resources/shader/skinFragmentShader.glsl | 6 +- .../Resources/shader/skinGeometryShader.glsl | 47 ++++++++ .../Resources/shader/skinVertexShader.glsl | 7 +- 15 files changed, 162 insertions(+), 163 deletions(-) create mode 100644 PCK-Studio/Resources/shader/skinGeometryShader.glsl diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index 3380a05c..6bf48180 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -641,6 +641,7 @@ + diff --git a/PCK-Studio/Properties/Resources.Designer.cs b/PCK-Studio/Properties/Resources.Designer.cs index 98a02888..0857b2de 100644 --- a/PCK-Studio/Properties/Resources.Designer.cs +++ b/PCK-Studio/Properties/Resources.Designer.cs @@ -585,6 +585,34 @@ namespace PckStudio.Properties { } } + /// + /// Looks up a localized string similar to #version 330 core + /// + ///layout (triangles) in; + ///layout (triangle_strips, max_vertices = 3) out; + /// + ///uniform mat4 u_ViewProjection; + ///uniform mat4 u_Model; + /// + ///out vec2 v_TexCoord; + /// + ///in geometry_data + ///{ + /// vec2 texCoord; + /// vec2 texSize; + ///} dataIn[]; + /// + ///void main() + ///{ + /// gl_Position = gl_in.gl_Position; + ///};. + /// + public static string skinGeometryShader { + get { + return ResourceManager.GetString("skinGeometryShader", resourceCulture); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -604,16 +632,20 @@ namespace PckStudio.Properties { /// ///uniform mat4 u_ViewProjection; ///uniform mat4 u_Model; + ///uniform vec2 u_TexSize; /// - ///out vec2 v_TexCoord; + ///out geometry_data + ///{ + /// vec2 TexCoord; + /// vec2 TexSize; + ///} dataOut; /// ///void main() ///{ - /// v_TexCoord = texCoord; + /// dataOut.TexCoord = texCoord; + /// dataOut.TexSize = u_TexSize; /// vec4 scaledVertex = scale * vertexPosition; - /// vec4 invertedVertex = vec4(scaledVertex.x, scaledVertex.y * -1.0, scaledVertex.z * -1.0, 1.0); - /// gl_Position = u_ViewProjection * u_Model * invertedVertex; - ///};. + /// vec4 invertedVertex = vec4(scaledVertex.x, scaledVertex.y * -1.0, scaledVertex.z * -1.0, [rest of string was truncated]";. /// public static string skinVertexShader { get { diff --git a/PCK-Studio/Properties/Resources.resx b/PCK-Studio/Properties/Resources.resx index 962702fc..749e736c 100644 --- a/PCK-Studio/Properties/Resources.resx +++ b/PCK-Studio/Properties/Resources.resx @@ -343,4 +343,7 @@ ..\Resources\shader\skyboxVertexShader.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\shader\skinGeometryShader.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/CubeData.cs b/PCK-Studio/Rendering/CubeData.cs index d6eda8b6..22f75a32 100644 --- a/PCK-Studio/Rendering/CubeData.cs +++ b/PCK-Studio/Rendering/CubeData.cs @@ -26,10 +26,6 @@ namespace PckStudio.Rendering { internal class CubeData { - internal delegate void RefAction(ref T val); - - internal const int vertexCountPerCube = 24; - internal bool ShouldRender { get; set; } = true; internal Vector3 Position @@ -122,19 +118,25 @@ namespace PckStudio.Rendering private bool _mirrorTexture = false; private bool _flipZMapping = false; - private static uint[] indicesData = [ + private static int[] indicesData = [ // Face 1 (Back) - 0, 1, 2, 3, + 0, 1, 2, + 2, 3, 0, // Face 2 (Front) - 4, 5, 6, 7, + 4, 5, 6, + 6, 7, 4, // Face 3 (Top) - 8, 9, 10, 11, + 8, 9, 10, + 10, 11, 8, // Face 4 (Bottom) - 12, 13, 14, 15, + 12, 13, 14, + 14, 15, 12, // Face 5 (Left) - 16, 17, 18, 19, + 16, 17, 18, + 18, 19, 16, // Face 6 (Right) - 20, 21, 22, 23, + 20, 21, 22, + 22, 23, 20 ]; private TextureVertex[] vertices; @@ -174,16 +176,6 @@ namespace PckStudio.Rendering { } - internal enum CubeFace - { - Back, - Front, - Top, - Bottom, - Left, - Right, - } - private static TextureVertex[] GetCubeVertexData(Vector3 position, Vector3 size, Vector2 uv, float scale, bool mirrorTexture, bool flipZMapping) { @@ -193,50 +185,50 @@ namespace PckStudio.Rendering var back = new TextureVertex[] { // Back - new TextureVertex(new Vector3(position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z * 2 + size.X + size.X * (1 - mirror), uv.Y + size.Z + size.Y), scale), + new TextureVertex(new Vector3( position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z * 2 + size.X + size.X * (1 - mirror), uv.Y + size.Z + size.Y), scale), new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z * 2 + size.X + size.X * mirror, uv.Y + size.Z + size.Y), scale), - new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z * 2 + size.X + size.X * mirror, uv.Y + size.Z), scale), - new TextureVertex(new Vector3(position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z * 2 + size.X + size.X * (1 - mirror), uv.Y + size.Z), scale) + new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z * 2 + size.X + size.X * mirror, uv.Y + size.Z), scale), + new TextureVertex(new Vector3( position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z * 2 + size.X + size.X * (1 - mirror), uv.Y + size.Z), scale) }; var front = new TextureVertex[] { // Front - new TextureVertex(new Vector3(position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z + size.Y), scale), + new TextureVertex(new Vector3( position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z + size.Y), scale), new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y + size.Z + size.Y), scale), - new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y + size.Z), scale), - new TextureVertex(new Vector3(position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z), scale), + new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y + size.Z), scale), + new TextureVertex(new Vector3( position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z), scale), }; var top = new TextureVertex[] { // Top - new TextureVertex(new Vector3(position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z), scale), - new TextureVertex(new Vector3(position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y), scale), + new TextureVertex(new Vector3( position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z), scale), + new TextureVertex(new Vector3( position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y), scale), new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y), scale), - new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y + size.Z), scale), + new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y + size.Z), scale), }; var bottom = new TextureVertex[] { // Bottom - new TextureVertex(new Vector3(position.X + size.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X + size.X * (1 - mirror), uv.Y + (flipZMapping ? size.Z : 0)), scale), + new TextureVertex(new Vector3(position.X + size.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X + size.X * (1 - mirror), uv.Y + (flipZMapping ? size.Z : 0)), scale), new TextureVertex(new Vector3(position.X + size.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X + size.X * (1 - mirror), uv.Y + (!flipZMapping ? size.Z : 0)), scale), - new TextureVertex(new Vector3(position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X + size.X * mirror, uv.Y + (!flipZMapping ? size.Z : 0)), scale), - new TextureVertex(new Vector3(position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X + size.X * mirror, uv.Y + (flipZMapping ? size.Z : 0)), scale), + new TextureVertex(new Vector3(position.X , size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X + size.X * mirror, uv.Y + (!flipZMapping ? size.Z : 0)), scale), + new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X + size.X * mirror, uv.Y + (flipZMapping ? size.Z : 0)), scale), }; var left = new TextureVertex[] { // Left - new TextureVertex(new Vector3((1 - mirror) * size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.X + size.Z, uv.Y + size.Z), scale), - new TextureVertex(new Vector3((1 - mirror) * size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.X + size.Z, uv.Y + size.Z + size.Y), scale), + new TextureVertex(new Vector3((1 - mirror) * size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.X + size.Z, uv.Y + size.Z), scale), + new TextureVertex(new Vector3((1 - mirror) * size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.X + size.Z, uv.Y + size.Z + size.Y), scale), new TextureVertex(new Vector3((1 - mirror) * size.X + position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.X + size.Z * 2, uv.Y + size.Z + size.Y), scale), - new TextureVertex(new Vector3((1 - mirror) * size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.X + size.Z * 2, uv.Y + size.Z), scale), + new TextureVertex(new Vector3((1 - mirror) * size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.X + size.Z * 2, uv.Y + size.Z), scale), }; var right = new TextureVertex[] { // Right - new TextureVertex(new Vector3(mirror * size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z), scale), - new TextureVertex(new Vector3(mirror * size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y), scale), + new TextureVertex(new Vector3(mirror * size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z), scale), + new TextureVertex(new Vector3(mirror * size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y), scale), new TextureVertex(new Vector3(mirror * size.X + position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X, uv.Y + size.Z + size.Y), scale), - new TextureVertex(new Vector3(mirror * size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X, uv.Y + size.Z), scale), + new TextureVertex(new Vector3(mirror * size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X, uv.Y + size.Z), scale), }; vertices.AddRange(back); @@ -254,43 +246,9 @@ namespace PckStudio.Rendering return vertices; } - internal Vector2[] GetMappedFaceTextureUv(CubeFace face) - { - var indices = GetIndices(); - var faceInices = indices.Skip((int)face * 4).Take(4).ToArray(); - var vertices = GetVertices(); - var uv0 = vertices[faceInices[0]].TexPosition; - var uv1 = vertices[faceInices[1]].TexPosition; - var uv2 = vertices[faceInices[2]].TexPosition; - var uv3 = vertices[faceInices[3]].TexPosition; - return [uv0, uv1, uv2, uv3]; - } - - internal uint[] GetIndices() + internal int[] GetIndices() { return indicesData; } - - internal void SetFaceUv(CubeFace face, RefAction refAction) - { - var indices = GetIndices(); - var faceInices = indices.Skip((int)face * 4).Take(4).ToArray(); - var vertices = GetVertices(); - var uv0 = vertices[faceInices[0]].TexPosition; - refAction(ref uv0); - vertices[faceInices[0]].TexPosition = uv0; - - var uv1 = vertices[faceInices[1]].TexPosition; - refAction(ref uv1); - vertices[faceInices[1]].TexPosition = uv1; - - var uv2 = vertices[faceInices[2]].TexPosition; - refAction(ref uv2); - vertices[faceInices[2]].TexPosition = uv2; - - var uv3 = vertices[faceInices[3]].TexPosition; - refAction(ref uv3); - vertices[faceInices[3]].TexPosition = uv3; - } } } \ No newline at end of file diff --git a/PCK-Studio/Rendering/CubeRenderGroup.cs b/PCK-Studio/Rendering/CubeRenderGroup.cs index 7b705ec3..67fe8700 100644 --- a/PCK-Studio/Rendering/CubeRenderGroup.cs +++ b/PCK-Studio/Rendering/CubeRenderGroup.cs @@ -18,7 +18,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Drawing; using System.Linq; using OpenTK; using OpenTK.Graphics.OpenGL; @@ -33,7 +32,7 @@ namespace PckStudio.Rendering internal float Scale { get; set; } = 1f; - internal CubeRenderGroup(string name) : base(name, PrimitiveType.Quads) + internal CubeRenderGroup(string name) : base(name, PrimitiveType.Triangles) { cubes = new List(5); } @@ -65,23 +64,12 @@ namespace PckStudio.Rendering { if (!cube.ShouldRender) continue; - - vertices.AddRange(cube.GetVertices()); + + TextureVertex[] cubeVertices = cube.GetVertices(); + vertices.AddRange(cubeVertices); var indexStorage = cube.GetIndices(); indices.AddRange(indexStorage.Select(n => n + indicesOffset)); - indicesOffset += CubeData.vertexCountPerCube; - } - } - - private void CheckAndFixUVFaveMapping(CubeData cube, CubeData.CubeFace face, Size textureSize) - { - if (cube.GetMappedFaceTextureUv(face).All(texVert => texVert.X >= textureSize.Width)) - { - CubeData.RefAction fixUV = (ref Vector2 uv) => - { - uv.X %= textureSize.Width; - }; - cube.SetFaceUv(face, fixUV); + indicesOffset += cubeVertices.Length; } } @@ -113,21 +101,5 @@ namespace PckStudio.Rendering cubes[index].ShouldRender = enable; Submit(); } - - internal void Validate(Size textureSize) - { - if (!textureSize.IsEmpty) - { - foreach (var cube in cubes) - { - CheckAndFixUVFaveMapping(cube, CubeData.CubeFace.Back, textureSize); - CheckAndFixUVFaveMapping(cube, CubeData.CubeFace.Front, textureSize); - CheckAndFixUVFaveMapping(cube, CubeData.CubeFace.Top, textureSize); - CheckAndFixUVFaveMapping(cube, CubeData.CubeFace.Bottom, textureSize); - CheckAndFixUVFaveMapping(cube, CubeData.CubeFace.Left, textureSize); - CheckAndFixUVFaveMapping(cube, CubeData.CubeFace.Right, textureSize); - } - } - } } } diff --git a/PCK-Studio/Rendering/IndexBuffer.cs b/PCK-Studio/Rendering/IndexBuffer.cs index ee4d5321..7937d575 100644 --- a/PCK-Studio/Rendering/IndexBuffer.cs +++ b/PCK-Studio/Rendering/IndexBuffer.cs @@ -11,11 +11,11 @@ namespace PckStudio.Rendering internal class IndexBuffer : IDisposable { private int _id; - private List _indecies; + private List _indecies; - public IndexBuffer(params uint[] indecies) + public IndexBuffer(params int[] indecies) { - _indecies = new List(indecies); + _indecies = new List(indecies); } /// @@ -23,7 +23,7 @@ namespace PckStudio.Rendering /// /// /// - public static IndexBuffer Create(params uint[] indecies) + public static IndexBuffer Create(params int[] indecies) { var ib = new IndexBuffer(indecies); ib.Attach(); @@ -34,7 +34,7 @@ namespace PckStudio.Rendering { _id = GL.GenBuffer(); Bind(); - GL.BufferData(BufferTarget.ElementArrayBuffer, _indecies.Count * sizeof(uint), _indecies.ToArray(), BufferUsageHint.StaticDraw); + GL.BufferData(BufferTarget.ElementArrayBuffer, _indecies.Count * sizeof(int), _indecies.ToArray(), BufferUsageHint.StaticDraw); } public int GetCount() => _indecies.Count; diff --git a/PCK-Studio/Rendering/RenderGroup.cs b/PCK-Studio/Rendering/RenderGroup.cs index a15873f9..5ac3230e 100644 --- a/PCK-Studio/Rendering/RenderGroup.cs +++ b/PCK-Studio/Rendering/RenderGroup.cs @@ -29,8 +29,8 @@ namespace PckStudio.Rendering internal readonly int SizeInBytes = Marshal.SizeOf(); protected List vertices; - protected List indices; - protected uint indicesOffset; + protected List indices; + protected int indicesOffset; private VertexArray vertexArray; private VertexBuffer vertexBuffer; @@ -44,7 +44,7 @@ namespace PckStudio.Rendering drawType = type; indicesOffset = 0; vertices = new List(10); - indices = new List(10); + indices = new List(10); _layout = new T().GetLayout(); } diff --git a/PCK-Studio/Rendering/Shader.cs b/PCK-Studio/Rendering/Shader.cs index d349b08f..8a542cc6 100644 --- a/PCK-Studio/Rendering/Shader.cs +++ b/PCK-Studio/Rendering/Shader.cs @@ -86,8 +86,7 @@ namespace PckStudio.Rendering if (status == 0) { - GL.GetShader(shaderId, ShaderParameter.InfoLogLength, out int length); - GL.GetShaderInfoLog(shaderId, length, out _, out string infoLog); + string infoLog = GL.GetShaderInfoLog(shaderId); GL.DeleteShader(shaderId); Trace.Fail(infoLog); return 0; @@ -107,16 +106,20 @@ namespace PckStudio.Rendering { GL.LinkProgram(_programId); GL.GetProgram(_programId, GetProgramParameterName.LinkStatus, out int status); - return status != 0; + bool success = status != 0; + if (!success) + Debug.WriteLine(GL.GetProgramInfoLog(_programId), category: nameof(Shader)); + return success; } public bool Validate() { GL.ValidateProgram(_programId); GL.GetProgram(_programId, GetProgramParameterName.ValidateStatus, out int status); - if (status == 0) + bool success = status != 0; + if (!success) Debug.WriteLine(GL.GetProgramInfoLog(_programId), category: nameof(Shader)); - return status != 0; + return success; } public static Shader Create(params ShaderSource[] shaderSources) diff --git a/PCK-Studio/Rendering/SkinRenderer.Designer.cs b/PCK-Studio/Rendering/SkinRenderer.Designer.cs index 05bc02c7..6828d002 100644 --- a/PCK-Studio/Rendering/SkinRenderer.Designer.cs +++ b/PCK-Studio/Rendering/SkinRenderer.Designer.cs @@ -35,25 +35,11 @@ namespace PckStudio.Rendering private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - this.moveTimer = new System.Windows.Forms.Timer(this.components); - this.animationTimer = new System.Windows.Forms.Timer(this.components); this.reToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.contextMenuStrip1.SuspendLayout(); this.SuspendLayout(); // - // moveTimer - // - this.moveTimer.Enabled = true; - this.moveTimer.Interval = 1; - this.moveTimer.Tick += new System.EventHandler(this.moveTimer_Tick); - // - // animationTimer - // - this.animationTimer.Enabled = true; - this.animationTimer.Interval = 50; - this.animationTimer.Tick += new System.EventHandler(this.animationTimer_Tick); - // // reToolStripMenuItem // this.reToolStripMenuItem.Name = "reToolStripMenuItem"; @@ -76,9 +62,6 @@ namespace PckStudio.Rendering this.ResumeLayout(false); } - - private System.Windows.Forms.Timer moveTimer; - private System.Windows.Forms.Timer animationTimer; private System.Windows.Forms.ToolStripMenuItem reToolStripMenuItem; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; } diff --git a/PCK-Studio/Rendering/SkinRenderer.cs b/PCK-Studio/Rendering/SkinRenderer.cs index ab6d1883..1709d3a7 100644 --- a/PCK-Studio/Rendering/SkinRenderer.cs +++ b/PCK-Studio/Rendering/SkinRenderer.cs @@ -104,8 +104,7 @@ namespace PckStudio.Rendering } } - internal Vector2 UvTranslation { get; private set; } = new Vector2(1f / 64); - private Size TextureSize = new Size(64, 64); + public Size TextureSize { get; private set; } = new Size(64, 64); private const float OverlayScale = 1.12f; private bool _isLeftMouseDown; @@ -397,7 +396,11 @@ namespace PckStudio.Rendering // Initialize skin shader { - _skinShader = Shader.Create(Resources.skinVertexShader, Resources.skinFragmentShader); + _skinShader = Shader.Create( + new ShaderSource(ShaderType.VertexShader, Resources.skinVertexShader), + new ShaderSource(ShaderType.FragmentShader, Resources.skinFragmentShader), + new ShaderSource(ShaderType.GeometryShader, Resources.skinGeometryShader) + ); _skinShader.Bind(); _skinShader.Validate(); @@ -488,7 +491,7 @@ namespace PckStudio.Rendering bool slim = ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL); if (slim || ANIM.GetFlag(SkinAnimFlag.RESOLUTION_64x64)) { - UvTranslation = new Vector2(1f / 64); + TextureSize = new Size(64, 64); bodyOverlay.SetEnabled(0, !ANIM.GetFlag(SkinAnimFlag.BODY_OVERLAY_DISABLED)); rightArmOverlay.SetEnabled(0, !ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED)); leftArmOverlay.SetEnabled(0, !ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED)); @@ -506,7 +509,7 @@ namespace PckStudio.Rendering return; } - UvTranslation = new Vector2(1f / 64, 1f / 32); + TextureSize = new Size(64, 32); rightArm.ReplaceCube(0, new(-3, -2, -2), new(4, 12, 4), new(40, 16)); rightArmOverlay.SetEnabled(0, false); @@ -533,7 +536,7 @@ namespace PckStudio.Rendering var viewProjection = camera.GetViewProjection(); _skinShader.Bind(); _skinShader.SetUniformMat4("u_ViewProjection", ref viewProjection); - _skinShader.SetUniform2("u_TexScale", UvTranslation); + _skinShader.SetUniform2("u_TexSize", new Vector2(TextureSize.Width, TextureSize.Height)); GL.Viewport(Size); diff --git a/PCK-Studio/Rendering/SkinRenderer.resx b/PCK-Studio/Rendering/SkinRenderer.resx index 986e3e38..b6091f39 100644 --- a/PCK-Studio/Rendering/SkinRenderer.resx +++ b/PCK-Studio/Rendering/SkinRenderer.resx @@ -117,13 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 17, 17 - - - 131, 17 - - 269, 17 + 16, 20 \ No newline at end of file diff --git a/PCK-Studio/Rendering/Texture/Texture2D.cs b/PCK-Studio/Rendering/Texture/Texture2D.cs index 0687129f..c09d51e7 100644 --- a/PCK-Studio/Rendering/Texture/Texture2D.cs +++ b/PCK-Studio/Rendering/Texture/Texture2D.cs @@ -36,9 +36,9 @@ namespace PckStudio.Rendering.Texture SetTexParameter(TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); SetTexParameter(TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); - - SetTexParameter(TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder); - SetTexParameter(TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder); + + SetTexParameter(TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + SetTexParameter(TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); 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); diff --git a/PCK-Studio/Resources/shader/skinFragmentShader.glsl b/PCK-Studio/Resources/shader/skinFragmentShader.glsl index 2776f3c6..cfa69e6a 100644 --- a/PCK-Studio/Resources/shader/skinFragmentShader.glsl +++ b/PCK-Studio/Resources/shader/skinFragmentShader.glsl @@ -3,11 +3,11 @@ layout(location = 0) out vec4 color; uniform sampler2D u_Texture; -uniform vec2 u_TexScale; -in vec2 v_TexCoord; +in vec2 o_TexScale; +in vec2 o_TexCoord; void main() { - color = texture(u_Texture, v_TexCoord * u_TexScale); + color = texture(u_Texture, o_TexCoord * o_TexScale); }; \ No newline at end of file diff --git a/PCK-Studio/Resources/shader/skinGeometryShader.glsl b/PCK-Studio/Resources/shader/skinGeometryShader.glsl new file mode 100644 index 00000000..2423ce57 --- /dev/null +++ b/PCK-Studio/Resources/shader/skinGeometryShader.glsl @@ -0,0 +1,47 @@ +#version 330 core + +layout (triangles) in; +layout (triangle_strip, max_vertices=3) out; + +uniform vec2 u_TexSize; + +out vec2 o_TexCoord; +out vec2 o_TexScale; + +in geometryData +{ + vec2 TexCoord; +} dataIn[]; + +void FixUV() +{ + bool isXBad = + dataIn[0].TexCoord.x >= u_TexSize.x && + dataIn[1].TexCoord.x >= u_TexSize.x && + dataIn[2].TexCoord.x >= u_TexSize.x; + + gl_Position = gl_in[0].gl_Position; + o_TexCoord = dataIn[0].TexCoord; + if (isXBad) + o_TexCoord.x = mod(o_TexCoord.x, u_TexSize.x); + EmitVertex(); + + gl_Position = gl_in[1].gl_Position; + o_TexCoord = dataIn[1].TexCoord; + if (isXBad) + o_TexCoord.x = mod(o_TexCoord.x, u_TexSize.x); + EmitVertex(); + + gl_Position = gl_in[2].gl_Position; + o_TexCoord = dataIn[2].TexCoord; + if (isXBad) + o_TexCoord.x = mod(o_TexCoord.x, u_TexSize.x); + EmitVertex(); +} + +void main() +{ + o_TexScale = 1.0 / u_TexSize; + FixUV(); + EndPrimitive(); +}; \ No newline at end of file diff --git a/PCK-Studio/Resources/shader/skinVertexShader.glsl b/PCK-Studio/Resources/shader/skinVertexShader.glsl index 41f8b276..b5a3cf3e 100644 --- a/PCK-Studio/Resources/shader/skinVertexShader.glsl +++ b/PCK-Studio/Resources/shader/skinVertexShader.glsl @@ -7,11 +7,14 @@ layout(location = 2) in float scale; uniform mat4 u_ViewProjection; uniform mat4 u_Model; -out vec2 v_TexCoord; +out geometryData +{ + vec2 TexCoord; +} dataOut; void main() { - v_TexCoord = texCoord; + dataOut.TexCoord = texCoord; vec4 scaledVertex = scale * vertexPosition; vec4 invertedVertex = vec4(scaledVertex.x, scaledVertex.y * -1.0, scaledVertex.z * -1.0, 1.0); gl_Position = u_ViewProjection * u_Model * invertedVertex;