changeset 1253:c4f98eb4bb05

fix: a few things
author sam <sam@basx.dev>
date Fri, 26 Jul 2024 23:39:24 +0700
parents 01e9f41d35b1
children b0f4c8ccd49a
files semiconginev2/core/matrix.nim semiconginev2/core/vector.nim semiconginev2/gltf.nim semiconginev2/rendering.nim semiconginev2/rendering/renderer.nim semiconginev2/rendering/shaders.nim tests/test_gltf.nim
diffstat 7 files changed, 77 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/semiconginev2/core/matrix.nim	Fri Jul 26 23:04:01 2024 +0700
+++ b/semiconginev2/core/matrix.nim	Fri Jul 26 23:39:24 2024 +0700
@@ -103,7 +103,7 @@
   elif m is TMat4: 16
 
 
-func toString[T: TMat](value: T): string =
+func toMatString[T: TMat](value: T): string =
   var
     strvalues: seq[string]
     maxwidth = 0
@@ -123,13 +123,13 @@
         result &= "  "
       result &= filler & strvalues[i] & "  "
 
-func `$`*(v: TMat2[SomeNumber]): string = toString[TMat2[SomeNumber]](v)
-func `$`*(v: TMat23[SomeNumber]): string = toString[TMat23[SomeNumber]](v)
-func `$`*(v: TMat32[SomeNumber]): string = toString[TMat32[SomeNumber]](v)
-func `$`*(v: TMat3[SomeNumber]): string = toString[TMat3[SomeNumber]](v)
-func `$`*(v: TMat34[SomeNumber]): string = toString[TMat34[SomeNumber]](v)
-func `$`*(v: TMat43[SomeNumber]): string = toString[TMat43[SomeNumber]](v)
-func `$`*(v: TMat4[SomeNumber]): string = toString[TMat4[SomeNumber]](v)
+func `$`*(v: TMat2[SomeNumber]): string = toMatString[TMat2[SomeNumber]](v)
+func `$`*(v: TMat23[SomeNumber]): string = toMatString[TMat23[SomeNumber]](v)
+func `$`*(v: TMat32[SomeNumber]): string = toMatString[TMat32[SomeNumber]](v)
+func `$`*(v: TMat3[SomeNumber]): string = toMatString[TMat3[SomeNumber]](v)
+func `$`*(v: TMat34[SomeNumber]): string = toMatString[TMat34[SomeNumber]](v)
+func `$`*(v: TMat43[SomeNumber]): string = toMatString[TMat43[SomeNumber]](v)
+func `$`*(v: TMat4[SomeNumber]): string = toMatString[TMat4[SomeNumber]](v)
 
 func `[]`*[T: TMat](m: T, row, col: int): auto = m.data[col + row * T.ColumnCount]
 func `[]=`*[T: TMat, U](m: var T, row, col: int, value: U) = m.data[col + row * T.ColumnCount] = value
--- a/semiconginev2/core/vector.nim	Fri Jul 26 23:04:01 2024 +0700
+++ b/semiconginev2/core/vector.nim	Fri Jul 26 23:39:24 2024 +0700
@@ -102,16 +102,16 @@
 func To*[T](v: TVec3): auto = TVec3([T(v[0]), T(v[1]), T(v[2])])
 func To*[T](v: TVec4): auto = TVec4([T(v[0]), T(v[1]), T(v[2]), T(v[3])])
 
-func toString[T: TVec](value: T): string =
+func toVecString[T: TVec](value: T): string =
   var items: seq[string]
   for item in value:
     items.add(&"{item.float:.5f}")
   & "(" & join(items, "  ") & ")"
 
-func `$`*(v: TVec1[SomeNumber]): string = toString[TVec1[SomeNumber]](v)
-func `$`*(v: TVec2[SomeNumber]): string = toString[TVec2[SomeNumber]](v)
-func `$`*(v: TVec3[SomeNumber]): string = toString[TVec3[SomeNumber]](v)
-func `$`*(v: TVec4[SomeNumber]): string = toString[TVec4[SomeNumber]](v)
+func `$`*(v: TVec1[SomeNumber]): string = toVecString[TVec1[SomeNumber]](v)
+func `$`*(v: TVec2[SomeNumber]): string = toVecString[TVec2[SomeNumber]](v)
+func `$`*(v: TVec3[SomeNumber]): string = toVecString[TVec3[SomeNumber]](v)
+func `$`*(v: TVec4[SomeNumber]): string = toVecString[TVec4[SomeNumber]](v)
 
 func Length*(vec: TVec1): auto = vec[0]
 func Length*(vec: TVec2[SomeFloat]): auto = sqrt(vec[0] * vec[0] + vec[1] * vec[1])
