#include <stdafx.h> #include "VulkanRenderer.h" #include "Context.h" #include "glm/gtc/random.hpp" #include "RenderPass.h" #include "Vertex.h" #include "Scene.h" #include "Model.h" #include "Camera.h" #include <algorithm> #include <numeric> namespace fpr { bool VulkanRenderer::IsRunning() const { return !glfwWindowShouldClose(fpr::Context::Get().GetWindow()->GetWindowHandle()); } VulkanRenderer::VulkanRenderer() {} void VulkanRenderer::SetScene(fpr::Scene* scene) { // Setting scene requires that commands are re-recorded, as now different models are present. fpr::Context& context = fpr::Context::Get(); context.m_loaded_scene = scene; context.GetSwapChain()->RecordCommands(); for(auto& model : scene->GetModels()) { for(auto& mesh : model->GetMeshes()) { auto matrix = mesh.GetMatrix(); auto index = mesh.GetMeshIndex(); memcpy(&context.PER_MODEL_UBO.model_matrix[index], &matrix, sizeof(glm::mat4)); } } } void VulkanRenderer::Draw(fpr::Camera* camera) { static double now; static double delta; static double last_time; static int count = 1; auto& context_ref = fpr::Context::Get(); // Update the model matrix. // Big performance hit. Could differentiate between static and dynamic models, as most models are static iin most // cases and can live in a buffer that doesn't need to be touched. context_ref.m_render_graph->Buffers.Get("Model" + std::to_string(context_ref.GetSwapChain()->GetCurrentFrameIdx())) ->Update(context_ref.PER_MODEL_UBO.model_matrix); camera->Update(); m_per_frame_UBO.camera_position = camera->GetPosition(); m_per_frame_UBO.projection_matrix = camera->GetProjectionMatrix(); m_per_frame_UBO.view_matrix = camera->GetViewMatrix(); auto result = context_ref.GetSwapChain()->SubmitFrame(); if(result != vk::Result::eSuccess) [[unlikely]] { context_ref.RecreateSwapchain(); } context_ref.m_render_graph->Buffers.Get("Camera" + std::to_string(context_ref.GetSwapChain()->GetCurrentFrameIdx())) ->Update(&m_per_frame_UBO); fpr::InputHandler::SetDeltaTime(delta); fpr::InputHandler::Update(context_ref.GetWindow()->GetWindowHandle()); fpr::PointLight::Update(); now = glfwGetTime(); delta = now - last_time; static std::vector<double> times; times.resize(501); times[count] = delta; double cum = std::accumulate(times.begin(), times.end(), 0.0); for(int i = 0; i < count; ++i) { cum += times[count]; }; if(count % 100 == 0) std::cout << 1.0 / (cum / 500.0) << '\n'; // glfwSwapBuffers(context_ref.GetWindow()->GetWindowHandle()); last_time = now; glfwPollEvents(); count++; if(count > 500) count = 0; } VulkanRenderer::~VulkanRenderer() { auto& context_ref = fpr::Context::Get(); [[maybe_unused]] vk::Result result = context_ref.GetDevice()->GetLogicalDeviceHandle().waitIdle(); assert(("Device idle state not reached upon cleanup", result == vk::Result::eSuccess)); } } // namespace fpr