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) |
