Mercurial > games > semicongine
comparison tests/test_text.nim @ 1404:80cfa19d1e2c
did: finally get text/glyph layouting correct again, 2/4 test adapted to new glyph API
| author | sam <sam@basx.dev> |
|---|---|
| date | Thu, 19 Dec 2024 23:32:45 +0700 |
| parents | 02d302c868d5 |
| children | 46bac138ad6c |
comparison
equal
deleted
inserted
replaced
| 1403:02d302c868d5 | 1404:80cfa19d1e2c |
|---|---|
| 12 import ../semicongine | 12 import ../semicongine |
| 13 | 13 |
| 14 type FontDS = object | 14 type FontDS = object |
| 15 fontAtlas: Image[Gray] | 15 fontAtlas: Image[Gray] |
| 16 | 16 |
| 17 type EMPTY = object | 17 const MAX_CODEPOINTS = 200 |
| 18 | 18 const FONTNAME = "Overhaul.ttf" |
| 19 const MAX_GLYPHS = 200 | 19 # const FONTNAME = "DejaVuSans.ttf" |
| 20 proc test_01_static_label_new(time: float32) = | 20 |
| 21 # var font = loadFont[MAX_GLYPHS]("Overhaul.ttf", lineHeightPixels = 200) | 21 proc test_01_static_label(time: float32) = |
| 22 var font = loadFont[MAX_GLYPHS]("DejaVuSans.ttf", lineHeightPixels = 200) | 22 var font = loadFont[MAX_CODEPOINTS](FONTNAME, lineHeightPixels = 200) |
| 23 var renderdata = initRenderData() | 23 var renderdata = initRenderData() |
| 24 var pipeline = | 24 var pipeline = createPipeline[GlyphShader[MAX_CODEPOINTS]]( |
| 25 createPipeline[GlyphShader[MAX_GLYPHS]](renderPass = vulkan.swapchain.renderPass) | 25 renderPass = vulkan.swapchain.renderPass |
| 26 ) | |
| 26 var glyphs = font.initGlyphs(1000, baseScale = 0.1) | 27 var glyphs = font.initGlyphs(1000, baseScale = 0.1) |
| 27 | 28 |
| 28 assignBuffers(renderdata, glyphs) | 29 assignBuffers(renderdata, glyphs) |
| 29 assignBuffers(renderdata, font.descriptorSet) | 30 assignBuffers(renderdata, font.descriptorSet) |
| 30 uploadImages(renderdata, font.descriptorSet) | 31 uploadImages(renderdata, font.descriptorSet) |
| 32 | 33 |
| 33 var start = getMonoTime() | 34 var start = getMonoTime() |
| 34 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 35 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
| 35 let t = getMonoTime() | 36 let t = getMonoTime() |
| 36 glyphs.reset() | 37 glyphs.reset() |
| 37 glyphs.add("+", vec3(0.0, 0.0), anchor = vec2(0.5, 0.5), color = vec4(0, 0, 0, 1)) | 38 glyphs.add("Hello semicongine!", vec3(0.5, 0.5), anchor = vec2(0.5, 0.5)) |
| 38 glyphs.add( | |
| 39 "Hello world\nHow are you today?\nWell, I am fine".toRunes(), | |
| 40 vec3(0.5, 0.5), | |
| 41 alignment = Right, | |
| 42 anchor = vec2(1, 0.5), | |
| 43 color = vec4(0, 0, 0, 1), | |
| 44 ) | |
| 45 glyphs.add( | |
| 46 "Hello world\nHow are you today?\nWell, I am fine".toRunes(), | |
| 47 vec3(0.5, 0.5), | |
| 48 alignment = Left, | |
| 49 anchor = vec2(0, 0.5), | |
| 50 color = vec4(0, 0, 0, 1), | |
| 51 ) | |
| 52 glyphs.add("semi-\ncon-\ngine".toRunes(), vec3(0.5, -0.5), color = vec4(0, 0, 0, 1)) | |
| 53 glyphs.add("semi-\ncon-\ngine".toRunes(), vec3(-0.5, 0.5), color = vec4(0, 0, 0, 1)) | |
| 54 # glyphs.add("11111111111111111", vec3(0.5, 0.5), vec2(1, 0)) | |
| 55 # glyphs.add("22222222222222222", vec3(0.5, 0.5)) | |
| 56 # glyphs.add("33333333333333333", vec3(0.5, 0.5), vec2(0, 1)) | |
| 57 glyphs.add("semi-\ncon-\ngineb".toRunes(), vec3(0.1, 0.9), color = vec4(0, 0, 0, 1)) | |
| 58 glyphs.updateAllGPUBuffers(flush = true) | 39 glyphs.updateAllGPUBuffers(flush = true) |
| 59 | 40 |
| 60 withNextFrame(framebuffer, commandbuffer): | 41 withNextFrame(framebuffer, commandbuffer): |
| 61 bindDescriptorSet(commandbuffer, font.descriptorSet, 0, pipeline) | 42 bindDescriptorSet(commandbuffer, font.descriptorSet, 0, pipeline) |
| 62 withRenderPass( | 43 withRenderPass( |
| 63 vulkan.swapchain.renderPass, | 44 vulkan.swapchain.renderPass, |
| 64 framebuffer, | 45 framebuffer, |
| 65 commandbuffer, | 46 commandbuffer, |
| 66 vulkan.swapchain.width, | 47 vulkan.swapchain.width, |
| 67 vulkan.swapchain.height, | 48 vulkan.swapchain.height, |
| 68 vec4(1, 1, 1, 1), | 49 vec4(0, 0, 0, 0), |
| 69 ): | 50 ): |
| 70 withPipeline(commandbuffer, pipeline): | 51 withPipeline(commandbuffer, pipeline): |
| 71 renderGlyphs(commandbuffer, pipeline, glyphs) | 52 renderGlyphs(commandbuffer, pipeline, glyphs) |
| 72 | 53 |
| 73 # cleanup | 54 # cleanup |
| 74 checkVkResult vkDeviceWaitIdle(vulkan.device) | 55 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 75 destroyPipeline(pipeline) | 56 destroyPipeline(pipeline) |
| 76 destroyRenderData(renderdata) | 57 destroyRenderData(renderdata) |
| 77 | 58 |
| 59 proc test_02_multi_counter(time: float32) = | |
| 60 var font1 = loadFont[MAX_CODEPOINTS]("Overhaul.ttf", lineHeightPixels = 40) | |
| 61 var font2 = loadFont[MAX_CODEPOINTS]("Overhaul.ttf", lineHeightPixels = 160) | |
| 62 var font3 = loadFont[MAX_CODEPOINTS]("DejaVuSans.ttf", lineHeightPixels = 160) | |
| 63 var renderdata = initRenderData() | |
| 64 | |
| 65 var pipeline = createPipeline[GlyphShader[MAX_CODEPOINTS]]( | |
| 66 renderPass = vulkan.swapchain.renderPass | |
| 67 ) | |
| 68 | |
| 69 assignBuffers(renderdata, font1.descriptorSet) | |
| 70 assignBuffers(renderdata, font2.descriptorSet) | |
| 71 assignBuffers(renderdata, font3.descriptorSet) | |
| 72 uploadImages(renderdata, font1.descriptorSet) | |
| 73 uploadImages(renderdata, font2.descriptorSet) | |
| 74 uploadImages(renderdata, font3.descriptorSet) | |
| 75 initDescriptorSet(renderdata, pipeline.layout(0), font1.descriptorSet) | |
| 76 initDescriptorSet(renderdata, pipeline.layout(0), font2.descriptorSet) | |
| 77 initDescriptorSet(renderdata, pipeline.layout(0), font3.descriptorSet) | |
| 78 | |
| 79 var glyphs1 = font1.initGlyphs(10, baseScale = 0.1) | |
| 80 var glyphs2 = font2.initGlyphs(10, baseScale = 0.1) | |
| 81 var glyphs3 = font3.initGlyphs(10, baseScale = 0.1) | |
| 82 | |
| 83 assignBuffers(renderdata, glyphs1) | |
| 84 assignBuffers(renderdata, glyphs2) | |
| 85 assignBuffers(renderdata, glyphs3) | |
| 86 | |
| 87 var labels = [" 0", " 1", " 2"] | |
| 88 | |
| 89 var start = getMonoTime() | |
| 90 var p = 0 | |
| 91 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | |
| 92 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time | |
| 93 glyphs1.reset() | |
| 94 glyphs2.reset() | |
| 95 glyphs3.reset() | |
| 96 | |
| 97 glyphs1.add($(p + 0), vec3(0.3, 0.5)) | |
| 98 glyphs2.add($(p + 1), vec3(0.5, 0.5)) | |
| 99 glyphs3.add($(p + 2), vec3(0.7, 0.5)) | |
| 100 | |
| 101 glyphs1.updateAllGPUBuffers(flush = true) | |
| 102 glyphs2.updateAllGPUBuffers(flush = true) | |
| 103 glyphs3.updateAllGPUBuffers(flush = true) | |
| 104 | |
| 105 inc p | |
| 106 withNextFrame(framebuffer, commandbuffer): | |
| 107 withRenderPass( | |
| 108 vulkan.swapchain.renderPass, | |
| 109 framebuffer, | |
| 110 commandbuffer, | |
| 111 vulkan.swapchain.width, | |
| 112 vulkan.swapchain.height, | |
| 113 vec4(0, 0, 0, 0), | |
| 114 ): | |
| 115 withPipeline(commandbuffer, pipeline): | |
| 116 bindDescriptorSet(commandbuffer, font1.descriptorSet, 0, pipeline) | |
| 117 renderGlyphs(commandbuffer, pipeline, glyphs1) | |
| 118 bindDescriptorSet(commandbuffer, font2.descriptorSet, 0, pipeline) | |
| 119 renderGlyphs(commandbuffer, pipeline, glyphs2) | |
| 120 bindDescriptorSet(commandbuffer, font3.descriptorSet, 0, pipeline) | |
| 121 renderGlyphs(commandbuffer, pipeline, glyphs3) | |
| 122 | |
| 123 # cleanup | |
| 124 checkVkResult vkDeviceWaitIdle(vulkan.device) | |
| 125 destroyPipeline(pipeline) | |
| 126 destroyRenderData(renderdata) | |
| 127 | |
| 78 #[ | 128 #[ |
| 79 proc test_01_static_label(time: float32) = | |
| 80 var font = loadFont[MAX_GLYPHS]("Overhaul.ttf", lineHeightPixels = 160) | |
| 81 var renderdata = initRenderData() | |
| 82 var pipeline = | |
| 83 createPipeline[GlyphShader[MAX_GLYPHS]](renderPass = vulkan.swapchain.renderPass) | |
| 84 | |
| 85 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas.copy())) | |
| 86 uploadImages(renderdata, ds) | |
| 87 initDescriptorSet(renderdata, pipeline.layout(0), ds) | |
| 88 | |
| 89 var label1 = | |
| 90 initTextbox(renderdata, pipeline.layout(0), font, 0.0005, "Hello semicongine!") | |
| 91 | |
| 92 var start = getMonoTime() | |
| 93 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | |
| 94 label1.refresh() | |
| 95 withNextFrame(framebuffer, commandbuffer): | |
| 96 bindDescriptorSet(commandbuffer, ds, 0, pipeline) | |
| 97 withRenderPass( | |
| 98 vulkan.swapchain.renderPass, | |
| 99 framebuffer, | |
| 100 commandbuffer, | |
| 101 vulkan.swapchain.width, | |
| 102 vulkan.swapchain.height, | |
| 103 vec4(0, 0, 0, 0), | |
| 104 ): | |
| 105 withPipeline(commandbuffer, pipeline): | |
| 106 render(commandbuffer, pipeline, label1, vec3(), vec4(1, 1, 1, 1)) | |
| 107 # cleanup | |
| 108 checkVkResult vkDeviceWaitIdle(vulkan.device) | |
| 109 destroyPipeline(pipeline) | |
| 110 destroyRenderData(renderdata) | |
| 111 | |
| 112 proc test_02_multiple_animated(time: float32) = | |
| 113 var font1 = loadFont[MAX_GLYPHS]("Overhaul.ttf", lineHeightPixels = 40) | |
| 114 var font2 = loadFont[MAX_GLYPHS]("Overhaul.ttf", lineHeightPixels = 160) | |
| 115 var font3 = loadFont[MAX_GLYPHS]("DejaVuSans.ttf", lineHeightPixels = 160) | |
| 116 var renderdata = initRenderData() | |
| 117 | |
| 118 var pipeline = | |
| 119 createPipeline[GlyphShader[MAX_GLYPHS]](renderPass = vulkan.swapchain.renderPass) | |
| 120 | |
| 121 var ds1 = asDescriptorSetData(FontDS(fontAtlas: font1.fontAtlas.copy())) | |
| 122 uploadImages(renderdata, ds1) | |
| 123 initDescriptorSet(renderdata, pipeline.layout(0), ds1) | |
| 124 | |
| 125 var ds2 = asDescriptorSetData(FontDS(fontAtlas: font2.fontAtlas.copy())) | |
| 126 uploadImages(renderdata, ds2) | |
| 127 initDescriptorSet(renderdata, pipeline.layout(0), ds2) | |
| 128 | |
| 129 var ds3 = asDescriptorSetData(FontDS(fontAtlas: font3.fontAtlas.copy())) | |
| 130 uploadImages(renderdata, ds3) | |
| 131 initDescriptorSet(renderdata, pipeline.layout(0), ds3) | |
| 132 | |
| 133 var labels = [ | |
| 134 initTextbox(renderdata, pipeline.layout(0), font1, 0.004, " 0"), | |
| 135 initTextbox(renderdata, pipeline.layout(0), font2, 0.001, " 1"), | |
| 136 initTextbox(renderdata, pipeline.layout(0), font3, 0.001, " 2"), | |
| 137 ] | |
| 138 | |
| 139 var start = getMonoTime() | |
| 140 var p = 0 | |
| 141 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | |
| 142 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time | |
| 143 for i in 0 ..< labels.len: | |
| 144 labels[i].text = $(p + i) | |
| 145 labels[i].refresh() | |
| 146 inc p | |
| 147 withNextFrame(framebuffer, commandbuffer): | |
| 148 withRenderPass( | |
| 149 vulkan.swapchain.renderPass, | |
| 150 framebuffer, | |
| 151 commandbuffer, | |
| 152 vulkan.swapchain.width, | |
| 153 vulkan.swapchain.height, | |
| 154 vec4(0, 0, 0, 0), | |
| 155 ): | |
| 156 withPipeline(commandbuffer, pipeline): | |
| 157 bindDescriptorSet(commandbuffer, ds1, 0, pipeline) | |
| 158 render( | |
| 159 commandbuffer, | |
| 160 pipeline, | |
| 161 labels[0], | |
| 162 position = vec3(0 / labels.len, 0.1 + progress * 0.5), | |
| 163 color = vec4(1, 1, 1, 1), | |
| 164 ) | |
| 165 bindDescriptorSet(commandbuffer, ds2, 0, pipeline) | |
| 166 render( | |
| 167 commandbuffer, | |
| 168 pipeline, | |
| 169 labels[1], | |
| 170 position = vec3(1 / labels.len, 0.1 + progress * 0.5), | |
| 171 color = vec4(1, 1, 1, 1), | |
| 172 ) | |
| 173 bindDescriptorSet(commandbuffer, ds3, 0, pipeline) | |
| 174 render( | |
| 175 commandbuffer, | |
| 176 pipeline, | |
| 177 labels[2], | |
| 178 position = vec3(2 / labels.len, 0.1 + progress * 0.5), | |
| 179 color = vec4(1, 1, 1, 1), | |
| 180 ) | |
| 181 | |
| 182 # cleanup | |
| 183 checkVkResult vkDeviceWaitIdle(vulkan.device) | |
| 184 destroyPipeline(pipeline) | |
| 185 destroyRenderData(renderdata) | |
| 186 | |
| 187 proc test_03_layouting(time: float32) = | 129 proc test_03_layouting(time: float32) = |
| 188 var font = loadFont[MAX_GLYPHS]("DejaVuSans.ttf", lineHeightPixels = 40) | 130 var font = loadFont[MAX_CODEPOINTS]("DejaVuSans.ttf", lineHeightPixels = 40) |
| 189 var renderdata = initRenderData() | 131 var renderdata = initRenderData() |
| 190 | 132 |
| 191 var pipeline = | 133 var pipeline = createPipeline[GlyphShader[MAX_CODEPOINTS]]( |
| 192 createPipeline[GlyphShader[MAX_GLYPHS]](renderPass = vulkan.swapchain.renderPass) | 134 renderPass = vulkan.swapchain.renderPass |
| 135 ) | |
| 193 | 136 |
| 194 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas.copy())) | 137 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas.copy())) |
| 195 uploadImages(renderdata, ds) | 138 uploadImages(renderdata, ds) |
| 196 initDescriptorSet(renderdata, pipeline.layout(0), ds) | 139 initDescriptorSet(renderdata, pipeline.layout(0), ds) |
| 197 | 140 |
| 256 checkVkResult vkDeviceWaitIdle(vulkan.device) | 199 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 257 destroyPipeline(pipeline) | 200 destroyPipeline(pipeline) |
| 258 destroyRenderData(renderdata) | 201 destroyRenderData(renderdata) |
| 259 | 202 |
| 260 proc test_04_lots_of_texts(time: float32) = | 203 proc test_04_lots_of_texts(time: float32) = |
| 261 var font = loadFont[MAX_GLYPHS]("DejaVuSans.ttf", lineHeightPixels = 160) | 204 var font = loadFont[MAX_CODEPOINTS]("DejaVuSans.ttf", lineHeightPixels = 160) |
| 262 var renderdata = initRenderData() | 205 var renderdata = initRenderData() |
| 263 | 206 |
| 264 var pipeline = | 207 var pipeline = createPipeline[GlyphShader[MAX_CODEPOINTS]]( |
| 265 createPipeline[GlyphShader[MAX_GLYPHS]](renderPass = vulkan.swapchain.renderPass) | 208 renderPass = vulkan.swapchain.renderPass |
| 209 ) | |
| 266 | 210 |
| 267 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas.copy())) | 211 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas.copy())) |
| 268 uploadImages(renderdata, ds) | 212 uploadImages(renderdata, ds) |
| 269 initDescriptorSet(renderdata, pipeline.layout(0), ds) | 213 initDescriptorSet(renderdata, pipeline.layout(0), ds) |
| 270 | 214 |
| 304 destroyPipeline(pipeline) | 248 destroyPipeline(pipeline) |
| 305 destroyRenderData(renderdata) | 249 destroyRenderData(renderdata) |
| 306 ]# | 250 ]# |
| 307 | 251 |
| 308 when isMainModule: | 252 when isMainModule: |
| 309 var time = 1000'f32 | 253 var time = 1'f32 |
| 310 initVulkan() | 254 initVulkan() |
| 311 | 255 |
| 312 for depthBuffer in [true, false]: | 256 for depthBuffer in [true, false]: |
| 313 var renderpass = createDirectPresentationRenderPass(depthBuffer = depthBuffer) | 257 var renderpass = createDirectPresentationRenderPass(depthBuffer = depthBuffer) |
| 314 setupSwapchain(renderpass = renderpass) | 258 setupSwapchain(renderpass = renderpass) |
| 315 | 259 |
| 316 # tests a simple triangle with minimalistic shader and vertex format | 260 # tests a simple triangle with minimalistic shader and vertex format |
| 317 test_01_static_label_new(time) | 261 test_01_static_label(time) |
| 318 # test_01_static_label(time) | 262 test_02_multi_counter(time) |
| 319 # test_02_multiple_animated(time) | |
| 320 # test_03_layouting(time) | 263 # test_03_layouting(time) |
| 321 # test_04_lots_of_texts(time) | 264 # test_04_lots_of_texts(time) |
| 322 | 265 |
| 323 checkVkResult vkDeviceWaitIdle(vulkan.device) | 266 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 324 vkDestroyRenderPass(vulkan.device, renderpass.vk, nil) | 267 vkDestroyRenderPass(vulkan.device, renderpass.vk, nil) |
