view tests/test_text.nim @ 1269:81450075ad89

fix: readme markup
author sam <sam@basx.dev>
date Sun, 28 Jul 2024 23:16:10 +0700
parents 4cf9872f7bb6
children c09cdff9a97e
line wrap: on
line source

import std/os
import std/algorithm
import std/strutils
import std/sequtils
import std/monotimes
import std/times
import std/options
import std/random

import ../semicongine

proc test_01_static_label(time: float32) =
  var renderdata = InitRenderData()

  var pipeline = CreatePipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass)

  var font = LoadFont("Overhaul.ttf", lineHeightPixels = 160)
  var label1 = InitTextbox(
    renderdata,
    pipeline.descriptorSetLayouts[0],
    font,
    "Hello semicongine!",
    color = NewVec4f(1, 1, 1, 1),
    scale = 0.0005,
  )

  var start = getMonoTime()
  while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
    label1.Refresh()
    WithNextFrame(framebuffer, commandbuffer):
      WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)):
        WithPipeline(commandbuffer, pipeline):
          Render(label1, commandbuffer, pipeline)

        # cleanup
  checkVkResult vkDeviceWaitIdle(vulkan.device)
  DestroyPipeline(pipeline)
  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 labels = [
    InitTextbox(
      renderdata,
      pipeline.descriptorSetLayouts[0],
      font1,
      "  0",
      color = NewVec4f(0, 1, 1, 1),
      scale = 0.004,
      position = NewVec3f(-0.3, 0.5)
    ),
    InitTextbox(
      renderdata,
      pipeline.descriptorSetLayouts[0],
      font2,
      "  1",
      color = NewVec4f(1, 0, 1, 1),
      scale = 0.001,
      position = NewVec3f(0, 0)
    ),
    InitTextbox(
      renderdata,
      pipeline.descriptorSetLayouts[0],
      font3,
      "  2",
      color = NewVec4f(1, 1, 0, 1),
      scale = 0.001,
      position = NewVec3f(0.3, -0.5)
    )
  ]

  var start = getMonoTime()
  var p = 0
  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 + NewVec3f(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, NewVec4f(0, 0, 0, 0)):
        WithPipeline(commandbuffer, pipeline):
          for label in labels:
            Render(label, commandbuffer, pipeline)

      # cleanup
  checkVkResult vkDeviceWaitIdle(vulkan.device)
  DestroyPipeline(pipeline)
  DestroyRenderData(renderdata)

proc test_03_layouting(time: float32) =
  var renderdata = InitRenderData()

  var pipeline = CreatePipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass)

  var font = LoadFont("DejaVuSans.ttf", lineHeightPixels = 40)
  var labels: seq[Textbox]

  for horizontal in HorizontalAlignment:
    labels.add InitTextbox(
      renderdata,
      pipeline.descriptorSetLayouts[0],
      font,
      $horizontal & " aligned",
      color = NewVec4f(1, 1, 1, 1),
      scale = 0.001,
      position = NewVec3f(0, 0.9 - (horizontal.float * 0.15)),
      horizontalAlignment = horizontal,
    )
  for vertical in VerticalAlignment:
    labels.add InitTextbox(
      renderdata,
      pipeline.descriptorSetLayouts[0],
      font,
      $vertical & " aligned",
      color = NewVec4f(1, 1, 1, 1),
      scale = 0.001,
      position = NewVec3f(-0.35 + (vertical.float * 0.35), 0.3),
      verticalAlignment = vertical,
    )
  labels.add InitTextbox(
    renderdata,
    pipeline.descriptorSetLayouts[0],
    font,
    """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 = NewVec4f(1, 1, 1, 1),
    scale = 0.001,
    position = NewVec3f(-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):
      WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)):
        WithPipeline(commandbuffer, pipeline):
          for label in labels:
            Render(label, commandbuffer, pipeline)

      # cleanup
  checkVkResult vkDeviceWaitIdle(vulkan.device)
  DestroyPipeline(pipeline)
  DestroyRenderData(renderdata)

proc test_04_lots_of_texts(time: float32) =
  var renderdata = InitRenderData()

  var pipeline = CreatePipeline[DefaultFontShader](renderPass = vulkan.swapchain.renderPass)

  var font = LoadFont("DejaVuSans.ttf", lineHeightPixels = 160)
  var labels: seq[Textbox]
  for i in 0 ..< 100:
    labels.add InitTextbox(
      renderdata,
      pipeline.descriptorSetLayouts[0],
      font,
      $i,
      color = NewVec4f(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 = NewVec3f(rand(-0.5 .. 0.5), rand(-0.5 .. 0.5), rand(-0.1 .. 0.1))
    )
  labels = labels.sortedByIt(-it.Position.z)

  var start = getMonoTime()
  while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
    for l in labels.mitems:
      l.Refresh()
    WithNextFrame(framebuffer, commandbuffer):
      WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)):
        WithPipeline(commandbuffer, pipeline):
          for l in labels:
            Render(l, commandbuffer, pipeline)

        # cleanup
  checkVkResult vkDeviceWaitIdle(vulkan.device)
  DestroyPipeline(pipeline)
  DestroyRenderData(renderdata)

when isMainModule:
  var time = 1'f32
  InitVulkan()

  for depthBuffer in [true, false]:
    var renderpass = CreateDirectPresentationRenderPass(depthBuffer = depthBuffer)
    SetupSwapchain(renderpass = renderpass)

    # tests a simple triangle with minimalistic shader and vertex format
    test_01_static_label(time)
    test_02_multiple_animated(time)
    test_03_layouting(time)
    test_04_lots_of_texts(time)

    checkVkResult vkDeviceWaitIdle(vulkan.device)
    vkDestroyRenderPass(vulkan.device, renderpass.vk, nil)
    ClearSwapchain()

  DestroyVulkan()