Mercurial > games > semicongine
annotate src/zamikongine/vertex.nim @ 35:7f99b21a8777
add: support for instance data
| author | Sam <sam@basx.dev> | 
|---|---|
| date | Mon, 16 Jan 2023 00:35:41 +0700 | 
| parents | 94c38e4b5782 | 
| children | 
| rev | line source | 
|---|---|
| 17 | 1 import std/macros | 
| 2 import std/strutils | |
| 3 import std/strformat | |
| 4 import std/typetraits | |
| 5 | |
| 6 import ./math/vector | |
| 32 | 7 import ./math/matrix | 
| 17 | 8 import ./vulkan | 
| 32 | 9 import ./glsl_helpers | 
| 17 | 10 | 
| 13 
a571db114152
add: vector/matrix modules, tests, nim config script
 Sam <sam@basx.dev> parents: diff
changeset | 11 type | 
| 17 | 12 VertexAttributeType = SomeNumber|Vec | 
| 32 | 13 AttributePurpose* = enum | 
| 14 Unknown, Position Color | |
| 15 GenericAttribute*[T:VertexAttributeType] = object | |
| 16 data*: seq[T] | |
| 33 
94c38e4b5782
did: refactoring, move more from make to nimscript
 Sam <sam@basx.dev> parents: 
32diff
changeset | 17 PositionAttribute*[T:Vec] = object | 
| 19 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 18 data*: seq[T] | 
| 33 
94c38e4b5782
did: refactoring, move more from make to nimscript
 Sam <sam@basx.dev> parents: 
32diff
changeset | 19 ColorAttribute*[T:Vec] = object | 
| 32 | 20 data*: seq[T] | 
| 35 | 21 InstanceAttribute*[T:Vec] = object | 
| 22 data*: seq[T] | |
| 23 VertexAttribute* = GenericAttribute|PositionAttribute|ColorAttribute|InstanceAttribute | |
| 17 | 24 | 
| 32 | 25 template getAttributeType*(v: VertexAttribute): auto = get(genericParams(typeof(v)), 0) | 
| 19 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 26 | 
| 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 27 func datasize*(attribute: VertexAttribute): uint64 = | 
| 32 | 28 uint64(sizeof(getAttributeType(attribute))) * uint64(attribute.data.len) | 
| 17 | 29 | 
| 30 # from https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap15.html | |
| 31 func nLocationSlots[T: VertexAttributeType](): int = | |
| 35 | 32 when (T is Mat44[float64]): | 
| 33 8 | |
| 34 elif (T is Mat44[float32]): | |
| 35 4 | |
| 36 elif (T is Vec3[float64] or T is Vec3[uint64] or T is Vec4[float64] or T is Vec4[float64]): | |
| 17 | 37 2 | 
| 38 else: | |
| 39 1 | |
| 40 | |
| 41 # numbers | |
| 42 func getVkFormat[T: VertexAttributeType](): VkFormat = | |
| 43 when T is uint8: VK_FORMAT_R8_UINT | |
| 44 elif T is int8: VK_FORMAT_R8_SINT | |
| 45 elif T is uint16: VK_FORMAT_R16_UINT | |
| 46 elif T is int16: VK_FORMAT_R16_SINT | |
| 47 elif T is uint32: VK_FORMAT_R32_UINT | |
| 48 elif T is int32: VK_FORMAT_R32_SINT | |
| 49 elif T is uint64: VK_FORMAT_R64_UINT | |
| 50 elif T is int64: VK_FORMAT_R64_SINT | |
| 51 elif T is float32: VK_FORMAT_R32_SFLOAT | |
| 52 elif T is float64: VK_FORMAT_R64_SFLOAT | |
| 53 elif T is Vec2[uint8]: VK_FORMAT_R8G8_UINT | |
| 54 elif T is Vec2[int8]: VK_FORMAT_R8G8_SINT | |
| 55 elif T is Vec2[uint16]: VK_FORMAT_R16G16_UINT | |
| 56 elif T is Vec2[int16]: VK_FORMAT_R16G16_SINT | |
| 57 elif T is Vec2[uint32]: VK_FORMAT_R32G32_UINT | |
| 58 elif T is Vec2[int32]: VK_FORMAT_R32G32_SINT | |
| 59 elif T is Vec2[uint64]: VK_FORMAT_R64G64_UINT | |
| 60 elif T is Vec2[int64]: VK_FORMAT_R64G64_SINT | |
| 61 elif T is Vec2[float32]: VK_FORMAT_R32G32_SFLOAT | |
| 62 elif T is Vec2[float64]: VK_FORMAT_R64G64_SFLOAT | |
| 63 elif T is Vec3[uint8]: VK_FORMAT_R8G8B8_UINT | |
| 64 elif T is Vec3[int8]: VK_FORMAT_R8G8B8_SINT | |
| 65 elif T is Vec3[uint16]: VK_FORMAT_R16G16B16_UINT | |
| 66 elif T is Vec3[int16]: VK_FORMAT_R16G16B16_SINT | |
| 67 elif T is Vec3[uint32]: VK_FORMAT_R32G32B32_UINT | |
| 68 elif T is Vec3[int32]: VK_FORMAT_R32G32B32_SINT | |
| 69 elif T is Vec3[uint64]: VK_FORMAT_R64G64B64_UINT | |
| 70 elif T is Vec3[int64]: VK_FORMAT_R64G64B64_SINT | |
| 71 elif T is Vec3[float32]: VK_FORMAT_R32G32B32_SFLOAT | |
| 72 elif T is Vec3[float64]: VK_FORMAT_R64G64B64_SFLOAT | |
| 73 elif T is Vec4[uint8]: VK_FORMAT_R8G8B8A8_UINT | |
| 74 elif T is Vec4[int8]: VK_FORMAT_R8G8B8A8_SINT | |
| 75 elif T is Vec4[uint16]: VK_FORMAT_R16G16B16A16_UINT | |
| 76 elif T is Vec4[int16]: VK_FORMAT_R16G16B16A16_SINT | |
| 77 elif T is Vec4[uint32]: VK_FORMAT_R32G32B32A32_UINT | |
| 78 elif T is Vec4[int32]: VK_FORMAT_R32G32B32A32_SINT | |
| 79 elif T is Vec4[uint64]: VK_FORMAT_R64G64B64A64_UINT | |
| 80 elif T is Vec4[int64]: VK_FORMAT_R64G64B64A64_SINT | |
| 81 elif T is Vec4[float32]: VK_FORMAT_R32G32B32A32_SFLOAT | |
| 82 elif T is Vec4[float64]: VK_FORMAT_R64G64B64A64_SFLOAT | |
| 83 | |
| 84 | |
| 85 | |
| 19 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 86 func VertexCount*[T](t: T): uint32 = | 
| 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 87 for name, value in t.fieldPairs: | 
| 35 | 88 when typeof(value) is VertexAttribute and not (typeof(value) is InstanceAttribute): | 
| 19 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 89 if result == 0: | 
| 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 90 result = uint32(value.data.len) | 
| 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 91 else: | 
| 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 92 assert result == uint32(value.data.len) | 
| 
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
 Sam <sam@basx.dev> parents: 
