diff --git a/GlitchyEngine/src/Renderer/Renderer2D.bf b/GlitchyEngine/src/Renderer/Renderer2D.bf index 9500e1b..1f5c2d8 100644 --- a/GlitchyEngine/src/Renderer/Renderer2D.bf +++ b/GlitchyEngine/src/Renderer/Renderer2D.bf @@ -618,9 +618,27 @@ namespace GlitchyEngine.Renderer s_circleInstanceQueue.Clear(); } + /// A specialized function that calculates the 2D transform matrix + private static Matrix Calculate2DTransform(Vector3 translation, Vector2 scale, float rotation) + { + float sin = 0.0f; + float cos = 1.0f; + + if (rotation != 0.0f) + { + sin = Math.Sin(rotation); + cos = Math.Cos(rotation); + } + + return .(cos * scale.X, -sin * scale.Y, 0, translation.X, + sin * scale.X, cos * scale.Y, 0, translation.Y, + 0 , 0 , 1, translation.Z, + 0 , 0 , 0, 1); + } + // Primitives - // Quad + // Colored Quad public static void DrawQuad(Vector2 position, Vector2 size, float rotation, ColorRGBA color) { @@ -648,33 +666,64 @@ namespace GlitchyEngine.Renderer DrawQuad(transform, s_whiteTexture, color); } + // Quad Subtexture + + [Inline] + private static Vector4 CalculateSubTexcoords(Vector4 texCoords, Vector4 innerTexcoords) + { + Vector4 uv = texCoords; + uv.XY += innerTexcoords.XY * uv.ZW; + uv.ZW *= innerTexcoords.ZW; + + return uv; + } + + // Subtex only + + public static void DrawQuad(Vector2 position, Vector2 size, float rotation, SubTexture2D texture, ColorRGBA color = .White) + { + DrawQuad(Vector3(position, 0.0f), size, rotation, texture.Texture, .White, texture.TexCoords); + } + + public static void DrawQuad(Vector3 position, Vector2 size, float rotation, SubTexture2D texture, ColorRGBA color = .White) + { + DrawQuad(position, size, rotation, texture.Texture, .White, texture.TexCoords); + } + + public static void DrawQuad(Matrix transform, SubTexture2D texture, ColorRGBA color = .White) + { + DrawQuad(transform, texture.Texture, .White, texture.TexCoords); + } + + // Subtex + Texcoords + + public static void DrawQuad(Vector2 position, Vector2 size, float rotation, SubTexture2D subtexture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) + { + Vector4 uv = CalculateSubTexcoords(subtexture.TexCoords, uvTransform); + + DrawQuad(Vector3(position, 0.0f), size, rotation, subtexture.Texture, .White, uv); + } + + public static void DrawQuad(Vector3 position, Vector2 size, float rotation, SubTexture2D subtexture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) + { + Vector4 uv = CalculateSubTexcoords(subtexture.TexCoords, uvTransform); + + DrawQuad(position, size, rotation, subtexture.Texture, .White, uv); + } + + public static void DrawQuad(Matrix transform, SubTexture2D subtexture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) + { + Vector4 uv = CalculateSubTexcoords(subtexture.TexCoords, uvTransform); + + DrawQuad(transform, subtexture.Texture, .White, uv); + } + + // Textured Quad + public static void DrawQuad(Vector2 position, Vector2 size, float rotation, Texture2D texture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) { DrawQuad(Vector3(position, 0.0f), size, rotation, texture, color, uvTransform); } - - public static void DrawQuadPivotCorner(Vector2 position, Vector2 size, float rotation, Texture2D texture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) - { - DrawQuadPivotCorner(Vector3(position, 0.0f), size, rotation, texture, color, uvTransform); - } - - /// A specialized function that calculates the 2D transform matrix - private static Matrix Calculate2DTransform(Vector3 translation, Vector2 scale, float rotation) - { - float sin = 0.0f; - float cos = 1.0f; - - if (rotation != 0.0f) - { - sin = Math.Sin(rotation); - cos = Math.Cos(rotation); - } - - return .(cos * scale.X, -sin * scale.Y, 0, translation.X, - sin * scale.X, cos * scale.Y, 0, translation.Y, - 0 , 0 , 1, translation.Z, - 0 , 0 , 0, 1); - } public static void DrawQuad(Vector3 position, Vector2 size, float rotation, Texture2D texture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) { @@ -699,6 +748,13 @@ namespace GlitchyEngine.Renderer } } + // Textured quad pivot + + public static void DrawQuadPivotCorner(Vector2 position, Vector2 size, float rotation, Texture2D texture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) + { + DrawQuadPivotCorner(Vector3(position, 0.0f), size, rotation, texture, color, uvTransform); + } + public static void DrawQuadPivotCorner(Vector3 position, Vector2 size, float rotation, Texture2D texture, ColorRGBA color = .White, Vector4 uvTransform = .(0, 0, 1, 1)) { DrawQuad(position + Vector3(size.X / 2, size.Y / -2, 0), size, rotation, texture, color, uvTransform); diff --git a/GlitchyEngine/src/Renderer/SubTexture.bf b/GlitchyEngine/src/Renderer/SubTexture.bf new file mode 100644 index 0000000..4f5029f --- /dev/null +++ b/GlitchyEngine/src/Renderer/SubTexture.bf @@ -0,0 +1,41 @@ +using GlitchyEngine.Core; +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + class SubTexture2D : RefCounter + { + protected Texture2D _texture ~ _.ReleaseRef(); + protected Vector4 _texCoords; + + public Texture2D Texture => _texture; + public Vector4 TexCoords => _texCoords; + + public this(Texture2D texture) : this(_texture, .(0, 0, 1, 1)) { } + + public this(Texture2D texture, Int2 topLeft, Int2 size) : + this(texture, + { + Vector2 texSize = Vector2(texture.Width, texture.Height); + Vector4 texCoords = Vector4((Vector2)topLeft, (Vector2)size) / texSize.XYXY; + texCoords + }) { } + + public this(Texture2D texture, Vector2 topLeft, Vector2 size) : this(texture, Vector4(topLeft, size)) { } + + public this(Texture2D texture, Vector4 texCoords) + { + _texture = texture..AddRef(); + _texCoords = texCoords; + } + + public static SubTexture2D CreateFromGrid(Texture2D texture, Vector2 coords, Vector2 gridSize, Vector2 spriteSize = .One) + { + Vector2 textureSize = .(texture.Width, texture.Height); + + Vector4 uv = .(coords * gridSize, gridSize * spriteSize) / textureSize.XYXY; + + return new SubTexture2D(texture, uv); + } + } +} \ No newline at end of file diff --git a/Sandbox/content/Rpg/textures/spritesheet.png b/Sandbox/content/Rpg/textures/spritesheet.png new file mode 100644 index 0000000..35a8cd9 Binary files /dev/null and b/Sandbox/content/Rpg/textures/spritesheet.png differ diff --git a/Sandbox/content/Rpg/textures/spritesheet_license.txt b/Sandbox/content/Rpg/textures/spritesheet_license.txt new file mode 100644 index 0000000..f354c24 --- /dev/null +++ b/Sandbox/content/Rpg/textures/spritesheet_license.txt @@ -0,0 +1,14 @@ + +############################################################################### + + RPG pack: base by Kenney Vleugels (www.kenney.nl) + + ------------------------------ + + License (CC0) + http://creativecommons.org/publicdomain/zero/1.0/ + + You may use these graphics in personal and commercial projects. + Credit (Kenney or www.kenney.nl) would be nice but is not mandatory. + +############################################################################### \ No newline at end of file diff --git a/Sandbox/src/ExampleLayer2D.bf b/Sandbox/src/ExampleLayer2D.bf index b168708..4acab12 100644 --- a/Sandbox/src/ExampleLayer2D.bf +++ b/Sandbox/src/ExampleLayer2D.bf @@ -27,8 +27,6 @@ namespace Sandbox OrthographicCameraController cameraController ~ delete _; - // Font fonty ~ _.ReleaseRef(); - ColorRGBA _squareColor0 = ColorRGBA.CornflowerBlue; ColorRGBA _squareColor1 = { ColorRGBA color = ColorRGBA.White - _squareColor0; @@ -37,6 +35,10 @@ namespace Sandbox DepthStencilState _depthStencilState ~ _.ReleaseRef(); + Texture2D _spriteSheet ~ _.ReleaseRef(); + SubTexture2D _treeSprite ~ _.ReleaseRef(); + SubTexture2D _barrelSprite ~ _.ReleaseRef(); + [AllowAppend] public this() : base("Example") { @@ -64,16 +66,6 @@ namespace Sandbox blendDesc.RenderTarget[0] = .(true, .SourceAlpha, .InvertedSourceAlpha, .Add, .SourceAlpha, .InvertedSourceAlpha, .Add, .All); _alphaBlendState = new BlendState(blendDesc); - /*fonty = new Font("C:\\Windows\\Fonts\\arial.ttf", 64, true, 'A', 16); - var japanese = new Font("C:\\Windows\\Fonts\\YuGothM.ttc", 64, true, '\0', 1); - var emojis = new Font("C:\\Windows\\Fonts\\seguiemj.ttf", 64, true, '😂' - 10, 1); - var mathstuff = new Font("C:\\Windows\\Fonts\\cambria.ttc", 64, true, 'α', 1); - var cascadiaCode = new Font("C:\\Windows\\Fonts\\CascadiaCode.ttf", 64, true, 'A', 1); - fonty.Fallback = japanese..ReleaseRefNoDelete(); - japanese.Fallback = emojis..ReleaseRefNoDelete(); - emojis.Fallback = mathstuff..ReleaseRefNoDelete(); - mathstuff.Fallback = cascadiaCode..ReleaseRefNoDelete();*/ - _textureViewer = new TextureViewer(); cameraController = new OrthographicCameraController(_context.SwapChain.AspectRatio); @@ -83,9 +75,14 @@ namespace Sandbox DepthEnabled = false }; _depthStencilState = new DepthStencilState(dssDesc); - } - String text = new .() ~ delete _; + + _spriteSheet = new Texture2D("content/Rpg/textures/spritesheet.png"); + _spriteSheet.SamplerState = SamplerStateManager.PointClamp; + + _treeSprite = SubTexture2D.CreateFromGrid(_spriteSheet, Vector2(5, 10), Vector2(128), .(1, 2)); + _barrelSprite = SubTexture2D.CreateFromGrid(_spriteSheet, Vector2(9, 11), Vector2(128)); + } public override void Update(GameTime gameTime) { @@ -102,12 +99,13 @@ namespace Sandbox RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport); Renderer2D.Stats.Reset(); - - Renderer2D.BeginScene(cameraController.Camera, .BackToFront); - + RenderCommand.SetBlendState(_alphaBlendState); RenderCommand.SetDepthStencilState(_depthStencilState); +#if FALSE + Renderer2D.BeginScene(cameraController.Camera, .BackToFront); + float rotation = (float)gameTime.TotalTime.TotalSeconds; Renderer2D.DrawQuad(Vector3(0, 0, 1), Vector2(20), 0, _checkerTexture, .White, .(0, 0, 10, 10)); @@ -140,6 +138,14 @@ namespace Sandbox //FontRenderer.DrawText(prepared, 0, 0); //prepared.ReleaseRef(); + Renderer2D.EndScene(); +#endif + + Renderer2D.BeginScene(cameraController.Camera, .BackToFront); + + Renderer2D.DrawQuad(Vector3(0, 0, 1), Vector2(1, 2), 0, _treeSprite); + Renderer2D.DrawQuad(Vector3(1, 0, 1), Vector2(1, 1), 0, _barrelSprite); + Renderer2D.EndScene(); }