--- a/semiconginev2/gltf.nim	Fri Jul 26 23:04:01 2024 +0700
+++ b/semiconginev2/gltf.nim	Fri Jul 26 23:39:24 2024 +0700
@@ -233,31 +233,32 @@
   if "matrix" in node:
     for i in 0 ..< node["matrix"].len:
       result.transform[i] = node["matrix"][i].getFloat()
+    result.transform = result.transform.Transposed()
+  else:
+    var (t, r, s) = (Unit4, Unit4, Unit4)
+    if "translation" in node:
+      t = Translate(
+        float32(node["translation"][0].getFloat()),
+        float32(node["translation"][1].getFloat()),
+        float32(node["translation"][2].getFloat())
+      )
+    if "rotation" in node:
+      t = Rotate(
+        float32(node["rotation"][3].getFloat()),
+        NewVec3f(
+          float32(node["rotation"][0].getFloat()),
+          float32(node["rotation"][1].getFloat()),
+          float32(node["rotation"][2].getFloat())
+        )
+      )
+    if "scale" in node:
+      t = Scale(
+        float32(node["scale"][0].getFloat()),
+        float32(node["scale"][1].getFloat()),
+        float32(node["scale"][2].getFloat())
+      )
 
-  var (t, r, s) = (Unit4, Unit4, Unit4)
-  if "translation" in node:
-    t = Translate(
-      float32(node["translation"][0].getFloat()),
-      float32(node["translation"][1].getFloat()),
-      float32(node["translation"][2].getFloat())
-    )
-  if "rotation" in node:
-    t = Rotate(
-      float32(node["rotation"][3].getFloat()),
-      NewVec3f(
-        float32(node["rotation"][0].getFloat()),
-        float32(node["rotation"][1].getFloat()),
-        float32(node["rotation"][2].getFloat())
-      )
-    )
-  if "scale" in node:
-    t = Scale(
-      float32(node["scale"][0].getFloat()),
-      float32(node["scale"][1].getFloat()),
-      float32(node["scale"][2].getFloat())
-    )
-
-  result.transform = t * r * s * result.transform
+    result.transform = t * r * s
 
 proc ReadglTF*[TMesh, TMaterial](
   stream: Stream,
--- a/semiconginev2/rendering.nim	Fri Jul 26 23:04:01 2024 +0700
+++ b/semiconginev2/rendering.nim	Fri Jul 26 23:39:24 2024 +0700
@@ -14,6 +14,7 @@
 const MAX_DESCRIPTORSETS = 4
 const SURFACE_FORMAT* = VK_FORMAT_B8G8R8A8_SRGB
 const DEPTH_FORMAT* = VK_FORMAT_D32_SFLOAT
+const PUSH_CONSTANT_SIZE = 128
 
 # custom pragmas to classify shader attributes
 template VertexAttribute* {.pragma.}
--- a/semiconginev2/rendering/renderer.nim	Fri Jul 26 23:04:01 2024 +0700
+++ b/semiconginev2/rendering/renderer.nim	Fri Jul 26 23:39:24 2024 +0700
@@ -670,6 +670,16 @@
 ) =
   Render(commandBuffer, pipeline, mesh, EMPTY())
 
+proc assertValidPushConstantType(TShader, TPushConstant: typedesc) =
+  assert sizeof(TPushConstant) <= PUSH_CONSTANT_SIZE, "Push constant values must be <= 128 bytes"
+  var foundPushConstant = false
+  for fieldname, fieldvalue in default(TShader).fieldPairs():
+    when hasCustomPragma(fieldvalue, PushConstantAttribute):
+      assert typeof(fieldvalue) is TPushConstant, "Provided push constant has not same type as declared in shader"
+      assert foundPushConstant == false, "More than on push constant found in shader"
+      foundPushConstant = true
+  assert foundPushConstant == true, "No push constant found in shader"
+
 proc RenderWithPushConstant*[TShader, TMesh, TInstance, TPushConstant](
   commandBuffer: VkCommandBuffer,
   pipeline: Pipeline[TShader],
@@ -677,12 +687,13 @@
   instances: TInstance,
   pushConstant: TPushConstant,
 ) =