17diff
changeset | 93 | 
| 32 | 94 func generateGLSLVertexDeclarations*[T](): string = | 
| 17 | 95 var stmtList: seq[string] | 
| 96 var i = 0 | |
| 97 for name, value in T().fieldPairs: | |
| 98 when typeof(value) is VertexAttribute: | |
| 32 | 99 let glsltype = getGLSLType[getAttributeType(value)]() | 
| 17 | 100 let n = name | 
| 101 stmtList.add(&"layout(location = {i}) in {glsltype} {n};") | |
| 32 | 102 i += nLocationSlots[getAttributeType(value)]() | 
| 17 | 103 | 
| 104 return stmtList.join("\n") | |
| 13 
a571db114152
add: vector/matrix modules, tests, nim config script
 Sam <sam@basx.dev> parents: diff
changeset | 105 | 
| 17 | 106 func generateInputVertexBinding*[T](bindingoffset: int = 0, locationoffset: int = 0): seq[VkVertexInputBindingDescription] = | 
| 107 # packed attribute data, not interleaved (aks "struct of arrays") | |
| 108 var binding = bindingoffset | |
| 109 for name, value in T().fieldPairs: | |
| 35 | 110 when typeof(value) is InstanceAttribute: | 
| 17 | 111 result.add( | 
| 112 VkVertexInputBindingDescription( | |
| 113 binding: uint32(binding), | |
| 32 | 114 stride: uint32(sizeof(getAttributeType(value))), | 
| 35 | 115 inputRate: VK_VERTEX_INPUT_RATE_INSTANCE, | 
| 116 ) | |
| 117 ) | |
| 118 binding += 1 | |
| 119 elif typeof(value) is VertexAttribute: | |
| 120 result.add( | |
| 121 VkVertexInputBindingDescription( | |
| 122 binding: uint32(binding), | |
| 123 stride: uint32(sizeof(getAttributeType(value))), | |
| 124 inputRate: VK_VERTEX_INPUT_RATE_VERTEX, | |
| 17 | 125 ) | 
| 126 ) | |
| 127 binding += 1 | |
| 128 | |
| 129 func generateInputAttributeBinding*[T](bindingoffset: int = 0, locationoffset: int = 0): seq[VkVertexInputAttributeDescription] = | |
| 130 # packed attribute data, not interleaved (aks "struct of arrays") | |
| 131 var location = 0 | |
| 132 var binding = bindingoffset | |
| 133 for name, value in T().fieldPairs: | |
| 134 when typeof(value) is VertexAttribute: | |
| 135 result.add( | |
| 136 VkVertexInputAttributeDescription( | |
| 137 binding: uint32(binding), | |
| 138 location: uint32(location), | |
| 32 | 139 format: getVkFormat[getAttributeType(value)](), | 
| 17 | 140 offset: 0, | 
| 141 ) | |
| 142 ) | |
| 32 | 143 location += nLocationSlots[getAttributeType(value)]() | 
| 17 | 144 binding += 1 | 
