# HG changeset patch # User Sam # Date 1681149496 -25200 # Node ID 6e2c48cb6f600cd0b595f72a4d2a62bebefa9a0a # Parent cb9e27a3016549e19912e6e4422b184599a75f9e add: mesh primitives diff -r cb9e27a30165 -r 6e2c48cb6f60 src/semicongine/mesh.nim --- 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) diff -r cb9e27a30165 -r 6e2c48cb6f60 src/semicongine/vulkan/shader.nim --- 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, diff -r cb9e27a30165 -r 6e2c48cb6f60 tests/test_vulkan_wrapper.nim --- 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)