Mercurial > games > semicongine
diff tests/test_text.nim @ 1327:373a4888f6ac
did: rework font-rendering
author | sam <sam@basx.dev> |
---|---|
date | Sat, 17 Aug 2024 13:54:22 +0700 |
parents | 385dbd68a947 |
children | ad09d41abd1e |
line wrap: on
line diff
--- a/tests/test_text.nim Sat Aug 17 11:34:15 2024 +0700 +++ b/tests/test_text.nim Sat Aug 17 13:54:22 2024 +0700 @@ -9,28 +9,39 @@ import ../semicongine +type + FontDS = object + fontAtlas: Image[Gray] + proc test_01_static_label(time: float32) = + var font = loadFont("Overhaul.ttf", lineHeightPixels = 160) var renderdata = initRenderData() + var pipeline = createPipeline[DefaultFontShader[FontDS]](renderPass = vulkan.swapchain.renderPass) - var pipeline = createPipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) + var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas)) + uploadImages(renderdata, ds) + initDescriptorSet( + renderdata, + pipeline.layout(0), + ds, + ) - var font = loadFont("Overhaul.ttf", lineHeightPixels = 160) var label1 = initTextbox( renderdata, pipeline.layout(0), font, + 0.0005, "Hello semicongine!", - color = vec4(1, 1, 1, 1), - scale = 0.0005, ) var start = getMonoTime() while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: label1.refresh() 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) + render(commandbuffer, pipeline, label1, vec3(), vec4(1, 1, 1, 1)) # cleanup checkVkResult vkDeviceWaitIdle(vulkan.device) @@ -38,40 +49,46 @@ destroyRenderData(renderdata) proc test_02_multiple_animated(time: float32) = - var renderdata = initRenderData() - - var pipeline = createPipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) - var font1 = loadFont("Overhaul.ttf", lineHeightPixels = 40) var font2 = loadFont("Overhaul.ttf", lineHeightPixels = 160) var font3 = loadFont("DejaVuSans.ttf", lineHeightPixels = 160) + var renderdata = initRenderData() + + var pipeline = createPipeline[DefaultFontShader[FontDS]](renderPass = vulkan.swapchain.renderPass) + + var ds1 = asDescriptorSetData(FontDS(fontAtlas: font1.fontAtlas)) + uploadImages(renderdata, ds1) + initDescriptorSet(renderdata, pipeline.layout(0), ds1) + + var ds2 = asDescriptorSetData(FontDS(fontAtlas: font2.fontAtlas)) + uploadImages(renderdata, ds2) + initDescriptorSet(renderdata, pipeline.layout(0), ds2) + + var ds3 = asDescriptorSetData(FontDS(fontAtlas: font3.fontAtlas)) + uploadImages(renderdata, ds3) + initDescriptorSet(renderdata, pipeline.layout(0), ds3) + var labels = [ initTextbox( renderdata, pipeline.layout(0), font1, + 0.004, " 0", - color = vec4(0, 1, 1, 1), - scale = 0.004, - position = vec3(-0.3, 0.5) ), initTextbox( renderdata, pipeline.layout(0), font2, + 0.001, " 1", - color = vec4(1, 0, 1, 1), - scale = 0.001, - position = vec3(0, 0) ), initTextbox( renderdata, pipeline.layout(0), font3, + 0.001, " 2", - color = vec4(1, 1, 0, 1), - scale = 0.001, - position = vec3(0.3, -0.5) ) ] @@ -80,19 +97,36 @@ while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time for i in 0 ..< labels.len: - var c = labels[i].color - c[i] = progress - labels[i].color = c - labels[i].scale = labels[i].scale * (1.0 + (i + 1).float * 0.001) - labels[i].position = labels[i].position + vec3(0.001 * (i.float - 1'f)) labels[i].text = $(p + i) labels[i].refresh() inc p withNextFrame(framebuffer, commandbuffer): withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): withPipeline(commandbuffer, pipeline): - for label in labels.litems: - render(commandbuffer, pipeline, label) + bindDescriptorSet(commandbuffer, ds1, 0, pipeline) + render( + commandbuffer, + pipeline, + labels[0], + position=vec3(0 / labels.len, 0.1 + progress * 0.5), + color=vec4(1, 1, 1, 1), + ) + bindDescriptorSet(commandbuffer, ds2, 0, pipeline) + render( + commandbuffer, + pipeline, + labels[1], + position=vec3(1 / labels.len, 0.1 + progress * 0.5), + color=vec4(1, 1, 1, 1), + ) + bindDescriptorSet(commandbuffer, ds3, 0, pipeline) + render( + commandbuffer, + pipeline, + labels[2], + position=vec3(2 / labels.len, 0.1 + progress * 0.5), + color=vec4(1, 1, 1, 1), + ) # cleanup checkVkResult vkDeviceWaitIdle(vulkan.device) @@ -100,11 +134,19 @@ destroyRenderData(renderdata) proc test_03_layouting(time: float32) = + var font = loadFont("DejaVuSans.ttf", lineHeightPixels = 40) var renderdata = initRenderData() - var pipeline = createPipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) + var pipeline = createPipeline[DefaultFontShader[FontDS]](renderPass = vulkan.swapchain.renderPass) - var font = loadFont("DejaVuSans.ttf", lineHeightPixels = 40) + var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas)) + uploadImages(renderdata, ds) + initDescriptorSet( + renderdata, + pipeline.layout(0), + ds, + ) + var labels: seq[Textbox] for horizontal in HorizontalAlignment: @@ -112,10 +154,8 @@ renderdata, pipeline.layout(0), font, + 0.001, $horizontal & " aligned", - color = vec4(1, 1, 1, 1), - scale = 0.001, - position = vec3(0, 0.9 - (horizontal.float * 0.15)), horizontalAlignment = horizontal, ) for vertical in VerticalAlignment: @@ -123,37 +163,33 @@ renderdata, pipeline.layout(0), font, + 0.001, $vertical & " aligned", - color = vec4(1, 1, 1, 1), - scale = 0.001, - position = vec3(-0.35 + (vertical.float * 0.35), 0.3), verticalAlignment = vertical, ) labels.add initTextbox( renderdata, pipeline.layout(0), font, + 0.001, """Paragraph This is a somewhat longer paragraph with a few newlines and a maximum width of 0.2. It should display with some space above and have a pleasing appearance overall! :)""", maxWidth = 0.6, - color = vec4(1, 1, 1, 1), - scale = 0.001, - position = vec3(-0.9, 0.1), verticalAlignment = Top, horizontalAlignment = Left, ) - var start = getMonoTime() while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: let progress = ((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): - for label in labels: - render(commandbuffer, pipeline, label) + for i in 0 ..< labels.len: + render(commandbuffer, pipeline, labels[i], vec3(0.5 - i.float32 * 0.1, 0.5 - i.float32 * 0.1), vec4(1, 1, 1, 1)) # cleanup checkVkResult vkDeviceWaitIdle(vulkan.device) @@ -161,33 +197,45 @@ destroyRenderData(renderdata) proc test_04_lots_of_texts(time: float32) = + var font = loadFont("DejaVuSans.ttf", lineHeightPixels = 160) var renderdata = initRenderData() - var pipeline = createPipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) + var pipeline = createPipeline[DefaultFontShader[FontDS]](renderPass = vulkan.swapchain.renderPass) - var font = loadFont("DejaVuSans.ttf", lineHeightPixels = 160) + var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas)) + uploadImages(renderdata, ds) + initDescriptorSet( + renderdata, + pipeline.layout(0), + ds, + ) + var labels: seq[Textbox] + var positions = newSeq[Vec3f](100) + var colors = newSeq[Vec4f](100) + var scales = newSeq[float32](100) for i in 0 ..< 100: + positions[i] = vec3(rand(-0.5 .. 0.5), rand(-0.5 .. 0.5), rand(-0.1 .. 0.1)) + colors[i] = vec4(rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0)) + scales[i] = rand(0.5'f32 .. 1.5'f32) labels.add initTextbox( renderdata, pipeline.layout(0), font, + 0.001, $i, - color = vec4(rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0)), - scale = rand(0.0002 .. 0.002), - position = vec3(rand(-0.5 .. 0.5), rand(-0.5 .. 0.5), rand(-0.1 .. 0.1)) ) - labels.sort(proc(x, y: Textbox): int = cmp(x.position.z, y.position.z), Ascending) var start = getMonoTime() while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: for l in labels.mitems: l.refresh() 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): - for l in labels: - render(commandbuffer, pipeline, l) + for i in 0 ..< labels.len: + render(commandbuffer, pipeline, labels[i], positions[i], colors[i], scales[i]) # cleanup checkVkResult vkDeviceWaitIdle(vulkan.device)