Mercurial > games > semicongine
annotate src/zamikongine/vertex.nim @ 26:8b4bc545958d
did: update gitignore
author | Sam <sam@basx.dev> |
---|---|
date | Wed, 11 Jan 2023 11:43:59 +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 |