Mercurial > games > semicongine
comparison tests/test_text.nim @ 1407:56f927b89716
did: finally got typography right, still improving text-rendering API to cache text parts
author | sam <sam@basx.dev> |
---|---|
date | Sun, 22 Dec 2024 00:31:29 +0700 |
parents | aeb15aa9768c |
children | 17d960ff6a24 |
comparison
equal
deleted
inserted
replaced
1406:aeb15aa9768c | 1407:56f927b89716 |
---|---|
19 var font = loadFont[MAX_CODEPOINTS](FONTNAME, lineHeightPixels = 200) | 19 var font = loadFont[MAX_CODEPOINTS](FONTNAME, lineHeightPixels = 200) |
20 var renderdata = initRenderData() | 20 var renderdata = initRenderData() |
21 var pipeline = createPipeline[GlyphShader[MAX_CODEPOINTS]]( | 21 var pipeline = createPipeline[GlyphShader[MAX_CODEPOINTS]]( |
22 renderPass = vulkan.swapchain.renderPass | 22 renderPass = vulkan.swapchain.renderPass |
23 ) | 23 ) |
24 var glyphs = font.initGlyphs(1000, baseScale = 0.1) | 24 var textbuffer = font.initTextBuffer(1000, baseScale = 0.1) |
25 | 25 |
26 assignBuffers(renderdata, glyphs) | 26 assignBuffers(renderdata, textbuffer) |
27 assignBuffers(renderdata, font.descriptorSet) | 27 assignBuffers(renderdata, font.descriptorSet) |
28 uploadImages(renderdata, font.descriptorSet) | 28 uploadImages(renderdata, font.descriptorSet) |
29 initDescriptorSet(renderdata, pipeline.layout(0), font.descriptorSet) | 29 initDescriptorSet(renderdata, pipeline.layout(0), font.descriptorSet) |
30 | 30 |
31 var start = getMonoTime() | 31 var start = getMonoTime() |
32 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 32 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
33 let t = getMonoTime() | 33 let t = getMonoTime() |
34 glyphs.reset() | 34 textbuffer.reset() |
35 glyphs.add("Hello semicongine!", vec3(0.5, 0.5), anchor = vec2(0.5, 0.5)) | 35 textbuffer.add("Hello semicongine!", vec3(0.5, 0.5), anchor = vec2(0.5, 0.5)) |
36 glyphs.updateAllGPUBuffers(flush = true) | 36 textbuffer.updateAllGPUBuffers(flush = true) |
37 | 37 |
38 withNextFrame(framebuffer, commandbuffer): | 38 withNextFrame(framebuffer, commandbuffer): |
39 bindDescriptorSet(commandbuffer, font.descriptorSet, 0, pipeline) | 39 bindDescriptorSet(commandbuffer, font.descriptorSet, 0, pipeline) |
40 withRenderPass( | 40 withRenderPass( |
41 vulkan.swapchain.renderPass, | 41 vulkan.swapchain.renderPass, |
44 vulkan.swapchain.width, | 44 vulkan.swapchain.width, |
45 vulkan.swapchain.height, | 45 vulkan.swapchain.height, |
46 vec4(0, 0, 0, 0), | 46 vec4(0, 0, 0, 0), |
47 ): | 47 ): |
48 withPipeline(commandbuffer, pipeline): | 48 withPipeline(commandbuffer, pipeline): |
49 renderGlyphs(commandbuffer, pipeline, glyphs) | 49 renderTextBuffer(commandbuffer, pipeline, textbuffer) |
50 | 50 |
51 # cleanup | 51 # cleanup |
52 checkVkResult vkDeviceWaitIdle(vulkan.device) | 52 checkVkResult vkDeviceWaitIdle(vulkan.device) |
53 destroyPipeline(pipeline) | 53 destroyPipeline(pipeline) |
54 destroyRenderData(renderdata) | 54 destroyRenderData(renderdata) |
71 uploadImages(renderdata, font3.descriptorSet) | 71 uploadImages(renderdata, font3.descriptorSet) |
72 initDescriptorSet(renderdata, pipeline.layout(0), font1.descriptorSet) | 72 initDescriptorSet(renderdata, pipeline.layout(0), font1.descriptorSet) |
73 initDescriptorSet(renderdata, pipeline.layout(0), font2.descriptorSet) | 73 initDescriptorSet(renderdata, pipeline.layout(0), font2.descriptorSet) |
74 initDescriptorSet(renderdata, pipeline.layout(0), font3.descriptorSet) | 74 initDescriptorSet(renderdata, pipeline.layout(0), font3.descriptorSet) |
75 | 75 |
76 var glyphs1 = font1.initGlyphs(10, baseScale = 0.1) | 76 var textbuffer1 = font1.initTextBuffer(10, baseScale = 0.1) |
77 var glyphs2 = font2.initGlyphs(10, baseScale = 0.1) | 77 var textbuffer2 = font2.initTextBuffer(10, baseScale = 0.1) |
78 var glyphs3 = font3.initGlyphs(10, baseScale = 0.1) | 78 var textbuffer3 = font3.initTextBuffer(10, baseScale = 0.1) |
79 | 79 |
80 assignBuffers(renderdata, glyphs1) | 80 assignBuffers(renderdata, textbuffer1) |
81 assignBuffers(renderdata, glyphs2) | 81 assignBuffers(renderdata, textbuffer2) |
82 assignBuffers(renderdata, glyphs3) | 82 assignBuffers(renderdata, textbuffer3) |
83 | 83 |
84 var labels = [" 0", " 1", " 2"] | 84 var labels = [" 0", " 1", " 2"] |
85 | 85 |
86 var start = getMonoTime() | 86 var start = getMonoTime() |
87 var p = 0 | 87 var p = 0 |
88 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 88 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
89 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time | 89 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time |
90 glyphs1.reset() | 90 textbuffer1.reset() |
91 glyphs2.reset() | 91 textbuffer2.reset() |
92 glyphs3.reset() | 92 textbuffer3.reset() |
93 | 93 |
94 glyphs1.add($(p + 0), vec3(0.3, 0.5)) | 94 textbuffer1.add($(p + 0), vec3(0.3, 0.5)) |
95 glyphs2.add($(p + 1), vec3(0.5, 0.5)) | 95 textbuffer2.add($(p + 1), vec3(0.5, 0.5)) |
96 glyphs3.add($(p + 2), vec3(0.7, 0.5)) | 96 textbuffer3.add($(p + 2), vec3(0.7, 0.5)) |
97 | 97 |
98 glyphs1.updateAllGPUBuffers(flush = true) | 98 textbuffer1.updateAllGPUBuffers(flush = true) |
99 glyphs2.updateAllGPUBuffers(flush = true) | 99 textbuffer2.updateAllGPUBuffers(flush = true) |
100 glyphs3.updateAllGPUBuffers(flush = true) | 100 textbuffer3.updateAllGPUBuffers(flush = true) |
101 | 101 |
102 inc p | 102 inc p |
103 withNextFrame(framebuffer, commandbuffer): | 103 withNextFrame(framebuffer, commandbuffer): |
104 withRenderPass( | 104 withRenderPass( |
105 vulkan.swapchain.renderPass, | 105 vulkan.swapchain.renderPass, |
109 vulkan.swapchain.height, | 109 vulkan.swapchain.height, |
110 vec4(0, 0, 0, 0), | 110 vec4(0, 0, 0, 0), |
111 ): | 111 ): |
112 withPipeline(commandbuffer, pipeline): | 112 withPipeline(commandbuffer, pipeline): |
113 bindDescriptorSet(commandbuffer, font1.descriptorSet, 0, pipeline) | 113 bindDescriptorSet(commandbuffer, font1.descriptorSet, 0, pipeline) |
114 renderGlyphs(commandbuffer, pipeline, glyphs1) | 114 renderTextBuffer(commandbuffer, pipeline, textbuffer1) |
115 bindDescriptorSet(commandbuffer, font2.descriptorSet, 0, pipeline) | 115 bindDescriptorSet(commandbuffer, font2.descriptorSet, 0, pipeline) |
116 renderGlyphs(commandbuffer, pipeline, glyphs2) | 116 renderTextBuffer(commandbuffer, pipeline, textbuffer2) |
117 bindDescriptorSet(commandbuffer, font3.descriptorSet, 0, pipeline) | 117 bindDescriptorSet(commandbuffer, font3.descriptorSet, 0, pipeline) |
118 renderGlyphs(commandbuffer, pipeline, glyphs3) | 118 renderTextBuffer(commandbuffer, pipeline, textbuffer3) |
119 | 119 |
120 # cleanup | 120 # cleanup |
121 checkVkResult vkDeviceWaitIdle(vulkan.device) | 121 checkVkResult vkDeviceWaitIdle(vulkan.device) |
122 destroyPipeline(pipeline) | 122 destroyPipeline(pipeline) |
123 destroyRenderData(renderdata) | 123 destroyRenderData(renderdata) |
132 | 132 |
133 assignBuffers(renderdata, font.descriptorSet) | 133 assignBuffers(renderdata, font.descriptorSet) |
134 uploadImages(renderdata, font.descriptorSet) | 134 uploadImages(renderdata, font.descriptorSet) |
135 initDescriptorSet(renderdata, pipeline.layout(0), font.descriptorSet) | 135 initDescriptorSet(renderdata, pipeline.layout(0), font.descriptorSet) |
136 | 136 |
137 var glyphs = font.initGlyphs(1000, baseScale = 0.1) | 137 var textbuffer = font.initTextBuffer(1000, baseScale = 0.1) |
138 assignBuffers(renderdata, glyphs) | 138 assignBuffers(renderdata, textbuffer) |
139 | 139 |
140 var start = getMonoTime() | 140 var start = getMonoTime() |
141 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 141 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
142 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time | 142 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time |
143 | 143 |
144 glyphs.reset() | 144 textbuffer.reset() |
145 glyphs.add("Anchor Center", vec3(0, 0), anchor = vec2(0, 0)) | 145 textbuffer.add("Anchor at center", vec3(0, 0), anchor = vec2(0, 0)) |
146 glyphs.add("Anchor top left", vec3(0, 0), anchor = vec2(-1, 1)) | 146 textbuffer.add("Anchor at top left`", vec3(-1, 1), anchor = vec2(-1, 1)) |
147 glyphs.add("Anchor top right", vec3(0, 0), anchor = vec2(1, 1)) | 147 textbuffer.add("Anchor at top right", vec3(1, 1), anchor = vec2(1, 1)) |
148 glyphs.add("Anchor bottom left", vec3(0, 0), anchor = vec2(-1, -1)) | 148 textbuffer.add("Anchor at bottom left", vec3(-1, -1), anchor = vec2(-1, -1)) |
149 glyphs.add("Anchor bottom right", vec3(0, 0), anchor = vec2(1, -1)) | 149 textbuffer.add("Anchor at bottom right", vec3(1, -1), anchor = vec2(1, -1)) |
150 | 150 |
151 glyphs.add( | 151 textbuffer.add( |
152 """Paragraph | 152 "Mutiline text\nLeft aligned\nCool!", vec3(-0.5, -0.5), alignment = Left |
153 This is a somewhat longer paragraph with a few newlines and a maximum width of 0.2. | |
154 | |
155 It should display with some space above and have a pleasing appearance overall! :)""", | |
156 vec3(0.5, 0.5), | |
157 anchor = vec2(0, 0), | |
158 alignment = Center, | |
159 ) | 153 ) |
160 glyphs.updateAllGPUBuffers(flush = true) | 154 textbuffer.add( |
155 "Mutiline text\nCenter aligned\nCool!!", vec3(0, -0.5), alignment = Center | |
156 ) | |
157 textbuffer.add( | |
158 "Mutiline text\nRight aligned\nCool!!!", vec3(0.5, -0.5), alignment = Right | |
159 ) | |
160 | |
161 textbuffer.updateAllGPUBuffers(flush = true) | |
161 | 162 |
162 withNextFrame(framebuffer, commandbuffer): | 163 withNextFrame(framebuffer, commandbuffer): |
163 bindDescriptorSet(commandbuffer, font.descriptorSet, 0, pipeline) | 164 bindDescriptorSet(commandbuffer, font.descriptorSet, 0, pipeline) |
164 withRenderPass( | 165 withRenderPass( |
165 vulkan.swapchain.renderPass, | 166 vulkan.swapchain.renderPass, |
168 vulkan.swapchain.width, | 169 vulkan.swapchain.width, |
169 vulkan.swapchain.height, | 170 vulkan.swapchain.height, |
170 vec4(0, 0, 0, 0), | 171 vec4(0, 0, 0, 0), |
171 ): | 172 ): |
172 withPipeline(commandbuffer, pipeline): | 173 withPipeline(commandbuffer, pipeline): |
173 renderGlyphs(commandbuffer, pipeline, glyphs) | 174 renderTextBuffer(commandbuffer, pipeline, textbuffer) |
174 | 175 |
175 # cleanup | 176 # cleanup |
176 checkVkResult vkDeviceWaitIdle(vulkan.device) | 177 checkVkResult vkDeviceWaitIdle(vulkan.device) |
177 destroyPipeline(pipeline) | 178 destroyPipeline(pipeline) |
178 destroyRenderData(renderdata) | 179 destroyRenderData(renderdata) |
179 | 180 |
180 #[ | |
181 proc test_04_lots_of_texts(time: float32) = | 181 proc test_04_lots_of_texts(time: float32) = |
182 var font = loadFont[MAX_CODEPOINTS]("DejaVuSans.ttf", lineHeightPixels = 160) | 182 var font = loadFont[MAX_CODEPOINTS]("DejaVuSans.ttf", lineHeightPixels = 160) |
183 var renderdata = initRenderData() | 183 var renderdata = initRenderData() |
184 | 184 |
185 var pipeline = createPipeline[GlyphShader[MAX_CODEPOINTS]]( | 185 var pipeline = createPipeline[GlyphShader[MAX_CODEPOINTS]]( |
186 renderPass = vulkan.swapchain.renderPass | 186 renderPass = vulkan.swapchain.renderPass |
187 ) | 187 ) |
188 | 188 |
189 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas.copy())) | 189 assignBuffers(renderdata, font.descriptorSet) |
190 uploadImages(renderdata, ds) | 190 uploadImages(renderdata, font.descriptorSet) |
191 initDescriptorSet(renderdata, pipeline.layout(0), ds) | 191 initDescriptorSet(renderdata, pipeline.layout(0), font.descriptorSet) |
192 | |
193 var textbuffer = font.initTextBuffer(1000, baseScale = 0.1) | |
194 assignBuffers(renderdata, textbuffer) | |
192 | 195 |
193 var labels: seq[Textbox] | 196 var labels: seq[Textbox] |
194 var positions = newSeq[Vec3f](100) | 197 var positions = newSeq[Vec3f](100) |
195 var colors = newSeq[Vec4f](100) | 198 var colors = newSeq[Vec4f](100) |
196 var scales = newSeq[Vec2f](100) | 199 var scales = newSeq[Vec2f](100) |
201 scales[i] = vec2(rand(0.5'f32 .. 1.5'f32), rand(0.5'f32 .. 1.5'f32)) | 204 scales[i] = vec2(rand(0.5'f32 .. 1.5'f32), rand(0.5'f32 .. 1.5'f32)) |
202 labels.add initTextbox(renderdata, pipeline.layout(0), font, 0.001, $i) | 205 labels.add initTextbox(renderdata, pipeline.layout(0), font, 0.001, $i) |
203 | 206 |
204 var start = getMonoTime() | 207 var start = getMonoTime() |
205 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 208 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
206 for l in labels.mitems: | 209 textbuffer.reset() |
207 l.refresh() | 210 withNextFrame(framebuffer, commandbuffer): |
208 withNextFrame(framebuffer, commandbuffer): | 211 bindDescriptorSet(commandbuffer, font.descriptorSet, 0, pipeline) |
209 bindDescriptorSet(commandbuffer, ds, 0, pipeline) | 212 withRenderPass( |
210 withRenderPass( | 213 vulkan.swapchain.renderPass, |
211 vulkan.swapchain.renderPass, | 214 framebuffer, |
212 framebuffer, | 215 commandbuffer, |
213 commandbuffer, | 216 vulkan.swapchain.width, |
214 vulkan.swapchain.width, | 217 vulkan.swapchain.height, |
215 vulkan.swapchain.height, | 218 vec4(0, 0, 0, 0), |
216 vec4(0, 0, 0, 0), | 219 ): |
217 ): | 220 withPipeline(commandbuffer, pipeline): |
218 withPipeline(commandbuffer, pipeline): | 221 renderTextBuffer(commandbuffer, pipeline, textbuffer) |
219 for i in 0 ..< labels.len: | |
220 render( | |
221 commandbuffer, pipeline, labels[i], positions[i], colors[i], scales[i] | |
222 ) | |
223 | 222 |
224 # cleanup | 223 # cleanup |
225 checkVkResult vkDeviceWaitIdle(vulkan.device) | 224 checkVkResult vkDeviceWaitIdle(vulkan.device) |
226 destroyPipeline(pipeline) | 225 destroyPipeline(pipeline) |
227 destroyRenderData(renderdata) | 226 destroyRenderData(renderdata) |
228 ]# | |
229 | 227 |
230 when isMainModule: | 228 when isMainModule: |
231 var time = 100'f32 | 229 var time = 100'f32 |
232 initVulkan() | 230 initVulkan() |
233 | 231 |