From 6cd31b4938db6f54815edf86e9fedbb3075c90ba Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 13 Dec 2023 17:19:02 -0800 Subject: [PATCH] add some defaults to make text render setup easier --- MoonWorks.csproj | 6 +++ src/Graphics/Font/Structs.cs | 9 +++- src/Graphics/Font/TextBatch.cs | 18 +++++++ src/Graphics/GraphicsDevice.cs | 45 +++++++++++++++++- .../Binary/text_msdf.frag.refresh | Bin 0 -> 2697 bytes .../Binary/text_transform.vert.refresh | Bin 0 -> 1529 bytes .../StockShaders/Source/text_msdf.frag | 34 +++++++++++++ .../StockShaders/Source/text_transform.vert | 20 ++++++++ src/Video/VideoPlayer.cs | 4 -- 9 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 src/Graphics/StockShaders/Binary/text_msdf.frag.refresh create mode 100644 src/Graphics/StockShaders/Binary/text_transform.vert.refresh create mode 100644 src/Graphics/StockShaders/Source/text_msdf.frag create mode 100644 src/Graphics/StockShaders/Source/text_transform.vert diff --git a/MoonWorks.csproj b/MoonWorks.csproj index baa210d..2e0eb18 100644 --- a/MoonWorks.csproj +++ b/MoonWorks.csproj @@ -32,5 +32,11 @@ MoonWorks.Graphics.StockShaders.VideoYUV2RGBA.frag.refresh + + MoonWorks.Graphics.StockShaders.TextTransform.vert.refresh + + + MoonWorks.Graphics.StockShaders.TextMSDF.frag.refresh + diff --git a/src/Graphics/Font/Structs.cs b/src/Graphics/Font/Structs.cs index b5b1e5a..f5f0eec 100644 --- a/src/Graphics/Font/Structs.cs +++ b/src/Graphics/Font/Structs.cs @@ -4,10 +4,17 @@ using MoonWorks.Math.Float; namespace MoonWorks.Graphics.Font { [StructLayout(LayoutKind.Sequential)] - public struct Vertex + public struct Vertex : IVertexType { public Vector3 Position; public Vector2 TexCoord; public Color Color; + + public static VertexElementFormat[] Formats { get; } = new VertexElementFormat[] + { + VertexElementFormat.Vector3, + VertexElementFormat.Vector2, + VertexElementFormat.Color + }; } } diff --git a/src/Graphics/Font/TextBatch.cs b/src/Graphics/Font/TextBatch.cs index a3b5e28..cccbd59 100644 --- a/src/Graphics/Font/TextBatch.cs +++ b/src/Graphics/Font/TextBatch.cs @@ -100,6 +100,24 @@ namespace MoonWorks.Graphics.Font PrimitiveCount = vertexCount / 2; // FIXME: is this jank? } + // Call this AFTER binding your text pipeline! + public void Render(CommandBuffer commandBuffer, Math.Float.Matrix4x4 transformMatrix) + { + commandBuffer.BindFragmentSamplers(new TextureSamplerBinding( + CurrentFont.Texture, + GraphicsDevice.LinearSampler + )); + commandBuffer.BindVertexBuffers(VertexBuffer); + commandBuffer.BindIndexBuffer(IndexBuffer, IndexElementSize.ThirtyTwo); + commandBuffer.DrawIndexedPrimitives( + 0, + 0, + PrimitiveCount, + commandBuffer.PushVertexShaderUniforms(transformMatrix), + commandBuffer.PushFragmentShaderUniforms(CurrentFont.DistanceRange) + ); + } + protected override void Dispose(bool disposing) { if (!IsDisposed) diff --git a/src/Graphics/GraphicsDevice.cs b/src/Graphics/GraphicsDevice.cs index 191dbde..7fc0737 100644 --- a/src/Graphics/GraphicsDevice.cs +++ b/src/Graphics/GraphicsDevice.cs @@ -4,6 +4,7 @@ using System.IO; using System.Runtime.InteropServices; using MoonWorks.Video; using RefreshCS; +using WellspringCS; namespace MoonWorks.Graphics { @@ -21,6 +22,15 @@ namespace MoonWorks.Graphics // Built-in video pipeline internal GraphicsPipeline VideoPipeline { get; } + // Built-in text shader info + public GraphicsShaderInfo TextVertexShaderInfo { get; } + public GraphicsShaderInfo TextFragmentShaderInfo { get; } + public VertexInputState TextVertexInputState { get; } + + // Built-in samplers + public Sampler PointSampler { get; } + public Sampler LinearSampler { get; } + public bool IsDisposed { get; private set; } private readonly HashSet resources = new HashSet(); @@ -41,14 +51,23 @@ namespace MoonWorks.Graphics Conversions.BoolToByte(debugMode) ); - // Check for optional video shaders + // TODO: check for CreateDevice fail + + // Check for replacement stock shaders string basePath = System.AppContext.BaseDirectory; + string videoVertPath = Path.Combine(basePath, "video_fullscreen.vert.refresh"); string videoFragPath = Path.Combine(basePath, "video_yuv2rgba.frag.refresh"); + string textVertPath = Path.Combine(basePath, "text_transform.vert.refresh"); + string textFragPath = Path.Combine(basePath, "text_msdf.frag.refresh"); + ShaderModule videoVertShader; ShaderModule videoFragShader; + ShaderModule textVertShader; + ShaderModule textFragShader; + if (File.Exists(videoVertPath) && File.Exists(videoFragPath)) { videoVertShader = new ShaderModule(this, videoVertPath); @@ -66,6 +85,23 @@ namespace MoonWorks.Graphics videoFragShader = new ShaderModule(this, fragStream); } + if (File.Exists(textVertPath) && File.Exists(textFragPath)) + { + textVertShader = new ShaderModule(this, textVertPath); + textFragShader = new ShaderModule(this, textFragPath); + } + else + { + // use defaults + var assembly = typeof(GraphicsDevice).Assembly; + + using var vertStream = assembly.GetManifestResourceStream("MoonWorks.Graphics.StockShaders.TextTransform.vert.refresh"); + using var fragStream = assembly.GetManifestResourceStream("MoonWorks.Graphics.StockShaders.TextMSDF.frag.refresh"); + + textVertShader = new ShaderModule(this, vertStream); + textFragShader = new ShaderModule(this, fragStream); + } + VideoPipeline = new GraphicsPipeline( this, new GraphicsPipelineCreateInfo @@ -94,6 +130,13 @@ namespace MoonWorks.Graphics } ); + TextVertexShaderInfo = GraphicsShaderInfo.Create(textVertShader, "main", 0); + TextFragmentShaderInfo = GraphicsShaderInfo.Create(textFragShader, "main", 1); + TextVertexInputState = VertexInputState.CreateSingleBinding(); + + PointSampler = new Sampler(this, SamplerCreateInfo.PointClamp); + LinearSampler = new Sampler(this, SamplerCreateInfo.LinearClamp); + FencePool = new FencePool(this); } diff --git a/src/Graphics/StockShaders/Binary/text_msdf.frag.refresh b/src/Graphics/StockShaders/Binary/text_msdf.frag.refresh new file mode 100644 index 0000000000000000000000000000000000000000..ba50a5aa2a2d33d398d20d8b5b57b6728ccf2cc0 GIT binary patch literal 2697 zcmZ9Ne^ZoI6vr>J3kZmssX3K_SYZ&UAxfl7f-V{bfo8wgWp|;cV3&cV(f+b&n&}1f zih2jVoBpZk^Lh5(dh8j$oO8bC*S+`LyRP5eSnhc?7((xn@%|8c!caICc0%_%8IHh& zpuCD43VpdH+qZwK+l|%TQ zCZ#YKDl65>>S|@>PPM+bS3T%F-Dy^LvR1R&$o8A{PWD67xPd}k)~fFuHi`jdB8t7s zbQ-3|ZnKfqS`%AW=DYu(LYe+Yk^52S81gmB520`7d|x<@JgDzCo2|7c>$TQ)bHdzm zI1hi=$~rlh$M%NTkPmOKa#H17#|(Sjti0bC_Tgq5y%Z+VcMlp{#+1qMjJtgvG@oo_ zKeAo;a(;eU3vRL9-sd1)-x5A@bN#+~IbRANqVLuAYrA=FDXjg^e(;>#A3n!Udt1s5 zI<;2aw$v?!Z;Zl`o{4_0#J_gY?_KiT{fuYZ&)Kd=zxk)=YTq%s*-!lpS|4&WM=8ID-bJ}F z{tiT4F2Vef$e*R>D^a)JDE6x{R{lJ(?zh{cl=m@CZl2gt&l7US(#N4K|qT(7qGMsA9g$b0F{DZ<<>IQyhr?d{0Taz6HS-G0{l6Q+!` z&mwXO^haCiTP@nY*P`uvE!w`A=HeQ^K=*e%)%+6On4j5~b-n^}-rHXy z_cgkC`mE{M%cUAsbh)2m{9|-EYYcO?*4+f2r!#pBykEW}>p469)^j%Bg6(LVn*n3i z*sK2UA}60b>jMwM+^F3K_5c*ZXZLY z{hvfPKG`pzn=>3|a|+!xy$+1kpJHD`FXo=cF6N%WHg^ITt3TzQMRz@^&r9g3k9qo& z?_Bg*$MqQdH~Ww;o`rYAZv?o{6G-2%zwQ2i;@KqoYP7wx7t!6{7#Ig>jc-JLjTqnI zn?Oz&a|t;GCP4$+^}QXrZE~FBJCU<)n;7d{j{L8&?iFln%R6h=DrXPluY+0eN3?H5 zF6GZ*&j5Mz-J4v>pGUW5vfoEH<~RC#hi(F6j4kPsjUkX%GcAkbT@BoI$55}sgI3k=iu~=2v=Mx*@ugEURuFDQ(w`5IOMZdE4UpiPd%ckA++r3`9 z`^q1V$NnV!76yK3qre~8Bp9alO8{?aj%TA`I33LsJTd0)_S7>SeGL76kQ@g|8k{N= zn&J55;)zXd90^@?d}eXDjnaYruA4cN<>*)PMH=(#iatYaH|?I-ak=2RPww;_D`A(mft`q@Zr3iI?s%Xpf;3r<^coQxcXwl=t9gK@X=&GZssxfZRl3^ zx_V$P{4IG4+H10Hou^M?=H1l)lJ=U6)y(5F^0{wU@v?UKV0-e=r>H>=tBH3`d!gmy zJm%eianGvbWp%lScumIIQH*xfrLR4mLPIcWU(n7hVALi?S1|Gyb00o4ZfmD!?k2yZ zy(9zYJTbb1(F@!wGGl%`gI|}&S^A+~Lpz+}zH9QygHw-~?*_*C8``N|0GGt9D^ zW7=le)g0sAg2!9qEIst42tDr0I1isZ+Wk~ray1!u!=XQBJ&^Gh=