comparison src/zamikongine/vertex.nim @ 32:9edca5dc4e93

add: working implementation of uniforms
author Sam <sam@basx.dev>
date Sat, 14 Jan 2023 23:34:50 +0700
parents b55d6ecde79d
children 94c38e4b5782
comparison
equal deleted inserted replaced
31:0996104ad066 32:9edca5dc4e93
2 import std/strutils 2 import std/strutils
3 import std/strformat 3 import std/strformat
4 import std/typetraits 4 import std/typetraits
5 5
6 import ./math/vector 6 import ./math/vector
7 import ./math/matrix
7 import ./vulkan 8 import ./vulkan
9 import ./glsl_helpers
8 10
9 type 11 type
10 VertexAttributeType = SomeNumber|Vec 12 VertexAttributeType = SomeNumber|Vec
11 VertexAttribute*[T:VertexAttributeType] = object 13 AttributePurpose* = enum
14 Unknown, Position Color
15 GenericAttribute*[T:VertexAttributeType] = object
12 data*: seq[T] 16 data*: seq[T]
17 PositionAttribute*[T:VertexAttributeType] = object
18 data*: seq[T]
19 ColorAttribute*[T:VertexAttributeType] = object
20 data*: seq[T]
21 VertexAttribute* = GenericAttribute|PositionAttribute|ColorAttribute
13 22
14 template rawAttributeType(v: VertexAttribute): auto = get(genericParams(typeof(v)), 0) 23 template getAttributeType*(v: VertexAttribute): auto = get(genericParams(typeof(v)), 0)
15 24
16 func datasize*(attribute: VertexAttribute): uint64 = 25 func datasize*(attribute: VertexAttribute): uint64 =
17 uint64(sizeof(rawAttributeType(attribute))) * uint64(attribute.data.len) 26 uint64(sizeof(getAttributeType(attribute))) * uint64(attribute.data.len)
18 27
19 # from https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap15.html 28 # from https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap15.html
20 func nLocationSlots[T: VertexAttributeType](): int = 29 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]): 30 when (T is Vec3[float64] or T is Vec3[uint64] or T is Vec4[float64] or T is Vec4[float64]):
22 2 31 2
64 elif T is Vec4[uint64]: VK_FORMAT_R64G64B64A64_UINT 73 elif T is Vec4[uint64]: VK_FORMAT_R64G64B64A64_UINT
65 elif T is Vec4[int64]: VK_FORMAT_R64G64B64A64_SINT 74 elif T is Vec4[int64]: VK_FORMAT_R64G64B64A64_SINT
66 elif T is Vec4[float32]: VK_FORMAT_R32G32B32A32_SFLOAT 75 elif T is Vec4[float32]: VK_FORMAT_R32G32B32A32_SFLOAT
67 elif T is Vec4[float64]: VK_FORMAT_R64G64B64A64_SFLOAT 76 elif T is Vec4[float64]: VK_FORMAT_R64G64B64A64_SFLOAT
68 77
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"
95
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 78
118 79
119 func VertexCount*[T](t: T): uint32 = 80 func VertexCount*[T](t: T): uint32 =
120 for name, value in t.fieldPairs: 81 for name, value in t.fieldPairs:
121 when typeof(value) is VertexAttribute: 82 when typeof(value) is VertexAttribute:
122 if result == 0: 83 if result == 0:
123 result = uint32(value.data.len) 84 result = uint32(value.data.len)
124 else: 85 else:
125 assert result == uint32(value.data.len) 86 assert result == uint32(value.data.len)
126 87
127 func generateGLSLDeclarations*[T](): string = 88 func generateGLSLVertexDeclarations*[T](): string =
128 var stmtList: seq[string] 89 var stmtList: seq[string]
129 var i = 0 90 var i = 0
130 for name, value in T().fieldPairs: 91 for name, value in T().fieldPairs:
131 when typeof(value) is VertexAttribute: 92 when typeof(value) is VertexAttribute:
132 let glsltype = getGLSLType[rawAttributeType(value)]() 93 let glsltype = getGLSLType[getAttributeType(value)]()
133 let n = name 94 let n = name
134 stmtList.add(&"layout(location = {i}) in {glsltype} {n};") 95 stmtList.add(&"layout(location = {i}) in {glsltype} {n};")
135 i += nLocationSlots[rawAttributeType(value)]() 96 i += nLocationSlots[getAttributeType(value)]()
136 97
137 return stmtList.join("\n") 98 return stmtList.join("\n")
138 99
139 func generateInputVertexBinding*[T](bindingoffset: int = 0, locationoffset: int = 0): seq[VkVertexInputBindingDescription] = 100 func generateInputVertexBinding*[T](bindingoffset: int = 0, locationoffset: int = 0): seq[VkVertexInputBindingDescription] =
140 # packed attribute data, not interleaved (aks "struct of arrays") 101 # packed attribute data, not interleaved (aks "struct of arrays")
142 for name, value in T().fieldPairs: 103 for name, value in T().fieldPairs:
143 when typeof(value) is VertexAttribute: 104 when typeof(value) is VertexAttribute:
144 result.add( 105 result.add(
145 VkVertexInputBindingDescription( 106 VkVertexInputBindingDescription(
146 binding: uint32(binding), 107 binding: uint32(binding),
147 stride: uint32(sizeof(rawAttributeType(value))), 108 stride: uint32(sizeof(getAttributeType(value))),
148 inputRate: VK_VERTEX_INPUT_RATE_VERTEX, # VK_VERTEX_INPUT_RATE_INSTANCE for instances 109 inputRate: VK_VERTEX_INPUT_RATE_VERTEX, # VK_VERTEX_INPUT_RATE_INSTANCE for instances
149 ) 110 )
150 ) 111 )
151 binding += 1 112 binding += 1
152 113
158 when typeof(value) is VertexAttribute: 119 when typeof(value) is VertexAttribute:
159 result.add( 120 result.add(
160 VkVertexInputAttributeDescription( 121 VkVertexInputAttributeDescription(
161 binding: uint32(binding), 122 binding: uint32(binding),
162 location: uint32(location), 123 location: uint32(location),
163 format: getVkFormat[rawAttributeType(value)](), 124 format: getVkFormat[getAttributeType(value)](),
164 offset: 0, 125 offset: 0,
165 ) 126 )
166 ) 127 )
167 location += nLocationSlots[rawAttributeType(value)]() 128 location += nLocationSlots[getAttributeType(value)]()
168 binding += 1 129 binding += 1