Mercurial > games > semicongine
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) |