changeset 125:6e2c48cb6f60

add: mesh primitives
author Sam <sam@basx.dev>
date Tue, 11 Apr 2023 00:58:16 +0700
parents cb9e27a30165
children 81a8e62215db
files src/semicongine/mesh.nim src/semicongine/vulkan/shader.nim tests/test_vulkan_wrapper.nim
diffstat 3 files changed, 90 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/mesh.nim	Mon Apr 10 20:09:37 2023 +0700
+++ b/src/semicongine/mesh.nim	Tue Apr 11 00:58:16 2023 +0700
@@ -1,3 +1,4 @@
+import std/math as nimmath
 import std/typetraits
 import std/tables
 import std/enumerate
@@ -8,6 +9,7 @@
 import ./gpu_data
 import ./entity
 import ./math
+import ./color
 
 type
   MeshIndexType* = enum
@@ -41,7 +43,7 @@
   positions: openArray[Vec3f],
   indices: openArray[array[3, uint32|int32|uint16|int16|int]],
   colors: openArray[Vec3f]=[],
-  instances=1'u32,
+  instanceCount=1'u32,
   autoResize=true
 ): auto =
   assert colors.len == 0 or colors.len == positions.len
@@ -49,7 +51,7 @@
   result = new Mesh
   result.vertexCount = uint32(positions.len)
   result.indicesCount = uint32(indices.len * 3)
-  result.instanceCount = instances
+  result.instanceCount = instanceCount
   result.data["position"] = DataList(thetype: Vec3F32)
   setValues(result.data["position"], positions.toSeq)
   if colors.len > 0:
@@ -80,9 +82,9 @@
 func newMesh*(
   positions: openArray[Vec3f],
   colors: openArray[Vec3f]=[],
-  instances=1'u32,
+  instanceCount=1'u32,
 ): auto =
-  newMesh(positions, newSeq[array[3, int]](), colors, instances)
+  newMesh(positions, newSeq[array[3, int]](), colors, instanceCount)
 
 func dataSize*(mesh: Mesh, attribute: string): uint32 =
   mesh.data[attribute].size
@@ -115,3 +117,64 @@
   assert not (attribute in mesh.data)
   mesh.data[attribute] = DataList(thetype: getDataType[T]())
   setValues(mesh.data[attribute], data)
