From 7eb24778703004d51e0309a020ef50327951c47a Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 23 Jan 2024 12:43:34 -0800 Subject: [PATCH] starting on sprite batch example --- .../InstancedSpriteBatch.vert.refresh | Bin 0 -> 5344 bytes .../Shaders/Source/InstancedSpriteBatch.vert | 45 ++++++ MoonWorksGraphicsTests.sln | 6 + SpriteBatch/SpriteBatch.csproj | 17 ++ SpriteBatch/SpriteBatchGame.cs | 152 ++++++++++++++++++ StoreLoad/StoreLoad.csproj | 1 - 6 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 MoonWorks.Test.Common/Content/Shaders/Compiled/InstancedSpriteBatch.vert.refresh create mode 100644 MoonWorks.Test.Common/Content/Shaders/Source/InstancedSpriteBatch.vert create mode 100644 SpriteBatch/SpriteBatch.csproj create mode 100644 SpriteBatch/SpriteBatchGame.cs diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/InstancedSpriteBatch.vert.refresh b/MoonWorks.Test.Common/Content/Shaders/Compiled/InstancedSpriteBatch.vert.refresh new file mode 100644 index 0000000000000000000000000000000000000000..6e5a7848d76c95f215a354c8afb7b31bd7127c2a GIT binary patch literal 5344 zcmbW5+jkU25XJ{`0Rs^gxp>0?L^lv(E-RvlA^}4rn2^hgBCN}15(hRradsDj9*@5J zq|g2}{#Cwsj^A&lYqxiZJUE<6ch&b*b#--3Gs*I2D>wH1c`yhD_MYAs1bc!5!D#S( zkUuX5du0h^8_veLg_VVgR(pM-{N5yt=YxTa2C z*^(rZ0sY&n@h=4#3`T;vh3eem;@raZYJGdV+G;;(MAb&zjH>H#8r9qJV+9xt_Itdz zS#NaKeZr6!ejex}T4SYNYp^~#x%Kpc;Dq#gh7DyoFDLCQa6WGY7K} z!@<6cPrWmH+-$GJKe8oxEwPw7L zq+3@TN&OM_VIkOgDsl7!BROItm!&j$$k|XW;w?hZLk&3dq|;uFc4m_#UC(e5UaREm z(F@8c-~4=YoeGf0R_>SEXOl*fVjs+U#;K}BevX_S`$nhV(8&v(GeGCLp$OEQ=RiJm zZSb)%8jqORsGHfCW23+3gb)wj4Oy&4Lz&*I*=gxK#4yf2=`Uoq+>dpAKXm-ANX!qL z`LQ;!Y~R%UR6#!}orgNqG+G_dIRo^3AA{LD$-d4?z^T7qN8VL*_J3HbvhGP~=**95 zHmos}9FsqJq7(nPe(u+Z4L#J)=bVlmK5N4#7PzjY>@2Wfa{8#V9g)s$6H0i_IsH(s zX8zQ6kA#@ujE5yW#(!CJIEEhs41WED_21CU_Q3kYqqpFb@03PjvVZu~8o{u`N2m8J zKKWjhu)o)Zf2I+CayX&coJLy@3?c3fjjRDqTy)-7Y}Da%jiJQWLBA>CIU$@Lp~eXD zzR*Yx*olWu?^xZJ+#Ei2A>OKl`1s$~$lBzJ{;kvPoX~5|W_5lbopWd3b&YVb;lHkN zj|4mUpwpY!z&G5SJiyU6oz3!#r4t{V{ODbB#J{PLSmX=kFjr-;4k+30_8^Lx$1u!Doq8?Q@Pli0+7`>`rWy}&HbP;=g! zgW4H;J1L>|&r3oHKGYPu`JC3=_jyY?KGXmVAL@?XeBRcaIHtd&Ih)N4uOZONkKro=eQ&TcVRq~nL({MIzbZ&hM`70t1m-iyaRChuo3ONN#I= z-kYzSO+(lAwX^YV81JsL?bT>C|3-8C;e&Igzbh{H#ytt^!y)JU8mp3d345hB=@%VLR!{(@L+@+*DQvBBw|uW)E#u*RXFmmJpWCvsm$XxFhbv3- z%a!VEnzUNg`Q~<~-7S2!lU{DB+3NK>vx|$%*CrK!qsbWEU3r8lpWuq&!P7om4zrv* zc*cjP!)%`(Ty}8h>0=OUrDErDO}zY2ciHM_y8Ppsw`lNvmY--H*0}wzRulQQl?)cHL%uJUrjpJ$IRf_Hx@j z>;JneGV}fhu*(VbB3l-Az!N*gTzqbq^`yx1&!Nluad%da+kYD5o&8Nh8EJ}+^%!z)2^>X$W zDHWfY+1zDhRV`4=>{wRD0?W*fwN@$MYZZs&H)VeoRvaql-6hV$uZpWyz6BLob#W}; qL;)-z<>6_&krl@N93--*{Ri3mzbWT?2IrDS?M~WsmF}jgv;P-7c52-K literal 0 HcmV?d00001 diff --git a/MoonWorks.Test.Common/Content/Shaders/Source/InstancedSpriteBatch.vert b/MoonWorks.Test.Common/Content/Shaders/Source/InstancedSpriteBatch.vert new file mode 100644 index 0000000..43031a4 --- /dev/null +++ b/MoonWorks.Test.Common/Content/Shaders/Source/InstancedSpriteBatch.vert @@ -0,0 +1,45 @@ +#version 450 + +layout (location = 0) in vec3 Position; +layout (location = 1) in vec3 Translation; +layout (location = 2) in float Rotation; +layout (location = 3) in vec2 Scale; +layout (location = 4) in vec4 Color; +layout (location = 5) in vec2[4] UV; + +layout (location = 0) out vec2 outTexCoord; +layout (location = 1) out vec4 outVertexColor; + +layout (binding = 0, set = 2) uniform UniformBlock +{ + mat4x4 View; + mat4x4 Projection; +}; + +void main() +{ + mat4 Scale = mat4( + Scale.x, 0, 0, 0, + 0, Scale.y, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ); + float c = cos(Rotation); + float s = sin(Rotation); + mat4 Rotation = mat4( + c, -s, 0, 0, + s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ); + mat4 Translation = mat4( + 1, 0, 0, Position.x, + 0, 1, 0, Position.y, + 0, 0, 1, Position.z, + 0, 0, 0, 1 + ); + mat4 Model = Scale * Rotation * Translation; + gl_Position = Model * View * Projection * vec4(Position, 1); + outTexCoord = UV[gl_VertexIndex % 4]; + outVertexColor = Color; +} diff --git a/MoonWorksGraphicsTests.sln b/MoonWorksGraphicsTests.sln index 2773e38..d34d756 100644 --- a/MoonWorksGraphicsTests.sln +++ b/MoonWorksGraphicsTests.sln @@ -61,6 +61,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowResizing", "WindowRes EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StoreLoad", "StoreLoad\StoreLoad.csproj", "{CD31F1B5-C76A-428A-A812-8DFD6CAB20A9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpriteBatch", "SpriteBatch\SpriteBatch.csproj", "{40E25B99-1196-4695-99A6-C0A8EF385539}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -183,6 +185,10 @@ Global {CD31F1B5-C76A-428A-A812-8DFD6CAB20A9}.Debug|x64.Build.0 = Debug|x64 {CD31F1B5-C76A-428A-A812-8DFD6CAB20A9}.Release|x64.ActiveCfg = Release|x64 {CD31F1B5-C76A-428A-A812-8DFD6CAB20A9}.Release|x64.Build.0 = Release|x64 + {40E25B99-1196-4695-99A6-C0A8EF385539}.Debug|x64.ActiveCfg = Debug|Any CPU + {40E25B99-1196-4695-99A6-C0A8EF385539}.Debug|x64.Build.0 = Debug|Any CPU + {40E25B99-1196-4695-99A6-C0A8EF385539}.Release|x64.ActiveCfg = Release|Any CPU + {40E25B99-1196-4695-99A6-C0A8EF385539}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SpriteBatch/SpriteBatch.csproj b/SpriteBatch/SpriteBatch.csproj new file mode 100644 index 0000000..af5328d --- /dev/null +++ b/SpriteBatch/SpriteBatch.csproj @@ -0,0 +1,17 @@ + + + + + + + + + Exe + net8.0 + enable + true + + + + + diff --git a/SpriteBatch/SpriteBatchGame.cs b/SpriteBatch/SpriteBatchGame.cs new file mode 100644 index 0000000..e445f25 --- /dev/null +++ b/SpriteBatch/SpriteBatchGame.cs @@ -0,0 +1,152 @@ +using System; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; + +namespace MoonWorks.Test +{ + class SpriteBatchGame : Game + { + GraphicsPipeline spriteBatchPipeline; + Graphics.Buffer quadVertexBuffer; + Graphics.Buffer quadIndexBuffer; + SpriteBatch SpriteBatch; + + public unsafe SpriteBatchGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + ShaderModule vertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("InstancedSpriteBatch.vert")); + ShaderModule fragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("InstancedSpriteBatch.frag")); + + var vertexBufferDescription = VertexBindingAndAttributes.Create(0); + var instanceBufferDescription = VertexBindingAndAttributes.Create(1, VertexInputRate.Instance); + + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + MainWindow.SwapchainFormat, + vertShaderModule, + fragShaderModule + ); + + pipelineCreateInfo.VertexInputState = new VertexInputState([ + vertexBufferDescription, + instanceBufferDescription + ]); + + spriteBatchPipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + quadVertexBuffer = Graphics.Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 4); + quadIndexBuffer = Graphics.Buffer.Create(GraphicsDevice, BufferUsageFlags.Index, 6); + + var vertices = stackalloc PositionVertex[4]; + vertices[0].Position = new Math.Float.Vector3(0, 0, 0); + vertices[1].Position = new Math.Float.Vector3(1, 0, 0); + vertices[2].Position = new Math.Float.Vector3(0, 1, 0); + vertices[3].Position = new Math.Float.Vector3(1, 1, 0); + + var indices = stackalloc ushort[6] + { + 0, 1, 2, + 2, 1, 3 + }; + + var cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData(quadVertexBuffer, new Span(vertices, 4)); + cmdbuf.SetBufferData(quadIndexBuffer, new Span(indices, 6)); + GraphicsDevice.Submit(cmdbuf); + + SpriteBatch = new SpriteBatch(GraphicsDevice); + } + + protected override void Update(TimeSpan delta) + { + + } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? swapchain = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (swapchain != null) + { + for (var i = 0; i < 1024; i += 1) + { + SpriteBatch.Add() + } + + SpriteBatch.Upload(cmdbuf); + + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(swapchain, Color.Black)); + cmdbuf.BindGraphicsPipeline(spriteBatchPipeline); + cmdbuf.BindVertexBuffers( + new BufferBinding(quadVertexBuffer, 0), + new BufferBinding(SpriteBatch.) + ) + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + SpriteBatchGame game = new SpriteBatchGame(); + game.Run(); + } + } + + public struct SpriteInstanceData : IVertexType + { + public Vector3 Translation; + public float Rotation; + public Vector2 Scale; + public Color Color; + public Vector2 UV0; + public Vector2 UV1; + public Vector2 UV2; + public Vector2 UV3; + + public static VertexElementFormat[] Formats => + [ + VertexElementFormat.Vector3, + VertexElementFormat.Float, + VertexElementFormat.Vector2, + VertexElementFormat.Color, + VertexElementFormat.Vector2, + VertexElementFormat.Vector2, + VertexElementFormat.Vector2, + VertexElementFormat.Vector2 + ]; + } + + class SpriteBatch + { + GraphicsDevice GraphicsDevice; + public Graphics.Buffer BatchBuffer; + SpriteInstanceData[] InstanceDatas; + int Index; + + public SpriteBatch(GraphicsDevice graphicsDevice) + { + GraphicsDevice = graphicsDevice; + BatchBuffer = Graphics.Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 1024); + InstanceDatas = new SpriteInstanceData[1024]; + Index = 0; + } + + public void Add(Vector3 position, float rotation, Vector2 size, Color color) + { + InstanceDatas[Index].Translation = position; + InstanceDatas[Index].Rotation = rotation; + InstanceDatas[Index].Scale = size; + InstanceDatas[Index].Color = color; + InstanceDatas[Index].UV0 = new Vector2(0, 0); + InstanceDatas[Index].UV1 = new Vector2(0, 1); + InstanceDatas[Index].UV2 = new Vector2(1, 0); + InstanceDatas[Index].UV3 = new Vector2(1, 1); + Index += 1; + } + + public void Upload(CommandBuffer commandBuffer) + { + commandBuffer.SetBufferData(BatchBuffer, InstanceDatas, 0, 0, (uint) Index); + Index = 0; + } + } +} diff --git a/StoreLoad/StoreLoad.csproj b/StoreLoad/StoreLoad.csproj index fb73c0c..5c541ff 100644 --- a/StoreLoad/StoreLoad.csproj +++ b/StoreLoad/StoreLoad.csproj @@ -9,7 +9,6 @@ Exe net8.0 enable - x64