changeset 35:7f99b21a8777

add: support for instance data
author Sam <sam@basx.dev>
date Mon, 16 Jan 2023 00:35:41 +0700
parents a3d46f434616
children 2979b69eef55
files config.nims examples/hello_triangle.nim src/zamikongine/vertex.nim
diffstat 3 files changed, 24 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/config.nims	Mon Jan 16 00:03:20 2023 +0700
+++ b/config.nims	Mon Jan 16 00:35:41 2023 +0700
@@ -105,5 +105,5 @@
   exec("rsync -rv build/ basx.dev:/var/www/public.basx.dev/zamikongine")
 
 
-if getCommand() == "c":
+if getCommand() in ["c", "compile", "r", "dump", "check"]:
   compilerFlags()
--- a/examples/hello_triangle.nim	Mon Jan 16 00:03:20 2023 +0700
+++ b/examples/hello_triangle.nim	Mon Jan 16 00:35:41 2023 +0700
@@ -17,6 +17,7 @@
   VertexDataA = object
     position: PositionAttribute[Vec2[float32]]
     color: ColorAttribute[Vec3[float32]]
+    id: InstanceAttribute[Vec3[float32]]
 
 var pipeline: RenderPipeline[VertexDataA, void]
 
@@ -44,6 +45,7 @@
   trianglemesh.vertexData = VertexDataA(
     position: PositionAttribute[Vec2[float32]](data: triangle_pos),
     color: ColorAttribute[Vec3[float32]](data: triangle_color),
+    id: InstanceAttribute[Vec3[float32]](data: @[Vec3[float32]([0.5'f32, 0.5'f32, 0.5'f32])]),
   )
   # build a single-object scene graph
   var triangle = new Thing
@@ -51,9 +53,7 @@
   triangle.parts.add trianglemesh
 
   # upload data, prepare shaders, etc
-  const vertexShader = generateVertexShaderCode[VertexDataA, void](
-    # "out_position = uniforms.mat * vec4(in_position, 0, 1);"
-  )
+  const vertexShader = generateVertexShaderCode[VertexDataA, void]()
   const fragmentShader = generateFragmentShaderCode[VertexDataA]()
   pipeline = setupPipeline[VertexDataA, void, uint16](
     myengine,
--- a/src/zamikongine/vertex.nim	Mon Jan 16 00:03:20 2023 +0700
+++ b/src/zamikongine/vertex.nim	Mon Jan 16 00:35:41 2023 +0700
@@ -18,7 +18,9 @@
     data*: seq[T]
   ColorAttribute*[T:Vec] = object
     data*: seq[T]
-  VertexAttribute* = GenericAttribute|PositionAttribute|ColorAttribute
+  InstanceAttribute*[T:Vec] = object
+    data*: seq[T]
+  VertexAttribute* = GenericAttribute|PositionAttribute|ColorAttribute|InstanceAttribute
 
 template getAttributeType*(v: VertexAttribute): auto = get(genericParams(typeof(v)), 0)
 
@@ -27,7 +29,11 @@
 
 # from https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap15.html
 func nLocationSlots[T: VertexAttributeType](): int =
-  when (T is Vec3[float64] or T is Vec3[uint64] or T is Vec4[float64] or T is Vec4[float64]):
+  when (T is Mat44[float64]):
+    8
+  elif (T is Mat44[float32]):
+    4
+  elif (T is Vec3[float64] or T is Vec3[uint64] or T is Vec4[float64] or T is Vec4[float64]):
     2
   else:
     1
@@ -79,17 +85,12 @@
 
 func VertexCount*[T](t: T): uint32 =
   for name, value in t.fieldPairs:
-    when typeof(value) is VertexAttribute:
+    when typeof(value) is VertexAttribute and not (typeof(value) is InstanceAttribute):
       if result == 0:
         result = uint32(value.data.len)
       else:
         assert result == uint32(value.data.len)
 
-func VertexAttributesCount*[T](): uint32 =
-  for name, value in T().fieldPairs:
-    when typeof(value) is VertexAttribute:
-      result += 1
-
 func generateGLSLVertexDeclarations*[T](): string =
   var stmtList: seq[string]
   var i = 0
@@ -106,12 +107,21 @@
   # packed attribute data, not interleaved (aks "struct of arrays")
   var binding = bindingoffset
   for name, value in T().fieldPairs:
-    when typeof(value) is VertexAttribute:
+    when typeof(value) is InstanceAttribute:
       result.add(
         VkVertexInputBindingDescription(
           binding: uint32(binding),
           stride: uint32(sizeof(getAttributeType(value))),
-          inputRate: VK_VERTEX_INPUT_RATE_VERTEX, # VK_VERTEX_INPUT_RATE_INSTANCE for instances
+          inputRate: VK_VERTEX_INPUT_RATE_INSTANCE,
+        )
+      )
+      binding += 1
+    elif typeof(value) is VertexAttribute:
+      result.add(
+        VkVertexInputBindingDescription(
+          binding: uint32(binding),
+          stride: uint32(sizeof(getAttributeType(value))),
+          inputRate: VK_VERTEX_INPUT_RATE_VERTEX,
         )
       )
       binding += 1