+  static: assertValidPushConstantType(TShader, TPushConstant)
   vkCmdPushConstants(
     commandBuffer = commandBuffer,
     layout = pipeline.layout,
     stageFlags = VkShaderStageFlags(VK_SHADER_STAGE_ALL_GRAPHICS),
     offset = 0,
-    size = 128,
+    size = PUSH_CONSTANT_SIZE,
     pValues = addr(pushConstant)
   );
   Render(commandBuffer, pipeline, mesh, instances)
@@ -692,12 +703,13 @@
   mesh: TMesh,
   pushConstant: TPushConstant,
 ) =
+  static: assertValidPushConstantType(TShader, TPushConstant)
   vkCmdPushConstants(
     commandBuffer = commandBuffer,
     layout = pipeline.layout,
     stageFlags = VkShaderStageFlags(VK_SHADER_STAGE_ALL_GRAPHICS),
     offset = 0,
-    size = 128,
+    size = PUSH_CONSTANT_SIZE,
     pValues = addr(pushConstant)
   );
   Render(commandBuffer, pipeline, mesh, EMPTY())
--- a/semiconginev2/rendering/shaders.nim	Fri Jul 26 23:04:01 2024 +0700
+++ b/semiconginev2/rendering/shaders.nim	Fri Jul 26 23:39:24 2024 +0700
@@ -376,7 +376,7 @@
   let pushConstant = VkPushConstantRange(
     stageFlags: VkShaderStageFlags(VK_SHADER_STAGE_ALL_GRAPHICS),
     offset: 0,
-    size: 128, # currently supported everywhere, places for two mat4
+    size: PUSH_CONSTANT_SIZE, # currently supported everywhere, places for two mat4
   )
 
   let pipelineLayoutInfo = VkPipelineLayoutCreateInfo(
--- a/tests/test_gltf.nim	Fri Jul 26 23:04:01 2024 +0700
+++ b/tests/test_gltf.nim	Fri Jul 26 23:39:24 2024 +0700
@@ -11,6 +11,11 @@
   var renderdata = InitRenderData()
 
   type
+    ObjectData = object
+      transform: Mat4
+    Camera = object
+      view: Mat4
+      perspective: Mat4
     Material = object
       color: Vec4f = NewVec4f(1, 1, 1, 1)
       colorTexture: int32 = -1
@@ -24,7 +29,9 @@
       emissiveTexture: int32 = -1
     MainDescriptors = object
       material: GPUValue[Material, UniformBuffer]
+      camera: GPUValue[Camera, UniformBufferMapped]
     Shader = object
+      objectData {.PushConstantAttribute.}: ObjectData
       position {.VertexAttribute.}: Vec3f
       uv {.VertexAttribute.}: Vec2f
       fragmentColor {.Pass.}: Vec4f
@@ -36,7 +43,7 @@
 void main() {
   fragmentColor = vec4(1, 1, 1, 1);
   fragmentUv = uv;
-  gl_Position = vec4(position, 1);
+  gl_Position = vec4(position, 1) * camera.perspective * camera.view;
 }"""
       fragmentCode: string = """void main() { outColor = fragmentColor;}"""
     Mesh = object
@@ -61,18 +68,28 @@
       emissiveFactor: "emissive",
     )
   )
+  var descriptors = asDescriptorSet(
+    MainDescriptors(
+      camera: asGPUValue(Camera(
+        view: Unit4,
+        perspective: Unit4,
+    ), UniformBufferMapped)
+  )
+  )
   for mesh in mitems(gltfData.meshes):
     for primitive in mitems(mesh):
       renderdata.AssignBuffers(primitive[0])
-  renderdata.FlushAllMemory()
+  renderdata.AssignBuffers(descriptors)
 
   var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass)
+  InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors)
+  renderdata.FlushAllMemory()
 
   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]:
-        Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = primitive[0])
+        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)
 
@@ -85,8 +102,9 @@
       WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)):
 
         WithPipeline(commandbuffer, pipeline):
-          for nodeId in gltfData.scenes[0]:
-            drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = nodeId)
+          WithBind(commandbuffer, (descriptors, ), pipeline):
+            for nodeId in gltfData.scenes[0]:
+              drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = nodeId)
 
   # cleanup
   checkVkResult vkDeviceWaitIdle(vulkan.device)