parent
cb8ee6a962
commit
8be5d3059f
17 changed files with 365 additions and 377 deletions
@ -1,54 +0,0 @@ |
|||||||
#pragma once |
|
||||||
|
|
||||||
#include "application.hpp" |
|
||||||
#include "constraints.hpp" |
|
||||||
#include <glm/vec3.hpp> |
|
||||||
|
|
||||||
class SoftBody; |
|
||||||
class Buffer; |
|
||||||
|
|
||||||
class Simulation : public Application { |
|
||||||
public: |
|
||||||
Simulation(); |
|
||||||
~Simulation(); |
|
||||||
private: |
|
||||||
unique_ptr<Buffer> vertexBuffer; |
|
||||||
unique_ptr<Buffer> faceBuffer; |
|
||||||
unique_ptr<Buffer> edgeBuffer; |
|
||||||
unique_ptr<Buffer> triangleBuffer; |
|
||||||
unique_ptr<Buffer> tetrahedronBuffer; |
|
||||||
void createMeshBuffers(); |
|
||||||
|
|
||||||
struct SizeInformation { |
|
||||||
uint32_t vertexCount; |
|
||||||
uint32_t faceCount; |
|
||||||
uint32_t edgeCount; |
|
||||||
uint32_t triangleCount; |
|
||||||
uint32_t tetrahedronCount; |
|
||||||
}; |
|
||||||
unique_ptr<Buffer> sizeInformationBuffer; |
|
||||||
|
|
||||||
struct Properties { |
|
||||||
glm::vec3 gravity; |
|
||||||
float dt; |
|
||||||
uint32_t k; |
|
||||||
}; |
|
||||||
unique_ptr<Buffer> propertiesBuffer; |
|
||||||
Properties properties {}; |
|
||||||
|
|
||||||
struct PBDPushData { |
|
||||||
uint32_t state; |
|
||||||
ConstraintData::Partition edgePartition; |
|
||||||
ConstraintData::Partition tetrahedronPartition; |
|
||||||
}; |
|
||||||
|
|
||||||
ConstraintData constraintData {}; |
|
||||||
|
|
||||||
unique_ptr<ComputePipeline> pbdPipeline; |
|
||||||
unique_ptr<ComputePipeline> normalPipeline; |
|
||||||
void createComputePipelines(); |
|
||||||
|
|
||||||
vector<unique_ptr<SoftBody>> softBodies; |
|
||||||
void recordDrawCommands() override; |
|
||||||
void recordComputeCommands(VkCommandBuffer cmdBuffer) override; |
|
||||||
}; |
|
@ -1,8 +1,10 @@ |
|||||||
#include "simulation.hpp" |
#include "application.hpp" |
||||||
|
#include "vulkan/instance.hpp" |
||||||
#include <thread> |
#include "input.hpp" |
||||||
|
|
||||||
int main() { |
int main() { |
||||||
Simulation simulation; |
Instance instance; |
||||||
simulation.mainLoop(); |
Input input(Instance::instance->window); |
||||||
|
Application application; |
||||||
|
application.mainLoop(); |
||||||
} |
} |
||||||
|
@ -1,205 +0,0 @@ |
|||||||
#include "application.hpp" |
|
||||||
#include "vulkan/swapchain.hpp" |
|
||||||
#include "vulkan/pipeline.hpp" |
|
||||||
#include "vulkan/instance.hpp" |
|
||||||
#include "vulkan/buffer.hpp" |
|
||||||
#include "vulkan/command_pool.hpp" |
|
||||||
#include "vulkan/image.hpp" |
|
||||||
#include "vulkan/synchronization.hpp" |
|
||||||
#include "camera.hpp" |
|
||||||
#include "input.hpp" |
|
||||||
#include "vulkan/descriptor_pool.hpp" |
|
||||||
|
|
||||||
Application::Application() { |
|
||||||
new Instance; |
|
||||||
new Input(Instance::instance->window); |
|
||||||
|
|
||||||
createSyncObjects(); |
|
||||||
swapchain = new Swapchain(); |
|
||||||
descriptorPool = new DescriptorPool(); |
|
||||||
graphicsPipeline = new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv", |
|
||||||
swapchain->renderPass, |
|
||||||
{descriptorPool->layouts[DescriptorSet::WORLD]}); |
|
||||||
|
|
||||||
VkDeviceSize bufferSize = sizeof(UniformBufferObject); |
|
||||||
|
|
||||||
uniformBuffer = new Buffer(bufferSize, |
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, |
|
||||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, |
|
||||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); |
|
||||||
|
|
||||||
descriptorPool->bindBuffer(*uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0); |
|
||||||
camera = new Camera(swapchain->extent); |
|
||||||
} |
|
||||||
|
|
||||||
void Application::updateUniformBuffer() { |
|
||||||
static float elapsed = 0; |
|
||||||
|
|
||||||
elapsed += 0.007; |
|
||||||
|
|
||||||
UniformBufferObject ubo {}; |
|
||||||
ubo.model = glm::mat4(1); |
|
||||||
ubo.view = camera->view(); |
|
||||||
ubo.projection = camera->projection(); |
|
||||||
ubo.projection[1][1] *= -1; |
|
||||||
|
|
||||||
memcpy(uniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(UniformBufferObject)); |
|
||||||
} |
|
||||||
|
|
||||||
void Application::recordGraphicsCommandBuffer(uint32_t imageIndex) { |
|
||||||
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer; |
|
||||||
|
|
||||||
VkCommandBufferBeginInfo beginInfo {}; |
|
||||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
||||||
|
|
||||||
vkBeginCommandBuffer(cmdBuffer, &beginInfo); |
|
||||||
|
|
||||||
VkRenderPassBeginInfo renderPassInfo {}; |
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; |
|
||||||
renderPassInfo.renderPass = swapchain->renderPass; |
|
||||||
renderPassInfo.framebuffer = swapchain->frameBuffers[imageIndex]; |
|
||||||
renderPassInfo.renderArea.offset = {0, 0}; |
|
||||||
renderPassInfo.renderArea.extent = swapchain->extent; |
|
||||||
|
|
||||||
VkClearValue clearValues[2] {}; |
|
||||||
clearValues[0].color = {{0, 0, 0, 1}}; |
|
||||||
clearValues[1].depthStencil = {1.0f, 0}; |
|
||||||
|
|
||||||
renderPassInfo.clearValueCount = 2; |
|
||||||
renderPassInfo.pClearValues = clearValues; |
|
||||||
|
|
||||||
vkCmdBeginRenderPass(cmdBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); |
|
||||||
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->handle); |
|
||||||
|
|
||||||
VkViewport viewport {}; |
|
||||||
viewport.x = 0; |
|
||||||
viewport.y = 0; |
|
||||||
viewport.width = static_cast<float>(swapchain->extent.width); |
|
||||||
viewport.height = static_cast<float>(swapchain->extent.height); |
|
||||||
viewport.minDepth = 0; |
|
||||||
viewport.maxDepth = 1; |
|
||||||
vkCmdSetViewport(cmdBuffer, 0, 1, &viewport); |
|
||||||
|
|
||||||
VkRect2D scissor {}; |
|
||||||
scissor.offset = {0, 0}; |
|
||||||
scissor.extent = swapchain->extent; |
|
||||||
vkCmdSetScissor(cmdBuffer, 0, 1, &scissor); |
|
||||||
|
|
||||||
recordDrawCommands(); |
|
||||||
|
|
||||||
vkCmdEndRenderPass(cmdBuffer); |
|
||||||
vkEndCommandBuffer(cmdBuffer); |
|
||||||
} |
|
||||||
|
|
||||||
void Application::createSyncObjects() { |
|
||||||
imageAvailable = new Semaphore; |
|
||||||
renderFinished = new Semaphore; |
|
||||||
computeFinished = new Semaphore; |
|
||||||
renderInFlight = new Fence(true); |
|
||||||
computeInFlight = new Fence(true); |
|
||||||
} |
|
||||||
|
|
||||||
void Application::mainLoop() { |
|
||||||
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
||||||
glfwPollEvents(); |
|
||||||
update(); |
|
||||||
drawFrame(); |
|
||||||
} |
|
||||||
vkDeviceWaitIdle(Instance::instance->device); |
|
||||||
} |
|
||||||
|
|
||||||
void Application::drawFrame() { |
|
||||||
vkWaitForFences(Instance::instance->device, 1, &renderInFlight->handle, VK_TRUE, UINT64_MAX); |
|
||||||
|
|
||||||
uint32_t imageIndex; |
|
||||||
VkResult result = vkAcquireNextImageKHR(Instance::instance->device, swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex); |
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR){ |
|
||||||
swapchain->recreateSwapchain(); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
vkResetFences(Instance::instance->device, 1, &renderInFlight->handle); |
|
||||||
|
|
||||||
vkResetCommandBuffer(Instance::instance->commandPool->graphicsBuffer, 0); |
|
||||||
recordGraphicsCommandBuffer(imageIndex); |
|
||||||
|
|
||||||
camera->update(0.017); |
|
||||||
updateUniformBuffer(); |
|
||||||
|
|
||||||
VkSubmitInfo submitInfo {}; |
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
||||||
|
|
||||||
VkSemaphore waitSemaphores[] = {imageAvailable->handle, computeFinished->handle}; |
|
||||||
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT}; |
|
||||||
submitInfo.waitSemaphoreCount = 2; |
|
||||||
submitInfo.pWaitSemaphores = waitSemaphores; |
|
||||||
submitInfo.pWaitDstStageMask = waitStages; |
|
||||||
submitInfo.commandBufferCount = 1; |
|
||||||
submitInfo.pCommandBuffers = &Instance::instance->commandPool->graphicsBuffer; |
|
||||||
|
|
||||||
VkSemaphore signalSemaphores[] = {renderFinished->handle}; |
|
||||||
submitInfo.signalSemaphoreCount = 1; |
|
||||||
submitInfo.pSignalSemaphores = signalSemaphores; |
|
||||||
|
|
||||||
vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, renderInFlight->handle); |
|
||||||
|
|
||||||
VkPresentInfoKHR presentInfo {}; |
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; |
|
||||||
presentInfo.waitSemaphoreCount = 1; |
|
||||||
presentInfo.pWaitSemaphores = signalSemaphores; |
|
||||||
|
|
||||||
VkSwapchainKHR swapchains[] = {swapchain->handle}; |
|
||||||
presentInfo.swapchainCount = 1; |
|
||||||
presentInfo.pSwapchains = swapchains; |
|
||||||
presentInfo.pImageIndices = &imageIndex; |
|
||||||
|
|
||||||
result = vkQueuePresentKHR(Instance::instance->presentQueue, &presentInfo); |
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || Instance::instance->windowResized){ |
|
||||||
Instance::instance->windowResized = false; |
|
||||||
swapchain->recreateSwapchain(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Application::update() { |
|
||||||
vkWaitForFences(Instance::instance->device, 1, &computeInFlight->handle, VK_TRUE, UINT64_MAX); |
|
||||||
vkResetFences(Instance::instance->device, 1, &computeInFlight->handle); |
|
||||||
|
|
||||||
|
|
||||||
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->computeBuffer; |
|
||||||
vkResetCommandBuffer(cmdBuffer, 0); |
|
||||||
|
|
||||||
VkCommandBufferBeginInfo beginInfo {}; |
|
||||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
||||||
beginInfo.flags = 0; |
|
||||||
|
|
||||||
vkBeginCommandBuffer(cmdBuffer, &beginInfo); |
|
||||||
recordComputeCommands(cmdBuffer); |
|
||||||
vkEndCommandBuffer(cmdBuffer); |
|
||||||
|
|
||||||
VkSubmitInfo submit {}; |
|
||||||
submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
||||||
submit.commandBufferCount = 1; |
|
||||||
submit.pCommandBuffers = &Instance::instance->commandPool->computeBuffer; |
|
||||||
submit.signalSemaphoreCount = 1; |
|
||||||
submit.pSignalSemaphores = &computeFinished->handle; |
|
||||||
|
|
||||||
vkQueueSubmit(Instance::instance->computeQueue, 1, &submit, computeInFlight->handle); |
|
||||||
} |
|
||||||
|
|
||||||
Application::~Application() { |
|
||||||
delete swapchain; |
|
||||||
delete descriptorPool; |
|
||||||
delete imageAvailable; |
|
||||||
delete renderFinished; |
|
||||||
delete computeFinished; |
|
||||||
delete renderInFlight; |
|
||||||
delete computeInFlight; |
|
||||||
delete uniformBuffer; |
|
||||||
delete graphicsPipeline; |
|
||||||
delete camera; |
|
||||||
delete Instance::instance; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in new issue