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)