diff tests/test_gltf.nim @ 1254:b0f4c8ccd49a

did: stuff to test gltf importer
author sam <sam@basx.dev>
date Sat, 27 Jul 2024 20:47:54 +0700
parents c4f98eb4bb05
children 2b5ca798f6d6
line wrap: on
line diff
--- a/tests/test_gltf.nim	Fri Jul 26 23:39:24 2024 +0700
+++ b/tests/test_gltf.nim	Sat Jul 27 20:47:54 2024 +0700
@@ -14,8 +14,7 @@
     ObjectData = object
       transform: Mat4
     Camera = object
-      view: Mat4
-      perspective: Mat4
+      viewPerspective: Mat4
     Material = object
       color: Vec4f = NewVec4f(1, 1, 1, 1)
       colorTexture: int32 = -1
@@ -33,7 +32,8 @@
     Shader = object
       objectData {.PushConstantAttribute.}: ObjectData
       position {.VertexAttribute.}: Vec3f
-      uv {.VertexAttribute.}: Vec2f
+      color {.VertexAttribute.}: Vec4f
+      # uv {.VertexAttribute.}: Vec2f
       fragmentColor {.Pass.}: Vec4f
       fragmentUv {.Pass.}: Vec2f
       outColor {.ShaderOutput.}: Vec4f
@@ -41,21 +41,26 @@
       # code
       vertexCode: string = """
 void main() {
-  fragmentColor = vec4(1, 1, 1, 1);
-  fragmentUv = uv;
-  gl_Position = vec4(position, 1) * camera.perspective * camera.view;
+  fragmentColor = color;
+  // fragmentUv = uv;
+  gl_Position = vec4(position, 1) * camera.viewPerspective;
 }"""
       fragmentCode: string = """void main() { outColor = fragmentColor;}"""
     Mesh = object
       position: GPUArray[Vec3f, VertexBuffer]
+      color: GPUArray[Vec4f, VertexBuffer]
       uv: GPUArray[Vec2f, VertexBuffer]
+    DebugMesh = object
+      position: GPUArray[Vec3f, VertexBuffer]
+      color: GPUArray[Vec4f, VertexBuffer]
 
   var gltfData = LoadMeshes[Mesh, Material](
     "town.glb",
     MeshAttributeNames(
       POSITION: "position",
-    TEXCOORD: @["uv"],
-  ),
+      COLOR: @["color"],
+      TEXCOORD: @["uv"],
+    ),
     MaterialAttributeNames(
       baseColorFactor: "color",
       baseColorTexture: "colorTexture",
@@ -71,31 +76,86 @@
   var descriptors = asDescriptorSet(
     MainDescriptors(
       camera: asGPUValue(Camera(
-        view: Unit4,
-        perspective: Unit4,
-    ), UniformBufferMapped)
-  )
+        viewPerspective: Unit4,
+      ), UniformBufferMapped)
+    )
   )
   for mesh in mitems(gltfData.meshes):
     for primitive in mitems(mesh):
+      primitive[0].color = asGPUArray(newSeqWith(primitive[0].position.data.len, NewVec4f(1, 1, 1, 1)), VertexBuffer)
       renderdata.AssignBuffers(primitive[0])
   renderdata.AssignBuffers(descriptors)
 
-  var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass)
+  let O = default(Vec3f)
+  let Gray = NewVec4f(0.5, 0.5, 0.5, 1)
+  var gridPos = @[O, X, O, Y, O, Z]
+  var gridColor = @[R, R, G, G, B, B]
+  for i in 0 ..< 10:
+    gridPos.add [NewVec3f(-5, -0.001, i.float32 - 5), NewVec3f(5, -0.001, i.float32 - 5)]
+    gridPos.add [NewVec3f(i.float32 - 5, -0.001, -5), NewVec3f(i.float32 - 5, -0.001, 5)]
+    gridColor.add [Gray, Gray, Gray, Gray]
+  var grid = DebugMesh(
+    position: asGPUArray(gridPos, VertexBuffer),
+    color: asGPUArray(gridColor, VertexBuffer),
+  )
+  renderdata.AssignBuffers(grid)
+
+  var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, cullMode = [])
+  var debugpipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass, topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, lineWidth=10)
   InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors)
+
   renderdata.FlushAllMemory()
 
-  proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4 = Unit4) =
+  proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int,
+      transform: Mat4 = Unit4) =
     let nodeTransform = gltfData.nodes[nodeId].transform * transform
     if gltfData.nodes[nodeId].mesh >= 0:
       for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh]:
-        RenderWithPushConstant(commandbuffer = commandbuffer, pipeline = pipeline, mesh = primitive[0], pushConstant = ObjectData(transform: nodeTransform))
+        RenderWithPushConstant(
+          commandbuffer = commandbuffer,
+          pipeline = pipeline,
+          mesh = primitive[0],
+          pushConstant = ObjectData(transform: nodeTransform)
+        )
     for childNode in gltfData.nodes[nodeId].children:
       drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = childNode, transform = nodeTransform)
 
+  var camPos: Vec3f
+  var camYaw: float32
+  var camPitch: float32
+
+  discard UpdateInputs() # clear inputs, otherwise MouseMove will have stuff
 
   var start = getMonoTime()
-  while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
+  var lastT = getMonoTime()
+  while ((getMonoTime() - start).inMilliseconds().int / 1000) < time and UpdateInputs():
+    let dt = ((getMonoTime() - lastT).inNanoseconds().int / 1_000_000_000).float32
+    lastT = getMonoTime()
+
+    camYaw  -= MouseMove().x / 1000
+    camPitch -= MouseMove().y / 1000
+    var
+      forward = 0'f32
+      sideward = 0'f32
+    if KeyIsDown(W): forward += 2
+    if KeyIsDown(S): forward -= 2
+    if KeyIsDown(A): sideward -= 2
+    if KeyIsDown(D): sideward += 2
+
+    let camDir = (Rotate(camPitch, X) * Rotate(camYaw, Y)) * Z
+    echo camDir
+    let camDirSide = (Rotate(camPitch, X) * Rotate(camYaw, Y)) * X
+    # echo camDir
+    # echo camDirSide
+    camPos += camDir * forward * dt
+    camPos += camDirSide * sideward * dt
+
+    descriptors.data.camera.data.viewPerspective = (
+      Perspective(PI/3, aspect = GetAspectRatio(), zNear = 0.001, zFar = 100) *
+      Rotate(-camPitch, X) * Rotate(-camYaw, Y) * Translate(-camPos)
+    )
+
+    UpdateGPUBuffer(descriptors.data.camera)
 
     WithNextFrame(framebuffer, commandbuffer):
 
@@ -105,17 +165,22 @@
           WithBind(commandbuffer, (descriptors, ), pipeline):
             for nodeId in gltfData.scenes[0]:
               drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = nodeId)
+        WithBind(commandbuffer, (descriptors, ), pipeline):
+          WithPipeline(commandbuffer, debugpipeline):
+            Render(commandbuffer = commandbuffer, pipeline = debugpipeline, mesh = grid)
 
   # cleanup
   checkVkResult vkDeviceWaitIdle(vulkan.device)
   DestroyPipeline(pipeline)
+  DestroyPipeline(debugpipeline)
   DestroyRenderData(renderdata)
 when isMainModule:
-  var time = 5'f32
+  var time = 1000'f32
   InitVulkan()
 
   var renderpass = CreateDirectPresentationRenderPass(depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT)
   SetupSwapchain(renderpass = renderpass)
+  LockMouse(true)
 
   # tests a simple triangle with minimalistic shader and vertex format
   test_gltf(time)