+
+
+func rect*(width=1'f32, height=1'f32, color="ffffff"): Mesh =
+  result = new Mesh
+  result.vertexCount = 4
+  result.indicesCount = 6
+  result.instanceCount = 1
+  result.data["position"] = DataList(thetype: Vec3F32)
+  result.data["color"] = DataList(thetype: Vec3F32)
+  result.indexType = Small
+  result.smallIndices = @[[0'u16, 1'u16, 2'u16], [2'u16, 3'u16, 0'u16]]
+
+  let
+    half_w = width / 2
+    half_h = height / 2
+    c = RGBfromHex(color)
+    v = [newVec3f(-half_w, -half_h), newVec3f( half_w, -half_h), newVec3f( half_w,  half_h), newVec3f(-half_w,  half_h)]
+
+  setValues(result.data["position"], v.toSeq)
+  setValues(result.data["color"], @[c, c, c, c])
+
+func tri*(width=1'f32, height=1'f32, color="ffffff"): Mesh =
+  result = new Mesh
+  result.vertexCount = 3
+  result.instanceCount = 1
+  result.data["position"] = DataList(thetype: Vec3F32)
+  result.data["color"] = DataList(thetype: Vec3F32)
+  let
+    half_w = width / 2
+    half_h = height / 2
+    colorVec = RGBfromHex(color)
+  setValues(result.data["position"], @[
+    newVec3f(0, -half_h), newVec3f( half_w, half_h), newVec3f(-half_w,  half_h),
+  ])
+  setValues(result.data["color"], @[colorVec, colorVec, colorVec])
+
+func circle*(width=1'f32, height=1'f32, nSegments=12'u16, color="ffffff"): Mesh =
+  assert nSegments >= 3
+  result = new Mesh
+  result.vertexCount = nSegments + 2
+  result.instanceCount = 1
+  result.indexType = Small
+  result.data["position"] = DataList(thetype: Vec3F32)
+  result.data["color"] = DataList(thetype: Vec3F32)
+  let
+    half_w = width / 2
+    half_h = height / 2
+    c = RGBfromHex(color)
+    step = (2'f32 * PI) / float32(nSegments)
+  var
+    pos = @[newVec3f(0, 0), newVec3f(0, half_h)]
+    col = @[c, c]
+    index: seq[array[3, uint16]] = @[]
+  for i in 0'u16 .. nSegments:
+    pos.add newVec3f(cos(float32(i) * step) * half_w, sin(float32(i) * step) * half_h)
+    col.add c
+    result.smallIndices.add [0'u16, i + 1, i + 2]
+
+  result.indicesCount = uint32(result.smallIndices.len * 3)
+  setValues(result.data["position"], pos)
+  setValues(result.data["color"], col)
--- a/src/semicongine/vulkan/shader.nim	Mon Apr 10 20:09:37 2023 +0700
+++ b/src/semicongine/vulkan/shader.nim	Tue Apr 11 00:58:16 2023 +0700
@@ -150,7 +150,7 @@
   var location = 0'u32
   var binding = baseBinding
 
-  for attribute in shader.inputs.vertexInputs:
+  for attribute in shader.inputs:
     bindings.add VkVertexInputBindingDescription(
       binding: binding,
       stride: attribute.size,
--- a/tests/test_vulkan_wrapper.nim	Mon Apr 10 20:09:37 2023 +0700
+++ b/tests/test_vulkan_wrapper.nim	Tue Apr 11 00:58:16 2023 +0700
@@ -89,13 +89,28 @@
     positions=[newVec3f(0.0, -0.8), newVec3f(0.8, 0.8), newVec3f(-0.8, 0.8)],
     colors=[newVec3f(0.0, 0.0, 1.0), newVec3f(0.0, 0.0, 1.0), newVec3f(0.0, 0.0, 1.0)],
     indices=[[0'u16, 1'u16, 2'u16]],
+    instanceCount=2
   )
-  setMeshData[Vec3f](mymesh1, "translate", @[newVec3f(0.3, 0.3)])
+  setMeshData[Vec3f](mymesh1, "translate", @[newVec3f(0.3, 0.0)])
+  setMeshData[Vec3f](mymesh2, "translate", @[newVec3f(0.0, 0.3)])
+  setMeshData[Vec3f](mymesh3, "translate", @[newVec3f(-0.3, 0.0)])
+  setMeshData[Vec3f](mymesh4, "translate", @[newVec3f(0.0, -0.3), newVec3f(0.0, 0.5)])
   result = Scene(
     name: "main",
-    root: newEntity("root", newEntity("triangle", mymesh4, mymesh3, mymesh2, mymesh1),)
+    root: newEntity("root", newEntity("triangle", mymesh4, mymesh3, mymesh2, mymesh1))
   )
 
+proc scene_primitives(): Scene =
+  var r = rect(color="ff0000")
+  var t = tri(color="0000ff")
+  var c = circle(color="00ff00")
+  setMeshData[Vec3f](r, "translate", @[newVec3f(0.5, -0.3)])
+  setMeshData[Vec3f](t, "translate", @[newVec3f(0.3,  0.3)])
+  setMeshData[Vec3f](c, "translate", @[newVec3f(-0.3,  0.1)])
+  result = Scene(
+    name: "main",
+    root: newEntity("root", t, r, c)
+  )
 
 when isMainModule:
   # INIT ENGINE:
@@ -121,7 +136,7 @@
     vertexInput = @[
       attr[Vec3f]("position", memoryLocation=VRAM),
       attr[Vec3f]("color", memoryLocation=VRAM),
-      # attr[Vec3f]("translate", perInstance=true)
+      attr[Vec3f]("translate", perInstance=true)
     ]
     vertexOutput = @[attr[Vec3f]("outcolor")]
     uniforms = @[attr[float32]("time")]
@@ -131,7 +146,7 @@
       inputs=vertexInput,
       uniforms=uniforms,
       outputs=vertexOutput,
-      body="""gl_Position = vec4(position, 1.0); outcolor = color * sin(Uniforms.time) * 0.5 + 0.5;"""
+      body="""gl_Position = vec4(position + translate, 1.0); outcolor = color;"""
     )
     fragmentCode = compileGlslShader(
       stage=VK_SHADER_STAGE_FRAGMENT_BIT,
@@ -152,7 +167,9 @@
   # INIT SCENE
   var time = initShaderGlobal("time", 0.0'f32)
 
-  var thescene = scene_simple()
+  # var thescene = scene_simple()
+  # var thescene = scene_different_mesh_types()
+  var thescene = scene_primitives()
   thescene.root.components.add time
   thescene.setupDrawables(renderPass)
   swapchain.setupUniforms(thescene)