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 <thread> |
||||
#include "application.hpp" |
||||
#include "vulkan/instance.hpp" |
||||
#include "input.hpp" |
||||
|
||||
int main() { |
||||
Simulation simulation; |
||||
simulation.mainLoop(); |
||||
Instance instance; |
||||
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