SkinRenderer - Fixed out of bound mapped UVs via geometry shader

This commit is contained in:
miku-666
2024-02-05 11:42:23 +01:00
parent 88a6abcc47
commit e02d739144
15 changed files with 162 additions and 163 deletions

View File

@@ -641,6 +641,7 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\shader\skinGeometryShader.glsl" />
<None Include="Resources\shader\skyboxFragmentShader.glsl" />
<None Include="Resources\shader\skyboxVertexShader.glsl" />
<None Include="Resources\skybox_texture.png" />

View File

@@ -585,6 +585,34 @@ namespace PckStudio.Properties {
}
}
/// <summary>
/// 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;
///};.
/// </summary>
public static string skinGeometryShader {
get {
return ResourceManager.GetString("skinGeometryShader", resourceCulture);
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@@ -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]&quot;;.
/// </summary>
public static string skinVertexShader {
get {

View File

@@ -343,4 +343,7 @@
<data name="skyboxVertexShader" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\shader\skyboxVertexShader.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="skinGeometryShader" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\shader\skinGeometryShader.glsl;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
</root>

View File

@@ -26,10 +26,6 @@ namespace PckStudio.Rendering
{
internal class CubeData
{
internal delegate void RefAction<T>(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<Vector2> 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;
}
}
}

View File

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

View File

@@ -11,11 +11,11 @@ namespace PckStudio.Rendering
internal class IndexBuffer : IDisposable
{
private int _id;
private List<uint> _indecies;
private List<int> _indecies;
public IndexBuffer(params uint[] indecies)
public IndexBuffer(params int[] indecies)
{
_indecies = new List<uint>(indecies);
_indecies = new List<int>(indecies);
}
/// <summary>
@@ -23,7 +23,7 @@ namespace PckStudio.Rendering
/// </summary>
/// <param name="indecies"></param>
/// <returns></returns>
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;

View File

@@ -29,8 +29,8 @@ namespace PckStudio.Rendering
internal readonly int SizeInBytes = Marshal.SizeOf<T>();
protected List<T> vertices;
protected List<uint> indices;
protected uint indicesOffset;
protected List<int> indices;
protected int indicesOffset;
private VertexArray vertexArray;
private VertexBuffer<T> vertexBuffer;
@@ -44,7 +44,7 @@ namespace PckStudio.Rendering
drawType = type;
indicesOffset = 0;
vertices = new List<T>(10);
indices = new List<uint>(10);
indices = new List<int>(10);
_layout = new T().GetLayout();
}

View File

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

View File

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

View File

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

View File

@@ -117,13 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="moveTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="animationTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>131, 17</value>
</metadata>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>269, 17</value>
<value>16, 20</value>
</metadata>
</root>

View File

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

View File

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

View File

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

View File

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