Mercurial > games > semicongine
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1326:41f3612ef38d | 1327:373a4888f6ac |
|---|---|
| 7 import std/options | 7 import std/options |
| 8 import std/random | 8 import std/random |
| 9 | 9 |
| 10 import ../semicongine | 10 import ../semicongine |
| 11 | 11 |
| 12 type | |
| 13 FontDS = object | |
| 14 fontAtlas: Image[Gray] | |
| 15 | |
| 12 proc test_01_static_label(time: float32) = | 16 proc test_01_static_label(time: float32) = |
| 13 var renderdata = initRenderData() | |
| 14 | |
| 15 var pipeline = createPipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) | |
| 16 | |
| 17 var font = loadFont("Overhaul.ttf", lineHeightPixels = 160) | 17 var font = loadFont("Overhaul.ttf", lineHeightPixels = 160) |
| 18 var renderdata = initRenderData() | |
| 19 var pipeline = createPipeline[DefaultFontShader[FontDS]](renderPass = vulkan.swapchain.renderPass) | |
| 20 | |
| 21 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas)) | |
| 22 uploadImages(renderdata, ds) | |
| 23 initDescriptorSet( | |
| 24 renderdata, | |
| 25 pipeline.layout(0), | |
| 26 ds, | |
| 27 ) | |
| 28 | |
| 18 var label1 = initTextbox( | 29 var label1 = initTextbox( |
| 19 renderdata, | 30 renderdata, |
| 20 pipeline.layout(0), | 31 pipeline.layout(0), |
| 21 font, | 32 font, |
| 33 0.0005, | |
| 22 "Hello semicongine!", | 34 "Hello semicongine!", |
| 23 color = vec4(1, 1, 1, 1), | |
| 24 scale = 0.0005, | |
| 25 ) | 35 ) |
| 26 | 36 |
| 27 var start = getMonoTime() | 37 var start = getMonoTime() |
| 28 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 38 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
| 29 label1.refresh() | 39 label1.refresh() |
| 30 withNextFrame(framebuffer, commandbuffer): | 40 withNextFrame(framebuffer, commandbuffer): |
| 31 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): | 41 bindDescriptorSet(commandbuffer, ds, 0, pipeline) |
| 32 withPipeline(commandbuffer, pipeline): | 42 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): |
| 33 render(commandbuffer, pipeline, label1) | 43 withPipeline(commandbuffer, pipeline): |
| 44 render(commandbuffer, pipeline, label1, vec3(), vec4(1, 1, 1, 1)) | |
| 34 | 45 |
| 35 # cleanup | 46 # cleanup |
| 36 checkVkResult vkDeviceWaitIdle(vulkan.device) | 47 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 37 destroyPipeline(pipeline) | 48 destroyPipeline(pipeline) |
| 38 destroyRenderData(renderdata) | 49 destroyRenderData(renderdata) |
| 39 | 50 |
| 40 proc test_02_multiple_animated(time: float32) = | 51 proc test_02_multiple_animated(time: float32) = |
| 41 var renderdata = initRenderData() | |
| 42 | |
| 43 var pipeline = createPipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) | |
| 44 | |
| 45 var font1 = loadFont("Overhaul.ttf", lineHeightPixels = 40) | 52 var font1 = loadFont("Overhaul.ttf", lineHeightPixels = 40) |
| 46 var font2 = loadFont("Overhaul.ttf", lineHeightPixels = 160) | 53 var font2 = loadFont("Overhaul.ttf", lineHeightPixels = 160) |
| 47 var font3 = loadFont("DejaVuSans.ttf", lineHeightPixels = 160) | 54 var font3 = loadFont("DejaVuSans.ttf", lineHeightPixels = 160) |
| 55 var renderdata = initRenderData() | |
| 56 | |
| 57 var pipeline = createPipeline[DefaultFontShader[FontDS]](renderPass = vulkan.swapchain.renderPass) | |
| 58 | |
| 59 var ds1 = asDescriptorSetData(FontDS(fontAtlas: font1.fontAtlas)) | |
| 60 uploadImages(renderdata, ds1) | |
| 61 initDescriptorSet(renderdata, pipeline.layout(0), ds1) | |
| 62 | |
| 63 var ds2 = asDescriptorSetData(FontDS(fontAtlas: font2.fontAtlas)) | |
| 64 uploadImages(renderdata, ds2) | |
| 65 initDescriptorSet(renderdata, pipeline.layout(0), ds2) | |
| 66 | |
| 67 var ds3 = asDescriptorSetData(FontDS(fontAtlas: font3.fontAtlas)) | |
| 68 uploadImages(renderdata, ds3) | |
| 69 initDescriptorSet(renderdata, pipeline.layout(0), ds3) | |
| 70 | |
| 48 var labels = [ | 71 var labels = [ |
| 49 initTextbox( | 72 initTextbox( |
| 50 renderdata, | 73 renderdata, |
| 51 pipeline.layout(0), | 74 pipeline.layout(0), |
| 52 font1, | 75 font1, |
| 76 0.004, | |
| 53 " 0", | 77 " 0", |
| 54 color = vec4(0, 1, 1, 1), | |
| 55 scale = 0.004, | |
| 56 position = vec3(-0.3, 0.5) | |
| 57 ), | 78 ), |
| 58 initTextbox( | 79 initTextbox( |
| 59 renderdata, | 80 renderdata, |
| 60 pipeline.layout(0), | 81 pipeline.layout(0), |
| 61 font2, | 82 font2, |
| 83 0.001, | |
| 62 " 1", | 84 " 1", |
| 63 color = vec4(1, 0, 1, 1), | |
| 64 scale = 0.001, | |
| 65 position = vec3(0, 0) | |
| 66 ), | 85 ), |
| 67 initTextbox( | 86 initTextbox( |
| 68 renderdata, | 87 renderdata, |
| 69 pipeline.layout(0), | 88 pipeline.layout(0), |
| 70 font3, | 89 font3, |
| 90 0.001, | |
| 71 " 2", | 91 " 2", |
| 72 color = vec4(1, 1, 0, 1), | |
| 73 scale = 0.001, | |
| 74 position = vec3(0.3, -0.5) | |
| 75 ) | 92 ) |
| 76 ] | 93 ] |
| 77 | 94 |
| 78 var start = getMonoTime() | 95 var start = getMonoTime() |
| 79 var p = 0 | 96 var p = 0 |
| 80 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 97 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
| 81 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time | 98 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time |
| 82 for i in 0 ..< labels.len: | 99 for i in 0 ..< labels.len: |
| 83 var c = labels[i].color | |
| 84 c[i] = progress | |
| 85 labels[i].color = c | |
| 86 labels[i].scale = labels[i].scale * (1.0 + (i + 1).float * 0.001) | |
| 87 labels[i].position = labels[i].position + vec3(0.001 * (i.float - 1'f)) | |
| 88 labels[i].text = $(p + i) | 100 labels[i].text = $(p + i) |
| 89 labels[i].refresh() | 101 labels[i].refresh() |
| 90 inc p | 102 inc p |
| 91 withNextFrame(framebuffer, commandbuffer): | 103 withNextFrame(framebuffer, commandbuffer): |
| 92 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): | 104 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): |
| 93 withPipeline(commandbuffer, pipeline): | 105 withPipeline(commandbuffer, pipeline): |
| 94 for label in labels.litems: | 106 bindDescriptorSet(commandbuffer, ds1, 0, pipeline) |
| 95 render(commandbuffer, pipeline, label) | 107 render( |
| 108 commandbuffer, | |
| 109 pipeline, | |
| 110 labels[0], | |
| 111 position=vec3(0 / labels.len, 0.1 + progress * 0.5), | |
| 112 color=vec4(1, 1, 1, 1), | |
| 113 ) | |
| 114 bindDescriptorSet(commandbuffer, ds2, 0, pipeline) | |
| 115 render( | |
| 116 commandbuffer, | |
| 117 pipeline, | |
| 118 labels[1], | |
| 119 position=vec3(1 / labels.len, 0.1 + progress * 0.5), | |
| 120 color=vec4(1, 1, 1, 1), | |
| 121 ) | |
| 122 bindDescriptorSet(commandbuffer, ds3, 0, pipeline) | |
| 123 render( | |
| 124 commandbuffer, | |
| 125 pipeline, | |
| 126 labels[2], | |
| 127 position=vec3(2 / labels.len, 0.1 + progress * 0.5), | |
| 128 color=vec4(1, 1, 1, 1), | |
| 129 ) | |
| 96 | 130 |
| 97 # cleanup | 131 # cleanup |
| 98 checkVkResult vkDeviceWaitIdle(vulkan.device) | 132 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 99 destroyPipeline(pipeline) | 133 destroyPipeline(pipeline) |
| 100 destroyRenderData(renderdata) | 134 destroyRenderData(renderdata) |
| 101 | 135 |
| 102 proc test_03_layouting(time: float32) = | 136 proc test_03_layouting(time: float32) = |
| 103 var renderdata = initRenderData() | |
| 104 | |
| 105 var pipeline = createPipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) | |
| 106 | |
| 107 var font = loadFont("DejaVuSans.ttf", lineHeightPixels = 40) | 137 var font = loadFont("DejaVuSans.ttf", lineHeightPixels = 40) |
| 138 var renderdata = initRenderData() | |
| 139 | |
| 140 var pipeline = createPipeline[DefaultFontShader[FontDS]](renderPass = vulkan.swapchain.renderPass) | |
| 141 | |
| 142 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas)) | |
| 143 uploadImages(renderdata, ds) | |
| 144 initDescriptorSet( | |
| 145 renderdata, | |
| 146 pipeline.layout(0), | |
| 147 ds, | |
| 148 ) | |
| 149 | |
| 108 var labels: seq[Textbox] | 150 var labels: seq[Textbox] |
| 109 | 151 |
| 110 for horizontal in HorizontalAlignment: | 152 for horizontal in HorizontalAlignment: |
| 111 labels.add initTextbox( | 153 labels.add initTextbox( |
| 112 renderdata, | 154 renderdata, |
| 113 pipeline.layout(0), | 155 pipeline.layout(0), |
| 114 font, | 156 font, |
| 157 0.001, | |
| 115 $horizontal & " aligned", | 158 $horizontal & " aligned", |
| 116 color = vec4(1, 1, 1, 1), | |
| 117 scale = 0.001, | |
| 118 position = vec3(0, 0.9 - (horizontal.float * 0.15)), | |
| 119 horizontalAlignment = horizontal, | 159 horizontalAlignment = horizontal, |
| 120 ) | 160 ) |
| 121 for vertical in VerticalAlignment: | 161 for vertical in VerticalAlignment: |
| 122 labels.add initTextbox( | 162 labels.add initTextbox( |
| 123 renderdata, | 163 renderdata, |
| 124 pipeline.layout(0), | 164 pipeline.layout(0), |
| 125 font, | 165 font, |
| 166 0.001, | |
| 126 $vertical & " aligned", | 167 $vertical & " aligned", |
| 127 color = vec4(1, 1, 1, 1), | |
| 128 scale = 0.001, | |
| 129 position = vec3(-0.35 + (vertical.float * 0.35), 0.3), | |
| 130 verticalAlignment = vertical, | 168 verticalAlignment = vertical, |
| 131 ) | 169 ) |
| 132 labels.add initTextbox( | 170 labels.add initTextbox( |
| 133 renderdata, | 171 renderdata, |
| 134 pipeline.layout(0), | 172 pipeline.layout(0), |
| 135 font, | 173 font, |
| 174 0.001, | |
| 136 """Paragraph | 175 """Paragraph |
| 137 This is a somewhat longer paragraph with a few newlines and a maximum width of 0.2. | 176 This is a somewhat longer paragraph with a few newlines and a maximum width of 0.2. |
| 138 | 177 |
| 139 It should display with some space above and have a pleasing appearance overall! :)""", | 178 It should display with some space above and have a pleasing appearance overall! :)""", |
| 140 maxWidth = 0.6, | 179 maxWidth = 0.6, |
| 141 color = vec4(1, 1, 1, 1), | |
| 142 scale = 0.001, | |
| 143 position = vec3(-0.9, 0.1), | |
| 144 verticalAlignment = Top, | 180 verticalAlignment = Top, |
| 145 horizontalAlignment = Left, | 181 horizontalAlignment = Left, |
| 146 ) | 182 ) |
| 147 | 183 |
| 148 | |
| 149 var start = getMonoTime() | 184 var start = getMonoTime() |
| 150 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 185 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
| 151 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time | 186 let progress = ((getMonoTime() - start).inMilliseconds().int / 1000) / time |
| 152 withNextFrame(framebuffer, commandbuffer): | 187 withNextFrame(framebuffer, commandbuffer): |
| 153 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): | 188 bindDescriptorSet(commandbuffer, ds, 0, pipeline) |
| 154 withPipeline(commandbuffer, pipeline): | 189 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): |
| 155 for label in labels: | 190 withPipeline(commandbuffer, pipeline): |
| 156 render(commandbuffer, pipeline, label) | 191 for i in 0 ..< labels.len: |
| 192 render(commandbuffer, pipeline, labels[i], vec3(0.5 - i.float32 * 0.1, 0.5 - i.float32 * 0.1), vec4(1, 1, 1, 1)) | |
| 157 | 193 |
| 158 # cleanup | 194 # cleanup |
| 159 checkVkResult vkDeviceWaitIdle(vulkan.device) | 195 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 160 destroyPipeline(pipeline) | 196 destroyPipeline(pipeline) |
| 161 destroyRenderData(renderdata) | 197 destroyRenderData(renderdata) |
| 162 | 198 |
| 163 proc test_04_lots_of_texts(time: float32) = | 199 proc test_04_lots_of_texts(time: float32) = |
| 164 var renderdata = initRenderData() | |
| 165 | |
| 166 var pipeline = createPipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass) | |
| 167 | |
| 168 var font = loadFont("DejaVuSans.ttf", lineHeightPixels = 160) | 200 var font = loadFont("DejaVuSans.ttf", lineHeightPixels = 160) |
| 201 var renderdata = initRenderData() | |
| 202 | |
| 203 var pipeline = createPipeline[DefaultFontShader[FontDS]](renderPass = vulkan.swapchain.renderPass) | |
| 204 | |
| 205 var ds = asDescriptorSetData(FontDS(fontAtlas: font.fontAtlas)) | |
| 206 uploadImages(renderdata, ds) | |
| 207 initDescriptorSet( | |
| 208 renderdata, | |
| 209 pipeline.layout(0), | |
| 210 ds, | |
| 211 ) | |
| 212 | |
| 169 var labels: seq[Textbox] | 213 var labels: seq[Textbox] |
| 214 var positions = newSeq[Vec3f](100) | |
| 215 var colors = newSeq[Vec4f](100) | |
| 216 var scales = newSeq[float32](100) | |
| 170 for i in 0 ..< 100: | 217 for i in 0 ..< 100: |
| 218 positions[i] = vec3(rand(-0.5 .. 0.5), rand(-0.5 .. 0.5), rand(-0.1 .. 0.1)) | |
| 219 colors[i] = vec4(rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0)) | |
| 220 scales[i] = rand(0.5'f32 .. 1.5'f32) | |
| 171 labels.add initTextbox( | 221 labels.add initTextbox( |
| 172 renderdata, | 222 renderdata, |
| 173 pipeline.layout(0), | 223 pipeline.layout(0), |
| 174 font, | 224 font, |
| 225 0.001, | |
| 175 $i, | 226 $i, |
| 176 color = vec4(rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0), rand(0.5 .. 1.0)), | 227 ) |
| 177 scale = rand(0.0002 .. 0.002), | |
| 178 position = vec3(rand(-0.5 .. 0.5), rand(-0.5 .. 0.5), rand(-0.1 .. 0.1)) | |
| 179 ) | |
| 180 labels.sort(proc(x, y: Textbox): int = cmp(x.position.z, y.position.z), Ascending) | |
| 181 | 228 |
| 182 var start = getMonoTime() | 229 var start = getMonoTime() |
| 183 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: | 230 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: |
| 184 for l in labels.mitems: | 231 for l in labels.mitems: |
| 185 l.refresh() | 232 l.refresh() |
| 186 withNextFrame(framebuffer, commandbuffer): | 233 withNextFrame(framebuffer, commandbuffer): |
| 187 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): | 234 bindDescriptorSet(commandbuffer, ds, 0, pipeline) |
| 188 withPipeline(commandbuffer, pipeline): | 235 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): |
| 189 for l in labels: | 236 withPipeline(commandbuffer, pipeline): |
| 190 render(commandbuffer, pipeline, l) | 237 for i in 0 ..< labels.len: |
| 238 render(commandbuffer, pipeline, labels[i], positions[i], colors[i], scales[i]) | |
| 191 | 239 |
| 192 # cleanup | 240 # cleanup |
| 193 checkVkResult vkDeviceWaitIdle(vulkan.device) | 241 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 194 destroyPipeline(pipeline) | 242 destroyPipeline(pipeline) |
| 195 destroyRenderData(renderdata) | 243 destroyRenderData(renderdata) |
