changeset 1374:92c089136a05

did: start with new glyph-renderer
author sam <sam@basx.dev>
date Fri, 06 Dec 2024 22:48:25 +0700
parents 19469f21f34e
children ca3299ea1bdf
files semicongine/text.nim tests/test_text.nim
diffstat 2 files changed, 78 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/semicongine/text.nim	Fri Dec 06 22:20:39 2024 +0700
+++ b/semicongine/text.nim	Fri Dec 06 22:48:25 2024 +0700
@@ -69,6 +69,45 @@
     color = vec4(textbox.color.rgb, textbox.color.a * v);
 }"""
 
+  GlyphDescriptors[N: static int] = object
+    fontAtlas: Image[Gray]
+    uvs1: array[N, Vec2f]
+    uvs2: array[N, Vec2f]
+    vertexPos1: array[N, Vec2f]
+    vertexPos2: array[N, Vec2f]
+
+  GlyphShader*[N: static int] = object
+    position {.InstanceAttribute.}: Vec3f
+    color {.InstanceAttribute.}: Vec4f
+    scale {.InstanceAttribute.}: float32
+    glyphIndex {.InstanceAttribute.}: uint16
+
+    fragmentUv {.Pass.}: Vec2f
+    fragmentColor {.PassFlat.}: Vec4f
+    color {.ShaderOutput.}: Vec4f
+    glyphData {.DescriptorSet: 0.}: GlyphDescriptors[N]
+    vertexCode* =
+      """void main() {
+  vec2 uv1 = uvs1[glyphIndex];
+  vec2 uv2 = uvs2[glyphIndex];
+  vec2 p1 = vertexPos1[glyphIndex];
+  vec2 p2 = vertexPos2[glyphIndex];
+  uv1[gl_VertexIndex % ]
+
+  gl_Position = vec4(position * vec3(textbox.scale, 1) + textbox.position, 1.0);
+  fragmentUv = uv;
+  fragmentColor = color;
+}  """
+    fragmentCode* =
+      """void main() {
+    float v = texture(fontAtlas, fragmentUv).r;
+    // CARFULL: This can lead to rough edges at times
+    if(v == 0) {
+      discard;
+    }
+    color = vec4(fragmentColor.rgb, fragmentColor.a * v);
+}"""
+
 proc `=copy`(dest: var FontObj, source: FontObj) {.error.}
 
 include ./text/font
--- a/tests/test_text.nim	Fri Dec 06 22:20:39 2024 +0700
+++ b/tests/test_text.nim	Fri Dec 06 22:48:25 2024 +0700
@@ -12,6 +12,36 @@
 type FontDS = object
   fontAtlas: Image[Gray]
 
+proc test_01_static_label_new(time: float32) =
+  var font = loadFont("Overhaul.ttf", lineHeightPixels = 160)
+  var renderdata = initRenderData()
+  var pipeline =
+    createPipeline[GlyphShader[200]](renderPass = vulkan.swapchain.renderPass)
+
+  var ds = asDescriptorSetData(GlyphDescriptors[200](fontAtlas: font.fontAtlas.copy()))
+  uploadImages(renderdata, ds)
+  initDescriptorSet(renderdata, pipeline.layout(0), ds)
+
+  var start = getMonoTime()
+  while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
+    withNextFrame(framebuffer, commandbuffer):
+      bindDescriptorSet(commandbuffer, ds, 0, pipeline)
+      withRenderPass(
+        vulkan.swapchain.renderPass,
+        framebuffer,
+        commandbuffer,
+        vulkan.swapchain.width,
+        vulkan.swapchain.height,
+        vec4(0, 0, 0, 0),
+      ):
+        withPipeline(commandbuffer, pipeline):
+          render(commandbuffer, pipeline, label1, vec3(), vec4(1, 1, 1, 1))
+
+        # cleanup
+  checkVkResult vkDeviceWaitIdle(vulkan.device)
+  destroyPipeline(pipeline)
+  destroyRenderData(renderdata)
+
 proc test_01_static_label(time: float32) =
   var font = loadFont("Overhaul.ttf", lineHeightPixels = 160)
   var renderdata = initRenderData()
@@ -39,7 +69,14 @@
         vec4(0, 0, 0, 0),
       ):
         withPipeline(commandbuffer, pipeline):
-          render(commandbuffer, pipeline, label1, vec3(), vec4(1, 1, 1, 1))
+          proc render(
+            commandBuffer = commandbuffer,
+            pipeline = pipeline,
+            mesh: TMesh,
+            instances: TInstance,
+            fixedVertexCount = -1,
+            fixedInstanceCount = -1,
+          )
 
         # cleanup
   checkVkResult vkDeviceWaitIdle(vulkan.device)
@@ -250,6 +287,7 @@
     setupSwapchain(renderpass = renderpass)
 
     # tests a simple triangle with minimalistic shader and vertex format
+    test_01_static_label_new(time)
     test_01_static_label(time)
     test_02_multiple_animated(time)
     test_03_layouting(time)