Mercurial > games > semicongine
annotate src/zamikongine/vertex.nim @ 22:b45a5d338cd0
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
| author | Sam <sam@basx.dev> |
|---|---|
| date | Wed, 11 Jan 2023 00:43:17 +0700 |
| parents | b55d6ecde79d |
| children | 9edca5dc4e93 |
| 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 | |
| 7 import ./vulkan | |
| 8 | |
|
13
a571db114152
add: vector/matrix modules, tests, nim config script
Sam <sam@basx.dev>
parents:
diff
changeset
|
9 type |
| 17 | 10 VertexAttributeType = SomeNumber|Vec |
| 11 VertexAttribute*[T:VertexAttributeType] = object | |
|
19
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
12 data*: seq[T] |
| 17 | 13 |
|
19
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
14 template rawAttributeType(v: VertexAttribute): auto = get(genericParams(typeof(v)), 0) |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
15 |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
16 func datasize*(attribute: VertexAttribute): uint64 = |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
17 uint64(sizeof(rawAttributeType(attribute))) * uint64(attribute.data.len) |
| 17 | 18 |
| 19 # from https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap15.html | |
| 20 func nLocationSlots[T: VertexAttributeType](): int = | |
| 21 when (T is Vec3[float64] or T is Vec3[uint64] or T is Vec4[float64] or T is Vec4[float64]): | |
| 22 2 | |
| 23 else: | |
| 24 1 | |
| 25 | |
| 26 # numbers | |
| 27 func getVkFormat[T: VertexAttributeType](): VkFormat = | |
| 28 when T is uint8: VK_FORMAT_R8_UINT | |
| 29 elif T is int8: VK_FORMAT_R8_SINT | |
| 30 elif T is uint16: VK_FORMAT_R16_UINT | |
| 31 elif T is int16: VK_FORMAT_R16_SINT | |
| 32 elif T is uint32: VK_FORMAT_R32_UINT | |
| 33 elif T is int32: VK_FORMAT_R32_SINT | |
| 34 elif T is uint64: VK_FORMAT_R64_UINT | |
| 35 elif T is int64: VK_FORMAT_R64_SINT | |
| 36 elif T is float32: VK_FORMAT_R32_SFLOAT | |
| 37 elif T is float64: VK_FORMAT_R64_SFLOAT | |
| 38 elif T is Vec2[uint8]: VK_FORMAT_R8G8_UINT | |
| 39 elif T is Vec2[int8]: VK_FORMAT_R8G8_SINT | |
| 40 elif T is Vec2[uint16]: VK_FORMAT_R16G16_UINT | |
| 41 elif T is Vec2[int16]: VK_FORMAT_R16G16_SINT | |
| 42 elif T is Vec2[uint32]: VK_FORMAT_R32G32_UINT | |
| 43 elif T is Vec2[int32]: VK_FORMAT_R32G32_SINT | |
| 44 elif T is Vec2[uint64]: VK_FORMAT_R64G64_UINT | |
| 45 elif T is Vec2[int64]: VK_FORMAT_R64G64_SINT | |
| 46 elif T is Vec2[float32]: VK_FORMAT_R32G32_SFLOAT | |
| 47 elif T is Vec2[float64]: VK_FORMAT_R64G64_SFLOAT | |
| 48 elif T is Vec3[uint8]: VK_FORMAT_R8G8B8_UINT | |
| 49 elif T is Vec3[int8]: VK_FORMAT_R8G8B8_SINT | |
| 50 elif T is Vec3[uint16]: VK_FORMAT_R16G16B16_UINT | |
| 51 elif T is Vec3[int16]: VK_FORMAT_R16G16B16_SINT | |
| 52 elif T is Vec3[uint32]: VK_FORMAT_R32G32B32_UINT | |
| 53 elif T is Vec3[int32]: VK_FORMAT_R32G32B32_SINT | |
| 54 elif T is Vec3[uint64]: VK_FORMAT_R64G64B64_UINT | |
| 55 elif T is Vec3[int64]: VK_FORMAT_R64G64B64_SINT | |
| 56 elif T is Vec3[float32]: VK_FORMAT_R32G32B32_SFLOAT | |
| 57 elif T is Vec3[float64]: VK_FORMAT_R64G64B64_SFLOAT | |
| 58 elif T is Vec4[uint8]: VK_FORMAT_R8G8B8A8_UINT | |
| 59 elif T is Vec4[int8]: VK_FORMAT_R8G8B8A8_SINT | |
| 60 elif T is Vec4[uint16]: VK_FORMAT_R16G16B16A16_UINT | |
| 61 elif T is Vec4[int16]: VK_FORMAT_R16G16B16A16_SINT | |
| 62 elif T is Vec4[uint32]: VK_FORMAT_R32G32B32A32_UINT | |
| 63 elif T is Vec4[int32]: VK_FORMAT_R32G32B32A32_SINT | |
| 64 elif T is Vec4[uint64]: VK_FORMAT_R64G64B64A64_UINT | |
| 65 elif T is Vec4[int64]: VK_FORMAT_R64G64B64A64_SINT | |
| 66 elif T is Vec4[float32]: VK_FORMAT_R32G32B32A32_SFLOAT | |
| 67 elif T is Vec4[float64]: VK_FORMAT_R64G64B64A64_SFLOAT | |
| 68 | |
| 69 func getGLSLType[T: VertexAttributeType](): string = | |
| 70 # todo: likely not correct as we would need to enable some | |
| 71 # extensions somewhere (Vulkan/GLSL compiler?) to have | |
| 72 # everything work as intended. Or maybe the GPU driver does | |
| 73 # some automagic conversion stuf.. | |
| 74 when T is uint8: "uint" | |
| 75 elif T is int8: "int" | |
| 76 elif T is uint16: "uint" | |
| 77 elif T is int16: "int" | |
| 78 elif T is uint32: "uint" | |
| 79 elif T is int32: "int" | |
| 80 elif T is uint64: "uint" | |
| 81 elif T is int64: "int" | |
| 82 elif T is float32: "float" | |
| 83 elif T is float64: "double" | |
| 84 | |
| 85 elif T is Vec2[uint8]: "uvec2" | |
| 86 elif T is Vec2[int8]: "ivec2" | |
| 87 elif T is Vec2[uint16]: "uvec2" | |
| 88 elif T is Vec2[int16]: "ivec2" | |
| 89 elif T is Vec2[uint32]: "uvec2" | |
| 90 elif T is Vec2[int32]: "ivec2" | |
| 91 elif T is Vec2[uint64]: "uvec2" | |
| 92 elif T is Vec2[int64]: "ivec2" | |
| 93 elif T is Vec2[float32]: "vec2" | |
| 94 elif T is Vec2[float64]: "dvec2" | |
|
13
a571db114152
add: vector/matrix modules, tests, nim config script
Sam <sam@basx.dev>
parents:
diff
changeset
|
95 |
| 17 | 96 elif T is Vec3[uint8]: "uvec3" |
| 97 elif T is Vec3[int8]: "ivec3" | |
| 98 elif T is Vec3[uint16]: "uvec3" | |
| 99 elif T is Vec3[int16]: "ivec3" | |
| 100 elif T is Vec3[uint32]: "uvec3" | |
| 101 elif T is Vec3[int32]: "ivec3" | |
| 102 elif T is Vec3[uint64]: "uvec3" | |
| 103 elif T is Vec3[int64]: "ivec3" | |
| 104 elif T is Vec3[float32]: "vec3" | |
| 105 elif T is Vec3[float64]: "dvec3" | |
| 106 | |
| 107 elif T is Vec4[uint8]: "uvec4" | |
| 108 elif T is Vec4[int8]: "ivec4" | |
| 109 elif T is Vec4[uint16]: "uvec4" | |
| 110 elif T is Vec4[int16]: "ivec4" | |
| 111 elif T is Vec4[uint32]: "uvec4" | |
| 112 elif T is Vec4[int32]: "ivec4" | |
| 113 elif T is Vec4[uint64]: "uvec4" | |
| 114 elif T is Vec4[int64]: "ivec4" | |
| 115 elif T is Vec4[float32]: "vec4" | |
| 116 elif T is Vec4[float64]: "dvec4" | |
| 117 | |
| 118 | |
|
19
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
119 func VertexCount*[T](t: T): uint32 = |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
120 for name, value in t.fieldPairs: |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
121 when typeof(value) is VertexAttribute: |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
122 if result == 0: |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
123 result = uint32(value.data.len) |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
124 else: |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
125 assert result == uint32(value.data.len) |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
126 |
|
b55d6ecde79d
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
17
diff
changeset
|
127 func generateGLSLDeclarations*[T](): string = |
| 17 | 128 var stmtList: seq[string] |
| 129 var i = 0 | |
| 130 for name, value in T().fieldPairs: | |
| 131 when typeof(value) is VertexAttribute: | |
| 132 let glsltype = getGLSLType[rawAttributeType(value)]() | |
| 133 let n = name | |
| 134 stmtList.add(&"layout(location = {i}) in {glsltype} {n};") | |
| 135 i += nLocationSlots[rawAttributeType(value)]() | |
| 136 | |
| 137 return stmtList.join("\n") | |
|
13
a571db114152
add: vector/matrix modules, tests, nim config script
Sam <sam@basx.dev>
parents:
diff
changeset
|
138 |
| 17 | 139 func generateInputVertexBinding*[T](bindingoffset: int = 0, locationoffset: int = 0): seq[VkVertexInputBindingDescription] = |
| 140 # packed attribute data, not interleaved (aks "struct of arrays") | |
| 141 var binding = bindingoffset | |
| 142 for name, value in T().fieldPairs: | |
| 143 when typeof(value) is VertexAttribute: | |
| 144 result.add( | |
| 145 VkVertexInputBindingDescription( | |
| 146 binding: uint32(binding), | |
| 147 stride: uint32(sizeof(rawAttributeType(value))), | |
| 148 inputRate: VK_VERTEX_INPUT_RATE_VERTEX, # VK_VERTEX_INPUT_RATE_INSTANCE for instances | |
| 149 ) | |
| 150 ) | |
| 151 binding += 1 | |
| 152 | |
| 153 func generateInputAttributeBinding*[T](bindingoffset: int = 0, locationoffset: int = 0): seq[VkVertexInputAttributeDescription] = | |
| 154 # packed attribute data, not interleaved (aks "struct of arrays") | |
| 155 var location = 0 | |
| 156 var binding = bindingoffset | |
| 157 for name, value in T().fieldPairs: | |
| 158 when typeof(value) is VertexAttribute: | |
| 159 result.add( | |
| 160 VkVertexInputAttributeDescription( | |
| 161 binding: uint32(binding), | |
| 162 location: uint32(location), | |
| 163 format: getVkFormat[rawAttributeType(value)](), | |
| 164 offset: 0, | |
| 165 ) | |
| 166 ) | |
| 167 location += nLocationSlots[rawAttributeType(value)]() | |
| 168 binding += 1 |
