diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-09-12 14:31:09 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-09-12 14:31:09 -0400 |
| commit | b4ba9eb4f1fe02d65945a263beb3185a617a414b (patch) | |
| tree | bc53bafd81c989b555792171eb9c505f08984aff | |
| parent | e6d5d4ff0dd3d3640860c23034955ff6db149827 (diff) | |
load gltf files - no shaders yet
| -rw-r--r-- | assets/models/cube.bin | bin | 0 -> 840 bytes | |||
| -rw-r--r-- | assets/models/cube.gltf | 121 | ||||
| -rw-r--r-- | src/components.hpp | 18 | ||||
| -rw-r--r-- | src/ecs.cpp | 2 | ||||
| -rw-r--r-- | src/entities.cpp | 238 | ||||
| -rw-r--r-- | src/entities.hpp | 11 | ||||
| -rw-r--r-- | src/window.cpp | 12 |
7 files changed, 374 insertions, 28 deletions
diff --git a/assets/models/cube.bin b/assets/models/cube.bin Binary files differnew file mode 100644 index 0000000..c59221c --- /dev/null +++ b/assets/models/cube.bin diff --git a/assets/models/cube.gltf b/assets/models/cube.gltf new file mode 100644 index 0000000..5077394 --- /dev/null +++ b/assets/models/cube.gltf @@ -0,0 +1,121 @@ +{ + "asset":{ + "generator":"Khronos glTF Blender I/O v3.6.27", + "version":"2.0" + }, + "scene":0, + "scenes":[ + { + "name":"Scene", + "nodes":[ + 0 + ] + } + ], + "nodes":[ + { + "mesh":0, + "name":"Cube" + } + ], + "materials":[ + { + "doubleSided":true, + "name":"Material", + "pbrMetallicRoughness":{ + "baseColorFactor":[ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1 + ], + "metallicFactor":0, + "roughnessFactor":0.5 + } + } + ], + "meshes":[ + { + "name":"Cube", + "primitives":[ + { + "attributes":{ + "POSITION":0, + "NORMAL":1, + "TEXCOORD_0":2 + }, + "indices":3, + "material":0 + } + ] + } + ], + "accessors":[ + { + "bufferView":0, + "componentType":5126, + "count":24, + "max":[ + 1, + 1, + 1 + ], + "min":[ + -1, + -1, + -1 + ], + "type":"VEC3" + }, + { + "bufferView":1, + "componentType":5126, + "count":24, + "type":"VEC3" + }, + { + "bufferView":2, + "componentType":5126, + "count":24, + "type":"VEC2" + }, + { + "bufferView":3, + "componentType":5123, + "count":36, + "type":"SCALAR" + } + ], + "bufferViews":[ + { + "buffer":0, + "byteLength":288, + "byteOffset":0, + "target":34962 + }, + { + "buffer":0, + "byteLength":288, + "byteOffset":288, + "target":34962 + }, + { + "buffer":0, + "byteLength":192, + "byteOffset":576, + "target":34962 + }, + { + "buffer":0, + "byteLength":72, + "byteOffset":768, + "target":34963 + } + ], + "buffers":[ + { + "byteLength":840, + "uri":"cube.bin" + } + ] +} diff --git a/src/components.hpp b/src/components.hpp index 4ea4db2..ce5f0f2 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -22,11 +22,6 @@ struct Entity { bool isMarkedForRemoval = false; }; -struct Vert { - glm::vec3 pos; - glm::vec2 tex; -}; - struct InstPos { glm::vec3 pos; glm::vec3 rot; @@ -36,17 +31,24 @@ struct InstPos { struct CompGrBinds { EntityHandle entHandle = EntityHandle_MAX; GrBindsHandle grBindsHandle = GrBindsHandle_MAX; - VkDeviceMemory deviceMemory = VK_NULL_HANDLE; + VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE; + VkDeviceMemory deviceMemoryInst = VK_NULL_HANDLE; VkBuffer vertexBuffer = VK_NULL_HANDLE; uint32_t vertexFirstBinding = 0; uint32_t vertexCount = 0; VkDeviceSize vertexOffsets = 0; - DynArray<Vert> vertexes{0}; + VkBuffer normalsBuffer = VK_NULL_HANDLE; + uint32_t normalsFirstBinding = 0; + uint32_t normalsCount = 0; + VkDeviceSize normalsOffsets = 0; + VkBuffer uvBuffer = VK_NULL_HANDLE; + uint32_t uvFirstBinding = 0; + uint32_t uvCount = 0; + VkDeviceSize uvOffsets = 0; VkBuffer indexBuffer = VK_NULL_HANDLE; uint32_t indexFirstBinding = 0; uint32_t indexCount = 0; VkDeviceSize indexOffsets = 0; - DynArray<uint16_t> indexes{0}; VkBuffer instanceBuffer = VK_NULL_HANDLE; uint32_t instanceFirstBinding = 0; uint32_t instanceCount = 0; diff --git a/src/ecs.cpp b/src/ecs.cpp index 387b8b6..1fae912 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -143,8 +143,6 @@ void ECS_Tick(double delta) { * pipeline layout, and descriptor set) are unloaded elsewhere, just, * as they were created elsewhere. */ - DynArrayDestroy(&grBinds->vertexes); - DynArrayDestroy(&grBinds->indexes); DynArrayDestroy(&grBinds->instances); } } diff --git a/src/entities.cpp b/src/entities.cpp index 2887074..75b56f4 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -1,19 +1,40 @@ #include "entities.hpp" -#include "ecs.hpp" -#include <vulkan/vulkan_core.h> -void EntityType_Init() {} +DynArray<EntityType> globalEntityTypes{16}; + +void EntityType_Init() { + globalEntityTypes.Push( + EntityType { + .modelFile = "assets/models/cube.gltf", + .entityTypeCode = "EntTypeCube", + .entityHandle = ECS_CreateEntity(), + .startingInstanceCount = 16, + .Importer_GLTF = { + .AccessorIndexVertex = 0, + .AccessorIndexNormal = 1, + .AccessorIndexUV = 2, + .AccessorIndexIndex = 3, + } + } + ); + + long entityTypeCount = globalEntityTypes.Count(); + for (long i = 0; i < entityTypeCount; ++i) { + EntityType_Load(globalEntityTypes[i]); + } +} void EntityType_Load(EntityType &et) { + assert(et.startingInstanceCount > 0); if (et.modelFile != nullptr && et.modelFile != CAFE_BABE(char)) { - assert(et.vkPipelineLayoutCreateInfo != nullptr && et.vkPipelineLayoutCreateInfo != CAFE_BABE(VkPipelineLayoutCreateInfo) && "EntityType with a defined model must also contain appropriate Vulkan CreateInfos"); + // assert(et.vkPipelineLayoutCreateInfo != nullptr && et.vkPipelineLayoutCreateInfo != CAFE_BABE(VkPipelineLayoutCreateInfo) && "EntityType with a defined model must also contain appropriate Vulkan CreateInfos"); AssetHandle assetHandle{AM_Register(et.modelFile)}; const Asset *asset = AM_Get(assetHandle); CompGrBinds &grBinds = ECS_CreateGrBinds(et.entityHandle); - auto vkResult = vkCreatePipelineLayout(vkDevice, et.vkPipelineLayoutCreateInfo, vkAllocator, &grBinds.vkPipelineLayout); - assert(vkResult == VK_SUCCESS); + // auto vkResult = vkCreatePipelineLayout(vkDevice, et.vkPipelineLayoutCreateInfo, vkAllocator, &grBinds.vkPipelineLayout); + // assert(vkResult == VK_SUCCESS); // TODO grBinds.vkDescriptorSet cgltf_options options{}; @@ -21,22 +42,198 @@ void EntityType_Load(EntityType &et) { cgltf_data *gltfData = nullptr; cgltf_result result = cgltf_parse(&options, asset->ptr, asset->size, &gltfData); assert(result == cgltf_result_success); + // TODO consider using AssetHandler OR loading this directly to the GPU + result = cgltf_load_buffers(&options, gltfData, et.modelFile); + assert(result == cgltf_result_success); result = cgltf_validate(gltfData); assert(result == cgltf_result_success); - // create buffers - // TODO + // make sure cgltf can interpret our model + for (long i = 0; i < gltfData->accessors_count; ++i) { + assert(gltfData->accessors[i].type != cgltf_type_invalid); + } + for (long i = 0; i < gltfData->buffers_count; ++i) { + assert(gltfData->buffer_views[i].type != cgltf_buffer_view_type_invalid); + } + assert(et.Importer_GLTF.AccessorIndexVertex > -1); + + VkBufferCreateInfo bufferCI; + bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferCI.pNext = nullptr; + bufferCI.flags = {}; + bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + bufferCI.queueFamilyIndexCount = 1; + bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex; + + VkMemoryRequirements vkMemoryRequirements; + + if (et.Importer_GLTF.AccessorIndexVertex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; + grBinds.vertexCount = acc.count; + bufferCI.size = acc.buffer_view->size; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.vertexBuffer); + + vkGetBufferMemoryRequirements(vkDevice, grBinds.vertexBuffer, &vkMemoryRequirements); + } + if (et.Importer_GLTF.AccessorIndexNormal > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; + grBinds.normalsCount = acc.count; + bufferCI.size = acc.buffer_view->size; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.normalsBuffer); + + VkMemoryRequirements vkMemoryRequirementsNormals; + vkGetBufferMemoryRequirements(vkDevice, grBinds.normalsBuffer, &vkMemoryRequirementsNormals); + vkMemoryRequirements.memoryTypeBits |= vkMemoryRequirementsNormals.memoryTypeBits; + vkMemoryRequirements.size += vkMemoryRequirementsNormals.size; + assert(vkMemoryRequirementsNormals.alignment == vkMemoryRequirements.alignment); + } + if (et.Importer_GLTF.AccessorIndexUV > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; + grBinds.uvCount = acc.count; + bufferCI.size = acc.buffer_view->size; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.uvBuffer); + + VkMemoryRequirements vkMemoryRequirementsUV; + vkGetBufferMemoryRequirements(vkDevice, grBinds.uvBuffer, &vkMemoryRequirementsUV); + vkMemoryRequirements.memoryTypeBits |= vkMemoryRequirementsUV.memoryTypeBits; + vkMemoryRequirements.size += vkMemoryRequirementsUV.size; + assert(vkMemoryRequirementsUV.alignment == vkMemoryRequirements.alignment); + } + if (et.Importer_GLTF.AccessorIndexIndex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; + grBinds.indexCount = acc.count; + bufferCI.size = acc.buffer_view->size; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.indexBuffer); + + VkMemoryRequirements vkMemoryRequirementsIndex; + vkGetBufferMemoryRequirements(vkDevice, grBinds.indexBuffer, &vkMemoryRequirementsIndex); + vkMemoryRequirements.memoryTypeBits |= vkMemoryRequirementsIndex.memoryTypeBits; + vkMemoryRequirements.size += vkMemoryRequirementsIndex.size; + assert(vkMemoryRequirementsIndex.alignment == vkMemoryRequirements.alignment); + } // create VkDeviceMemory VkMemoryAllocateInfo vkMemoryAllocateInfo; vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; vkMemoryAllocateInfo.pNext = nullptr; - vkMemoryAllocateInfo.allocationSize = gltfData->buffers[0].size;; - vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(0, 0); // TODO + vkMemoryAllocateInfo.allocationSize = vkMemoryRequirements.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &grBinds.deviceMemoryVert); + + // bind buffers + if (et.Importer_GLTF.AccessorIndexVertex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; + assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); + vkBindBufferMemory(vkDevice, grBinds.vertexBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + } + if (et.Importer_GLTF.AccessorIndexNormal > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; + assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); + vkBindBufferMemory(vkDevice, grBinds.normalsBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + } + if (et.Importer_GLTF.AccessorIndexUV > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; + assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); + vkBindBufferMemory(vkDevice, grBinds.uvBuffer , grBinds.deviceMemoryVert, acc.buffer_view->offset); + } + if (et.Importer_GLTF.AccessorIndexIndex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; + assert(acc.buffer_view->offset % vkMemoryRequirements.alignment == 0); + vkBindBufferMemory(vkDevice, grBinds.indexBuffer, grBinds.deviceMemoryVert, acc.buffer_view->offset); + } + + // create transfer items && transfer + { + // reminder that we don't need to do instance here, because we're just + // setting up the type. No instances have been created yet. + VkDeviceMemory transferDeviceMemory; + VkBuffer transferBuffer; + VkMemoryRequirements vkMemoryRequirementsTransfer; + + bufferCI.size = vkMemoryRequirements.size; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &transferBuffer); + vkGetBufferMemoryRequirements(vkDevice, transferBuffer, &vkMemoryRequirementsTransfer); + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemoryRequirementsTransfer.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + // note, this should be identical (other than memory type) to the dst buffer + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &transferDeviceMemory); + vkBindBufferMemory(vkDevice, transferBuffer, transferDeviceMemory, 0); + void *data; + vkMapMemory(vkDevice, transferDeviceMemory, 0, gltfData->buffers[0].size, 0, &data); + memcpy(data, gltfData->buffers[0].data, gltfData->buffers[0].size); + vkUnmapMemory(vkDevice, transferDeviceMemory); + + VkCommandBufferBeginInfo vkCommandBufferBeginInfo; + vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + vkCommandBufferBeginInfo.pNext = nullptr; + // TODO consider single-use? + vkCommandBufferBeginInfo.flags = 0; + vkCommandBufferBeginInfo.pInheritanceInfo = nullptr; + vkBeginCommandBuffer(transferCommandBuffer, &vkCommandBufferBeginInfo); + VkBufferCopy bufferCopys[4]; + for (long i = 0; i < 4; ++i) { + bufferCopys[i].dstOffset = 0; + } + long index = 0; + if (et.Importer_GLTF.AccessorIndexVertex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexVertex]; + bufferCopys[index].srcOffset = acc.buffer_view->offset; + bufferCopys[index].size = acc.buffer_view->size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.vertexBuffer, 1, &bufferCopys[index]); + index += 1; + } + if (et.Importer_GLTF.AccessorIndexNormal > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexNormal]; + bufferCopys[index].srcOffset = acc.buffer_view->offset; + bufferCopys[index].size = acc.buffer_view->size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.normalsBuffer, 1, &bufferCopys[index]); + index += 1; + } + if (et.Importer_GLTF.AccessorIndexUV > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexUV]; + bufferCopys[index].srcOffset = acc.buffer_view->offset; + bufferCopys[index].size = acc.buffer_view->size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.uvBuffer, 1, &bufferCopys[index]); + index += 1; + } + if (et.Importer_GLTF.AccessorIndexIndex > -1) { + const auto &acc = gltfData->accessors[et.Importer_GLTF.AccessorIndexIndex]; + bufferCopys[index].srcOffset = acc.buffer_view->offset; + bufferCopys[index].size = acc.buffer_view->size; + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.indexBuffer, 1, &bufferCopys[index]); + } + + vkEndCommandBuffer(transferCommandBuffer); + + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.pNext = nullptr; + submitInfo.waitSemaphoreCount = 0; + submitInfo.pWaitSemaphores = nullptr; + submitInfo.pWaitDstStageMask = nullptr; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &transferCommandBuffer; + submitInfo.signalSemaphoreCount = 0; + submitInfo.pSignalSemaphores = nullptr; + vkQueueSubmit(transferQueue, 1, &submitInfo, nullptr); + vkQueueWaitIdle(transferQueue); - vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &grBinds.deviceMemory); + vkDestroyBuffer(vkDevice, transferBuffer, vkAllocator); + vkFreeMemory(vkDevice, transferDeviceMemory, vkAllocator); + } - // TODO bind buffers to memory + // set up instance buffer + bufferCI.size = sizeof(InstPos) * et.startingInstanceCount; + bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &grBinds.instanceBuffer); + VkMemoryRequirements vkMemoryRequirementsInst; + vkGetBufferMemoryRequirements(vkDevice, grBinds.instanceBuffer, &vkMemoryRequirementsInst); + vkMemoryAllocateInfo.allocationSize = vkMemoryRequirementsInst.size; + vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemoryRequirementsInst.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &grBinds.deviceMemoryInst); + vkBindBufferMemory(vkDevice, grBinds.instanceBuffer, grBinds.deviceMemoryInst, 0); // cleanup cgltf_free(gltfData); @@ -49,8 +246,19 @@ void EntityType_Teardown() { if (globalEntityTypes[i].modelFile == nullptr) continue; auto *grBinds = ECS_GetGrBinds(globalEntityTypes[i].entityHandle); vkDestroyPipelineLayout(vkDevice, grBinds->vkPipelineLayout, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); - vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); + if (grBinds->vertexBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); + if (grBinds->normalsBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->normalsBuffer, vkAllocator); + if (grBinds->uvBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->uvBuffer, vkAllocator); + if (grBinds->indexBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->indexBuffer, vkAllocator); + if (grBinds->instanceBuffer != VK_NULL_HANDLE) + vkDestroyBuffer(vkDevice, grBinds->instanceBuffer, vkAllocator); + if (grBinds->deviceMemoryInst != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, grBinds->deviceMemoryInst, vkAllocator); + if (grBinds->deviceMemoryVert != VK_NULL_HANDLE) + vkFreeMemory(vkDevice, grBinds->deviceMemoryVert, vkAllocator); } } diff --git a/src/entities.hpp b/src/entities.hpp index 005c83c..53fe0d9 100644 --- a/src/entities.hpp +++ b/src/entities.hpp @@ -8,15 +8,24 @@ #include "memory.hpp" #include "window.hpp" +#include <vulkan/vulkan_core.h> + struct EntityType { const char *modelFile = nullptr; const char *entityTypeCode = nullptr; EntityHandle entityHandle = EntityHandle_MAX; VkPipelineLayoutCreateInfo *vkPipelineLayoutCreateInfo = nullptr; + uint32_t startingInstanceCount = 1024; + struct Importer_GLTF { + int16_t AccessorIndexVertex = -1; + int16_t AccessorIndexNormal = -1; + int16_t AccessorIndexUV = -1; + int16_t AccessorIndexIndex = -1; + } Importer_GLTF; }; void EntityType_Init(); -void EntityType_Load(EntityType et); +void EntityType_Load(EntityType &et); void EntityType_Teardown(); #endif /* PKE_ENTITIES_HPP */ diff --git a/src/window.cpp b/src/window.cpp index d8328b5..443fdea 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1019,9 +1019,17 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { for (long i = 0; i < itemCount; ++i) { CompGrBinds *binder = &items[i]; vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->vkPipelineLayout, 0U, 1U, &binder->vkDescriptorSet, 0, {}); - vkCmdBindVertexBuffers(commandBuffer, binder->indexFirstBinding, binder->vertexCount, &binder->vertexBuffer, &binder->vertexOffsets); - vkCmdBindIndexBuffer(commandBuffer, binder->indexBuffer, binder->vertexOffsets, VK_INDEX_TYPE_UINT16); + vkCmdBindVertexBuffers(commandBuffer, binder->vertexFirstBinding, binder->vertexCount, &binder->vertexBuffer, &binder->vertexOffsets); + if (binder->normalsCount > 0) + vkCmdBindVertexBuffers(commandBuffer, binder->normalsFirstBinding, binder->normalsCount, &binder->normalsBuffer, &binder->normalsOffsets); + if (binder->uvCount > 0) + vkCmdBindVertexBuffers(commandBuffer, binder->uvFirstBinding, binder->uvCount, &binder->uvBuffer, &binder->uvOffsets); + if (binder->indexCount > 0) + vkCmdBindIndexBuffer(commandBuffer, binder->indexBuffer, binder->vertexOffsets, VK_INDEX_TYPE_UINT16); + vkCmdBindVertexBuffers(commandBuffer, binder->indexFirstBinding, binder->instanceCount, &binder->instanceBuffer, &binder->instanceOffsets); + + vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instanceCount, 0, 0, 0); } } |
