|
|
@ -15,6 +15,14 @@ |
|
|
|
#include "timer.hpp" |
|
|
|
#include "timer.hpp" |
|
|
|
#include "grabber.hpp" |
|
|
|
#include "grabber.hpp" |
|
|
|
#include "stb_image.h" |
|
|
|
#include "stb_image.h" |
|
|
|
|
|
|
|
#include <future> |
|
|
|
|
|
|
|
#include <chrono> |
|
|
|
|
|
|
|
#include "imgui.h" |
|
|
|
|
|
|
|
#include "imgui/backends/imgui_impl_vulkan.h" |
|
|
|
|
|
|
|
#include "imgui/backends/imgui_impl_glfw.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std::chrono; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct SizesUniformData { |
|
|
|
struct SizesUniformData { |
|
|
|
uint32_t vertexCount; |
|
|
|
uint32_t vertexCount; |
|
|
@ -51,6 +59,7 @@ struct PBDPushData { |
|
|
|
Application::Application() { |
|
|
|
Application::Application() { |
|
|
|
createSyncObjects(); |
|
|
|
createSyncObjects(); |
|
|
|
swapchain = make_unique<Swapchain>(); |
|
|
|
swapchain = make_unique<Swapchain>(); |
|
|
|
|
|
|
|
Instance::instance->initImGui(*swapchain); |
|
|
|
descriptorPool = make_unique<DescriptorPool>(); |
|
|
|
descriptorPool = make_unique<DescriptorPool>(); |
|
|
|
graphicsPipeline = unique_ptr<GraphicsPipeline>(new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv", |
|
|
|
graphicsPipeline = unique_ptr<GraphicsPipeline>(new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv", |
|
|
|
swapchain->renderPass, |
|
|
|
swapchain->renderPass, |
|
|
@ -129,14 +138,11 @@ Application::Application() { |
|
|
|
printVmaStats(); |
|
|
|
printVmaStats(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#include <future> |
|
|
|
|
|
|
|
#include <chrono> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std::chrono; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Application::mainLoop() { |
|
|
|
void Application::mainLoop() { |
|
|
|
vkDeviceWaitIdle(Instance::GetDevice()); |
|
|
|
vkDeviceWaitIdle(Instance::GetDevice()); |
|
|
|
std::future compute = std::async(std::launch::async, [this](){ |
|
|
|
std::future compute = std::async(std::launch::async, [this](){ |
|
|
|
|
|
|
|
setbuf(stdout, NULL); |
|
|
|
|
|
|
|
descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); |
|
|
|
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
|
|
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
|
|
auto t1 = system_clock::now(); |
|
|
|
auto t1 = system_clock::now(); |
|
|
|
update(); |
|
|
|
update(); |
|
|
@ -145,12 +151,26 @@ void Application::mainLoop() { |
|
|
|
auto measuredUpdateDuration = duration<float>(t2 - t1); |
|
|
|
auto measuredUpdateDuration = duration<float>(t2 - t1); |
|
|
|
auto requestedUpdateDuration = duration<float>(simulationPropertiesBuffer->access<SimulationUniformData>().dt); |
|
|
|
auto requestedUpdateDuration = duration<float>(simulationPropertiesBuffer->access<SimulationUniformData>().dt); |
|
|
|
std::this_thread::sleep_for(requestedUpdateDuration - measuredUpdateDuration); |
|
|
|
std::this_thread::sleep_for(requestedUpdateDuration - measuredUpdateDuration); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto totalUpdateDuration = std::max(requestedUpdateDuration, measuredUpdateDuration); |
|
|
|
|
|
|
|
printf("\r%f", totalUpdateDuration.count()); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool show_demo_window = true; |
|
|
|
|
|
|
|
|
|
|
|
auto t1 = system_clock::now(); |
|
|
|
auto t1 = system_clock::now(); |
|
|
|
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
|
|
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
|
|
glfwPollEvents(); |
|
|
|
glfwPollEvents(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ImGui_ImplVulkan_NewFrame(); |
|
|
|
|
|
|
|
ImGui_ImplGlfw_NewFrame(); |
|
|
|
|
|
|
|
ImGui::NewFrame(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ImGui::ShowDemoWindow(&show_demo_window); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ImGui::Render(); |
|
|
|
|
|
|
|
|
|
|
|
auto t2 = system_clock::now(); |
|
|
|
auto t2 = system_clock::now(); |
|
|
|
float seconds = duration<float>(t2 - t1).count(); |
|
|
|
float seconds = duration<float>(t2 - t1).count(); |
|
|
|
t1 = system_clock::now(); |
|
|
|
t1 = system_clock::now(); |
|
|
@ -176,18 +196,18 @@ void Application::createSyncObjects() { |
|
|
|
|
|
|
|
|
|
|
|
void Application::createMeshBuffers() { |
|
|
|
void Application::createMeshBuffers() { |
|
|
|
Mesh sphere("models/icosphere.ply"); |
|
|
|
Mesh sphere("models/icosphere.ply"); |
|
|
|
Mesh bunny("models/bunny_high.ply"); |
|
|
|
Mesh bunny("models/bunny_medium.ply"); |
|
|
|
|
|
|
|
|
|
|
|
auto body = std::make_unique<SoftBody>(&sphere, 1.f / 100); |
|
|
|
auto body = std::make_unique<SoftBody>(&sphere, 1.f / 60); |
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 0; i++){ |
|
|
|
for (size_t i = 0; i < 5; i++){ |
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
copy->applyVertexOffset({i * 2, 0, 0}); |
|
|
|
copy->applyVertexOffset({i * 2, 0, 0}); |
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
body = std::make_unique<SoftBody>(&bunny, 1.f / 10); |
|
|
|
body = std::make_unique<SoftBody>(&bunny, 1.f / 10); |
|
|
|
for (size_t i = 0; i < 2; i++){ |
|
|
|
for (size_t i = 0; i < 5; i++){ |
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
copy->applyVertexOffset({i * 2, 0, 2}); |
|
|
|
copy->applyVertexOffset({i * 2, 0, 2}); |
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
@ -423,6 +443,8 @@ void Application::drawFrame(float dt) { |
|
|
|
|
|
|
|
|
|
|
|
recordDrawCommands(cmdBuffer); |
|
|
|
recordDrawCommands(cmdBuffer); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmdBuffer); |
|
|
|
|
|
|
|
|
|
|
|
vkCmdEndRenderPass(cmdBuffer); |
|
|
|
vkCmdEndRenderPass(cmdBuffer); |
|
|
|
vkEndCommandBuffer(cmdBuffer); |
|
|
|
vkEndCommandBuffer(cmdBuffer); |
|
|
|
} |
|
|
|
} |
|
|
@ -485,11 +507,12 @@ void Application::update() { |
|
|
|
vkResetFences(Instance::GetDevice(), 1, &computeFence->handle); |
|
|
|
vkResetFences(Instance::GetDevice(), 1, &computeFence->handle); |
|
|
|
|
|
|
|
|
|
|
|
currentDrawVertexBuffer = 1 - currentDrawVertexBuffer; |
|
|
|
currentDrawVertexBuffer = 1 - currentDrawVertexBuffer; |
|
|
|
descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vkWaitForFences(Instance::GetDevice(), 1, &transferFence->handle, VK_TRUE, UINT64_MAX); |
|
|
|
vkWaitForFences(Instance::GetDevice(), 1, &transferFence->handle, VK_TRUE, UINT64_MAX); |
|
|
|
vkResetFences(Instance::GetDevice(), 1, &transferFence->handle); |
|
|
|
vkResetFences(Instance::GetDevice(), 1, &transferFence->handle); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
currentDrawVertexBuffer = 1 - currentDrawVertexBuffer; |
|
|
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo beginInfo {}; |
|
|
|
VkCommandBufferBeginInfo beginInfo {}; |
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
|
|
beginInfo.flags = 0; |
|
|
|
beginInfo.flags = 0; |
|
|
@ -687,9 +710,3 @@ void Application::recordNormalCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; |
|
|
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; |
|
|
|
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); |
|
|
|
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|