# HG changeset patch # User Sam # Date 1673804141 -25200 # Node ID 7f99b21a8777b21ba50f5a33f945978424c6dd3f # Parent a3d46f4346165844b02acaf26a3887d1759e51b1 add: support for instance data diff -r a3d46f434616 -r 7f99b21a8777 config.nims --- 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() diff -r a3d46f434616 -r 7f99b21a8777 examples/hello_triangle.nim --- 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, diff -r a3d46f434616 -r 7f99b21a8777 src/zamikongine/vertex.nim --- 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