comparison src/zamikongine/mesh.nim @ 19:b55d6ecde79d

did: introduce scene graph, meshs and generic vertex buffers
author Sam <sam@basx.dev>
date Mon, 09 Jan 2023 11:04:19 +0700
parents
children beb86492b178
comparison
equal deleted inserted replaced
18:90e117952f74 19:b55d6ecde79d
1 import std/typetraits
2
3 import ./vulkan
4 import ./thing
5 import ./buffer
6 import ./vertex
7
8 type
9 Mesh*[T] = object of Part
10 vertexData*: T
11 IndexedMesh*[T: object, U: uint16|uint32] = object of Part
12 vertexData*: T
13 indices*: seq[array[3, U]]
14
15 func getVkIndexType[T: object, U: uint16|uint32](m: IndexedMesh[T, U]): VkIndexType =
16 when U is uint16: VK_INDEX_TYPE_UINT16
17 elif U is uint32: VK_INDEX_TYPE_UINT32
18
19 proc createVertexBuffers*[M: Mesh|IndexedMesh](
20 mesh: var M,
21 device: VkDevice,
22 physicalDevice: VkPhysicalDevice,
23 commandPool: VkCommandPool,
24 queue: VkQueue,
25 useDeviceLocalBuffer: bool = true # decides if data is transfered to the fast device-local memory or not
26 ): (seq[Buffer], uint32) =
27 result[1] = mesh.vertexData.VertexCount
28 for name, value in mesh.vertexData.fieldPairs:
29 when typeof(value) is VertexAttribute:
30 assert value.data.len > 0
31 var flags = if useDeviceLocalBuffer: {TransferSrc} else: {VertexBuffer}
32 var stagingBuffer = device.InitBuffer(physicalDevice, value.datasize, flags, {VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT})
33 var d: pointer
34 stagingBuffer.withMapping(d):
35 copyMem(d, addr(value.data[0]), value.datasize)
36
37 if useDeviceLocalBuffer:
38 var finalBuffer = device.InitBuffer(physicalDevice, value.datasize, {TransferDst, VertexBuffer}, {VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT})
39 copyBuffer(commandPool, queue, stagingBuffer, finalBuffer, value.datasize)
40 stagingBuffer.trash()
41 result[0].add(finalBuffer)
42 else:
43 result[0].add(stagingBuffer)
44
45 proc createIndexBuffer*(
46 mesh: var IndexedMesh,
47 device: VkDevice,
48 physicalDevice: VkPhysicalDevice,
49 commandPool: VkCommandPool,
50 queue: VkQueue,
51 useDeviceLocalBuffer: bool = true # decides if data is transfered to the fast device-local memory or not
52 ): Buffer =
53 let bufferSize = uint64(mesh.indices.len * sizeof(get(genericParams(typeof(mesh.indices)), 0)))
54 let flags = if useDeviceLocalBuffer: {TransferSrc} else: {IndexBuffer}
55
56 var stagingBuffer = device.InitBuffer(physicalDevice, bufferSize, flags, {VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT})
57 var d: pointer
58 stagingBuffer.withMapping(d):
59 copyMem(d, addr(mesh.indices[0]), bufferSize)
60
61 if useDeviceLocalBuffer:
62 var finalBuffer = device.InitBuffer(physicalDevice, bufferSize, {TransferDst, IndexBuffer}, {VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT})
63 copyBuffer(commandPool, queue, stagingBuffer, finalBuffer, bufferSize)
64 stagingBuffer.trash()
65 return finalBuffer
66 else:
67 return stagingBuffer
68
69 proc createIndexedVertexBuffers*(
70 mesh: var IndexedMesh,
71 device: VkDevice,
72 physicalDevice: VkPhysicalDevice,
73 commandPool: VkCommandPool,
74 queue: VkQueue,
75 useDeviceLocalBuffer: bool = true # decides if data is transfered to the fast device-local memory or not
76 ): (seq[Buffer], Buffer, uint32, VkIndexType) =
77 result[0] = createVertexBuffers(mesh, device, physicalDevice, commandPool, queue, useDeviceLocalBuffer)[0]
78 result[1] = createIndexBuffer(mesh, device, physicalDevice, commandPool, queue, useDeviceLocalBuffer)
79 result[2] = uint32(mesh.indices.len * mesh.indices[0].len)
80
81 result[3] = getVkIndexType(mesh)