summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-11-01 19:18:06 -0400
committerJonathan Bradley <jcb@pikum.xyz>2023-11-15 13:13:27 -0500
commit948d54c6833374682d2dd9442436b8c6400ae0f4 (patch)
tree2443759edbc9310af052e271caf8725f4380275d
parentea7ba25b9df7380caa9ee31a0b2bc33cf7219ad7 (diff)
use convex polyhedron for debug wireframe - buggy but functional
-rw-r--r--src/components.hpp10
-rw-r--r--src/entities.cpp281
-rw-r--r--src/entities.hpp1
-rw-r--r--src/window.cpp10
4 files changed, 268 insertions, 34 deletions
diff --git a/src/components.hpp b/src/components.hpp
index cd79e4b..0de9592 100644
--- a/src/components.hpp
+++ b/src/components.hpp
@@ -22,6 +22,12 @@ struct Entity {
bool isMarkedForRemoval = false;
};
+struct BufferBindingDetails {
+ VkBuffer buffer = VK_NULL_HANDLE;
+ uint32_t firstBinding = 0;
+ uint32_t bindingCount = 0;
+ VkDeviceSize offsets[1] = {0};
+};
struct CompGrBinds {
EntityHandle entHandle = EntityHandle_MAX;
GrBindsHandle grBindsHandle = GrBindsHandle_MAX;
@@ -44,6 +50,10 @@ struct CompGrBinds {
uint32_t indexBindingCount = 0;
VkDeviceSize indexOffsets = 0;
VkDeviceSize indexCount = 0;
+ BufferBindingDetails physVertBD;
+ BufferBindingDetails physNormBD;
+ BufferBindingDetails physUvBD;
+ BufferBindingDetails physIndxBD;
VkBuffer instanceBuffer = VK_NULL_HANDLE;
uint32_t instanceFirstBinding = 0;
uint32_t instanceBindingCount = 0;
diff --git a/src/entities.cpp b/src/entities.cpp
index bdd6709..23632c7 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -1,9 +1,12 @@
#include "entities.hpp"
+#include "math-helpers.hpp"
#include "physics.hpp"
+#include "window.hpp"
#include <BulletCollision/CollisionShapes/btConvexHullShape.h>
+#include <BulletCollision/CollisionShapes/btConvexPolyhedron.h>
#include <vulkan/vulkan_core.h>
DynArray<EntityType> GlobalEntityTypes{16};
@@ -33,6 +36,39 @@ int64_t EntityType_FindByEntityHandle(EntityHandle handle) {
return -1;
}
+void CalculateCombinedMemReqs(uint64_t memReqsCount, VkMemoryRequirements *memReqs, VkMemoryRequirements &combinedMemReqs) {
+ combinedMemReqs.alignment = memReqs[0].alignment;
+ combinedMemReqs.memoryTypeBits = memReqs[0].memoryTypeBits;
+ for (long i = 1; i < memReqsCount; ++i) {
+ combinedMemReqs.memoryTypeBits = memReqs[i].memoryTypeBits;
+ if (combinedMemReqs.alignment == memReqs[i].alignment) {
+ continue;
+ }
+ VkDeviceSize larger, smaller;
+ if (combinedMemReqs.alignment > memReqs[i].alignment) {
+ larger = combinedMemReqs.alignment;
+ smaller = memReqs[i].alignment;
+ } else {
+ larger = memReqs[i].alignment;
+ smaller = combinedMemReqs.alignment;
+ }
+ if (larger % smaller == 0) {
+ combinedMemReqs.alignment = larger;
+ continue;
+ }
+ int combined = larger * smaller;
+ while ((combined / 2) % 2 == 0 && (combined / 2) % larger == 0) {
+ combined /= 2;
+ }
+ combinedMemReqs.alignment = combined;
+ }
+ for (long i = 0; i < memReqsCount; ++i) {
+ uint32_t alignmentPadding = memReqs[i].size % combinedMemReqs.alignment;
+ memReqs[i].size += (alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding);
+ combinedMemReqs.size += memReqs[i].size;
+ }
+}
+
void EntityType_Load(EntityType &et) {
assert(et.startingInstanceCount > 0);
if (et.modelFile != nullptr && et.modelFile != CAFE_BABE(char)) {
@@ -435,33 +471,7 @@ void EntityType_Load(EntityType &et) {
combinedMemReqs.alignment = vkMemoryRequirements[0].alignment;
combinedMemReqs.memoryTypeBits = 0;
combinedMemReqs.size = 0;
- for (long i = 1; i < expectedBufferCount; ++i) {
- if (combinedMemReqs.alignment == vkMemoryRequirements[i].alignment) {
- continue;
- }
- int larger, smaller;
- if (combinedMemReqs.alignment > vkMemoryRequirements[i].alignment) {
- larger = combinedMemReqs.alignment;
- smaller = vkMemoryRequirements[i].alignment;
- } else {
- larger = vkMemoryRequirements[i].alignment;
- smaller = combinedMemReqs.alignment;
- }
- if (larger % smaller == 0) {
- combinedMemReqs.alignment = larger;
- continue;
- }
- int combined = larger * smaller;
- while ((combined / 2) % 2 == 0 && (combined / 2) % larger == 0) {
- combined /= 2;
- }
- combinedMemReqs.alignment = combined;
- }
- for (long i = 0; i < expectedBufferCount; ++i) {
- uint32_t alignmentPadding = vkMemoryRequirements[i].size % combinedMemReqs.alignment;
- combinedMemReqs.size += vkMemoryRequirements[i].size + (alignmentPadding == 0 ? 0 : combinedMemReqs.alignment - alignmentPadding);
- combinedMemReqs.memoryTypeBits |= vkMemoryRequirements[i].memoryTypeBits;
- }
+ CalculateCombinedMemReqs(expectedBufferCount, vkMemoryRequirements, combinedMemReqs);
// create VkDeviceMemory
VkMemoryAllocateInfo vkMemoryAllocateInfo;
@@ -614,11 +624,214 @@ void EntityType_Load(EntityType &et) {
vkBindBufferMemory(vkDevice, grBinds.instanceBuffer, et.deviceMemoryInst, 0);
// bullet
+ btConvexHullShape *shape;
{
- et.bt.shape = Pke_New<btConvexHullShape>(MemBkt_Bullet);
+ shape = Pke_New<btConvexHullShape>(MemBkt_Bullet);
btScalar *vertDataPointer = reinterpret_cast<btScalar *>(accVert.buffer_view->buffer->data);
vertDataPointer += accVert.buffer_view->offset;
- new (et.bt.shape) btConvexHullShape(vertDataPointer, accVert.count, accVert.stride);
+ new (shape) btConvexHullShape(vertDataPointer, accVert.count, accVert.stride);
+ shape->initializePolyhedralFeatures();
+ shape->optimizeConvexHull();
+ et.bt.shape = shape;
+ }
+ assert(shape != nullptr);
+
+ // set up convex hull debug
+ {
+ const btConvexPolyhedron *pol = shape->getConvexPolyhedron();
+ DynArray<glm::vec3> vertexes{pol->m_vertices.size(), MemBkt_Bullet};
+ DynArray<glm::vec3> normals{pol->m_vertices.size(), MemBkt_Bullet};
+ DynArray<glm::vec2> uv{pol->m_vertices.size(), MemBkt_Bullet};
+ DynArray<uint16_t> indexes{pol->m_faces.size() * 6, MemBkt_Bullet};
+ for (long i = 0; i < pol->m_vertices.size(); ++i) {
+ btVector3 norm = pol->m_vertices[i];
+ auto &glmVert = vertexes.Push();
+ BulletToGlm(norm, glmVert);
+ norm.safeNormalize();
+ auto &glmNorm = normals.Push();
+ BulletToGlm(norm, glmNorm);
+ uv.Push({norm.x(), norm.y()});
+ }
+ for (long i = 0; i < pol->m_faces.size(); ++i) {
+ for (long k = 2; k < pol->m_faces[i].m_indices.size(); ++k) {
+ indexes.Push(pol->m_faces[i].m_indices[0]);
+ indexes.Push(pol->m_faces[i].m_indices[k - 1]);
+ indexes.Push(pol->m_faces[i].m_indices[k]);
+ }
+ }
+
+ VkBufferCreateInfo physBufferCI;
+ physBufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ physBufferCI.pNext = nullptr;
+ physBufferCI.flags = {};
+ physBufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ physBufferCI.queueFamilyIndexCount = 1;
+ physBufferCI.pQueueFamilyIndices = &graphicsFamilyIndex;
+
+ VkMemoryRequirements memReqs[4];
+
+ // vertex
+ index = 0;
+ physBufferCI.size = sizeof(glm::vec3) * vertexes.Count();
+ physBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physVertBD.buffer);
+ vkGetBufferMemoryRequirements(vkDevice, grBinds.physVertBD.buffer, &memReqs[index]);
+ if (memReqs[index].size != physBufferCI.size) {
+ vkDestroyBuffer(vkDevice, grBinds.physVertBD.buffer, vkAllocator);
+ physBufferCI.size = memReqs[index].size;
+ vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physVertBD.buffer);
+ }
+ grBinds.physVertBD.bindingCount = vertexes.Count();
+ grBinds.physVertBD.firstBinding = index;
+
+ // norm
+ index = 1;
+ physBufferCI.size = sizeof(glm::vec3) * normals.Count();
+ physBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physNormBD.buffer);
+ vkGetBufferMemoryRequirements(vkDevice, grBinds.physNormBD.buffer, &memReqs[index]);
+ if (memReqs[index].size != physBufferCI.size) {
+ vkDestroyBuffer(vkDevice, grBinds.physNormBD.buffer, vkAllocator);
+ physBufferCI.size = memReqs[index].size;
+ vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physNormBD.buffer);
+ }
+ grBinds.physNormBD.bindingCount = normals.Count();
+ grBinds.physNormBD.firstBinding = index;
+
+ // uv
+ index = 2;
+ physBufferCI.size = sizeof(glm::vec2) * uv.Count();
+ physBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physUvBD.buffer);
+ vkGetBufferMemoryRequirements(vkDevice, grBinds.physUvBD.buffer, &memReqs[index]);
+ if (memReqs[index].size != physBufferCI.size) {
+ vkDestroyBuffer(vkDevice, grBinds.physUvBD.buffer, vkAllocator);
+ physBufferCI.size = memReqs[index].size;
+ vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physUvBD.buffer);
+ }
+ grBinds.physUvBD.bindingCount = uv.Count();
+ grBinds.physUvBD.firstBinding = index;
+
+ // index
+ index = 3;
+ physBufferCI.size = sizeof(glm::vec2) * uv.Count();
+ physBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physIndxBD.buffer);
+ vkGetBufferMemoryRequirements(vkDevice, grBinds.physIndxBD.buffer, &memReqs[index]);
+ if (memReqs[index].size != physBufferCI.size) {
+ vkDestroyBuffer(vkDevice, grBinds.physIndxBD.buffer, vkAllocator);
+ physBufferCI.size = memReqs[index].size;
+ vkCreateBuffer(vkDevice, &physBufferCI, vkAllocator, &grBinds.physIndxBD.buffer);
+ }
+ grBinds.physIndxBD.bindingCount = indexes.Count();
+ // grBinds.physIndxBD.firstBinding = index;
+
+ CalculateCombinedMemReqs(4, memReqs, combinedMemReqs);
+
+ // allocate memory
+ VkMemoryAllocateInfo physVertMemAI;
+ physVertMemAI.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ physVertMemAI.pNext = nullptr;
+ physVertMemAI.allocationSize = combinedMemReqs.size;
+ physVertMemAI.memoryTypeIndex = combinedMemReqs.memoryTypeBits;
+ physVertMemAI.memoryTypeIndex = FindMemoryTypeIndex(combinedMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+ vkAllocateMemory(vkDevice, &physVertMemAI, vkAllocator, &et.deviceMemoryPhysVert);
+
+ runningOffset = 0;
+ vkBindBufferMemory(vkDevice, grBinds.physVertBD.buffer, et.deviceMemoryPhysVert, runningOffset);
+ runningOffset += memReqs[0].size;
+ vkBindBufferMemory(vkDevice, grBinds.physNormBD.buffer, et.deviceMemoryPhysVert, runningOffset);
+ runningOffset += memReqs[1].size;
+ vkBindBufferMemory(vkDevice, grBinds.physUvBD.buffer, et.deviceMemoryPhysVert, runningOffset);
+ runningOffset += memReqs[2].size;
+ vkBindBufferMemory(vkDevice, grBinds.physIndxBD.buffer, et.deviceMemoryPhysVert, runningOffset);
+
+ // create transfer items && transfer
+ {
+ VkDeviceMemory transferDeviceMemory;
+ VkBuffer transferBuffer;
+ void *data;
+ BeginTransferBuffer(combinedMemReqs.size, transferBuffer, transferDeviceMemory, data);
+ memset(data, '\0', combinedMemReqs.size);
+ runningOffset = 0;
+
+ char *dstPtr = nullptr;
+ char *srcPtr = nullptr;
+
+ dstPtr = static_cast<char *>(data) + runningOffset;
+ srcPtr = reinterpret_cast<char *>(vertexes.GetPtr());
+ memcpy(dstPtr, srcPtr, sizeof(glm::vec3) * vertexes.Count());
+ runningOffset += memReqs[0].size;
+
+ dstPtr = static_cast<char *>(data) + runningOffset;
+ srcPtr = reinterpret_cast<char *>(normals.GetPtr());
+ memcpy(dstPtr, srcPtr, sizeof(glm::vec3) * normals.Count());
+ runningOffset += memReqs[1].size;
+
+ dstPtr = static_cast<char *>(data) + runningOffset;
+ srcPtr = reinterpret_cast<char *>(uv.GetPtr());
+ memcpy(dstPtr, srcPtr, sizeof(glm::vec2) * uv.Count());
+ runningOffset += memReqs[2].size;
+
+ dstPtr = static_cast<char *>(data) + runningOffset;
+ srcPtr = reinterpret_cast<char *>(indexes.GetPtr());
+ memcpy(dstPtr, srcPtr, sizeof(uint16_t) * indexes.Count());
+
+ 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[expectedBufferCount];
+ for (long i = 0; i < expectedBufferCount; ++i) {
+ bufferCopys[i].dstOffset = 0;
+ }
+ index = 0;
+ runningOffset = 0;
+ bufferCopys[index].srcOffset = runningOffset;
+ bufferCopys[index].size = memReqs[index].size;
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.physVertBD.buffer, 1, &bufferCopys[index]);
+ runningOffset += memReqs[index].size;
+ index+=1;
+
+ bufferCopys[index].srcOffset = runningOffset;
+ bufferCopys[index].size = memReqs[index].size;
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.physNormBD.buffer, 1, &bufferCopys[index]);
+ runningOffset += memReqs[index].size;
+ index+=1;
+
+ bufferCopys[index].srcOffset = runningOffset;
+ bufferCopys[index].size = memReqs[index].size;
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.physUvBD.buffer, 1, &bufferCopys[index]);
+ runningOffset += memReqs[index].size;
+ index+=1;
+
+ bufferCopys[index].srcOffset = runningOffset;
+ bufferCopys[index].size = memReqs[index].size;
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.physIndxBD.buffer, 1, &bufferCopys[index]);
+ // runningOffset += memReqs[index].size;
+ // index+=1;
+
+ 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);
+
+ EndTransferBuffer(transferBuffer, transferDeviceMemory);
+ }
}
// cleanup
@@ -756,6 +969,14 @@ void EntityType_Teardown() {
vkDestroyBuffer(vkDevice, grBinds->uvBuffer, vkAllocator);
if (grBinds->indexBuffer != VK_NULL_HANDLE)
vkDestroyBuffer(vkDevice, grBinds->indexBuffer, vkAllocator);
+ if (grBinds->physVertBD.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, grBinds->physVertBD.buffer, vkAllocator);
+ if (grBinds->physNormBD.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, grBinds->physNormBD.buffer, vkAllocator);
+ if (grBinds->physUvBD.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, grBinds->physUvBD.buffer, vkAllocator);
+ if (grBinds->physIndxBD.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, grBinds->physIndxBD.buffer, vkAllocator);
if (grBinds->instanceBuffer != VK_NULL_HANDLE)
vkDestroyBuffer(vkDevice, grBinds->instanceBuffer, vkAllocator);
@@ -767,6 +988,8 @@ void EntityType_Teardown() {
vkFreeMemory(vkDevice, et->deviceMemoryInst, vkAllocator);
if (et->deviceMemoryVert != VK_NULL_HANDLE)
vkFreeMemory(vkDevice, et->deviceMemoryVert, vkAllocator);
+ if (et->deviceMemoryPhysVert != VK_NULL_HANDLE)
+ vkFreeMemory(vkDevice, et->deviceMemoryPhysVert, vkAllocator);
if (et->deviceMemoryTexture != VK_NULL_HANDLE)
vkFreeMemory(vkDevice, et->deviceMemoryTexture, vkAllocator);
if (et->modelsDir)
diff --git a/src/entities.hpp b/src/entities.hpp
index e16097c..522fe68 100644
--- a/src/entities.hpp
+++ b/src/entities.hpp
@@ -20,6 +20,7 @@ struct EntityType {
GrBindsHandle grBindsHandle = GrBindsHandle_MAX;
VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE;
VkDeviceMemory deviceMemoryInst = VK_NULL_HANDLE;
+ VkDeviceMemory deviceMemoryPhysVert = VK_NULL_HANDLE;
VkDeviceMemory deviceMemoryTexture = VK_NULL_HANDLE;
VkImage textureImage = VK_NULL_HANDLE;
VkImageView textureImageView = VK_NULL_HANDLE;
diff --git a/src/window.cpp b/src/window.cpp
index 4c6b598..bb83b32 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -2294,13 +2294,13 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
if (pkeSettings.isRenderingDebug) {
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.TextureWireframe);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.vkPipelineLayout_Texture, 0, 1, &pkeDebugHitbox.vkDescriptorSets[imageIndex], 0, {});
- vkCmdBindIndexBuffer(commandBuffer, pkeDebugHitbox.indexBuffer, 0, VK_INDEX_TYPE_UINT16);
- vkCmdBindVertexBuffers(commandBuffer, 0, 1, &pkeDebugHitbox.vertexBuffer, offsets);
- vkCmdBindVertexBuffers(commandBuffer, 1, 1, &pkeDebugHitbox.normalsBuffer, offsets);
- vkCmdBindVertexBuffers(commandBuffer, 2, 1, &pkeDebugHitbox.uvBuffer, offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physVertBD.firstBinding, 1, &binder->physVertBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physNormBD.firstBinding, 1, &binder->physNormBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physUvBD.firstBinding, 1, &binder->physUvBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindIndexBuffer(commandBuffer, binder->physIndxBD.buffer, binder->physIndxBD.offsets[0], VK_INDEX_TYPE_UINT16);
- vkCmdDrawIndexed(commandBuffer, 36, binder->instanceCounter, 0, 0, 0);
+ vkCmdDrawIndexed(commandBuffer, binder->physIndxBD.bindingCount, binder->instanceCounter, 0, 0, 0);
}
}
}