Triangle finally renderedgit add . Swap ChainRecreation is up next, to allow for resizing. Then, it will be on to buffers for non-hardcoded shaders
This commit is contained in:
parent
10a8c236f0
commit
29599e4b9a
@ -19,14 +19,12 @@ namespace DeviceControl {
|
|||||||
VkPhysicalDeviceFeatures deviceFeatures;
|
VkPhysicalDeviceFeatures deviceFeatures;
|
||||||
|
|
||||||
|
|
||||||
VkSwapchainKHR swapChain;
|
|
||||||
std::vector<VkImage> swapChainImages;
|
std::vector<VkImage> swapChainImages;
|
||||||
VkFormat swapChainImageFormat;
|
VkFormat swapChainImageFormat;
|
||||||
VkExtent2D swapChainExtent;
|
VkExtent2D swapChainExtent;
|
||||||
std::vector<VkImageView> swapChainImageViews;
|
std::vector<VkImageView> swapChainImageViews;
|
||||||
|
|
||||||
VkQueue graphicsQueue;
|
|
||||||
VkQueue presentQueue;
|
|
||||||
|
|
||||||
struct SwapChainSupportDetails {
|
struct SwapChainSupportDetails {
|
||||||
VkSurfaceCapabilitiesKHR capabilities;
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
@ -227,8 +225,8 @@ namespace DeviceControl {
|
|||||||
}
|
}
|
||||||
if(Global::enableValidationLayers) std::cout << "Created Logical device successfully!\n" << std::endl;
|
if(Global::enableValidationLayers) std::cout << "Created Logical device successfully!\n" << std::endl;
|
||||||
|
|
||||||
vkGetDeviceQueue(Global::device, indices.graphicsFamily.value(), 0, &graphicsQueue);
|
vkGetDeviceQueue(Global::device, indices.graphicsFamily.value(), 0, &Global::graphicsQueue);
|
||||||
vkGetDeviceQueue(Global::device, indices.presentFamily.value(), 0, &presentQueue);
|
vkGetDeviceQueue(Global::device, indices.presentFamily.value(), 0, &Global::presentQueue);
|
||||||
}
|
}
|
||||||
void devicelibrary::createSwapChain(GLFWwindow* window) {
|
void devicelibrary::createSwapChain(GLFWwindow* window) {
|
||||||
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(Global::physicalDevice);
|
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(Global::physicalDevice);
|
||||||
@ -284,20 +282,20 @@ namespace DeviceControl {
|
|||||||
// require you to recreate it and reference the old one specified here, will revisit in a few days.
|
// require you to recreate it and reference the old one specified here, will revisit in a few days.
|
||||||
createSwapChainInfo.oldSwapchain = VK_NULL_HANDLE;
|
createSwapChainInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
if(vkCreateSwapchainKHR(Global::device, &createSwapChainInfo, nullptr, &swapChain) != VK_SUCCESS) {
|
if(vkCreateSwapchainKHR(Global::device, &createSwapChainInfo, nullptr, &Global::swapChain) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create the swap chain!!");
|
throw std::runtime_error("Failed to create the swap chain!!");
|
||||||
}
|
}
|
||||||
if(Global::enableValidationLayers) std::cout << "Swap Chain created successfully\n" << std::endl;
|
if(Global::enableValidationLayers) std::cout << "Swap Chain created successfully\n" << std::endl;
|
||||||
|
|
||||||
vkGetSwapchainImagesKHR(Global::device, swapChain, &imageCount, nullptr);
|
vkGetSwapchainImagesKHR(Global::device, Global::swapChain, &imageCount, nullptr);
|
||||||
swapChainImages.resize(imageCount);
|
swapChainImages.resize(imageCount);
|
||||||
vkGetSwapchainImagesKHR(Global::device, swapChain, &imageCount, swapChainImages.data());
|
vkGetSwapchainImagesKHR(Global::device, Global::swapChain, &imageCount, swapChainImages.data());
|
||||||
|
|
||||||
swapChainImageFormat = surfaceFormat.format;
|
swapChainImageFormat = surfaceFormat.format;
|
||||||
swapChainExtent = extent;
|
swapChainExtent = extent;
|
||||||
}
|
}
|
||||||
void devicelibrary::destroySwapChain() {
|
void devicelibrary::destroySwapChain() {
|
||||||
vkDestroySwapchainKHR(Global::device, swapChain, nullptr);
|
vkDestroySwapchainKHR(Global::device, Global::swapChain, nullptr);
|
||||||
if(Global::enableValidationLayers) std::cout << "Destroyed Swap Chain safely\n" << std::endl;
|
if(Global::enableValidationLayers) std::cout << "Destroyed Swap Chain safely\n" << std::endl;
|
||||||
}
|
}
|
||||||
void devicelibrary::createImageViews() {
|
void devicelibrary::createImageViews() {
|
||||||
|
@ -14,6 +14,7 @@ class devicelibrary {
|
|||||||
void destroyImageViews();
|
void destroyImageViews();
|
||||||
void createCommandPool();
|
void createCommandPool();
|
||||||
void destroyCommandPool();
|
void destroyCommandPool();
|
||||||
|
|
||||||
// ---------- Getters & Setters ----------- //
|
// ---------- Getters & Setters ----------- //
|
||||||
VkFormat getImageFormat();
|
VkFormat getImageFormat();
|
||||||
std::vector<VkImageView> getSwapChainImageViews();
|
std::vector<VkImageView> getSwapChainImageViews();
|
||||||
|
@ -14,7 +14,11 @@ namespace Global {
|
|||||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||||
VkDevice device = VK_NULL_HANDLE;
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
|
VkSwapchainKHR swapChain = VK_NULL_HANDLE;
|
||||||
|
VkCommandPool commandPool = VK_NULL_HANDLE;
|
||||||
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
|
VkQueue graphicsQueue = VK_NULL_HANDLE;
|
||||||
|
VkQueue presentQueue = VK_NULL_HANDLE;
|
||||||
Global::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
|
Global::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
|
||||||
// First we feed in a integer we want to use to hold the number of queued items, that fills it, then we create that amount of default constructed *VkQueueFamilyProperties* structs.
|
// First we feed in a integer we want to use to hold the number of queued items, that fills it, then we create that amount of default constructed *VkQueueFamilyProperties* structs.
|
||||||
// These store the flags, the amount of queued items in the family, and timestamp data. Queue families are simply group collections of tasks we want to get done.
|
// These store the flags, the amount of queued items in the family, and timestamp data. Queue families are simply group collections of tasks we want to get done.
|
||||||
|
@ -14,6 +14,11 @@ namespace Global {
|
|||||||
extern const std::vector<const char*> validationLayers;
|
extern const std::vector<const char*> validationLayers;
|
||||||
extern const bool enableValidationLayers;
|
extern const bool enableValidationLayers;
|
||||||
extern VkDevice device;
|
extern VkDevice device;
|
||||||
|
extern VkCommandPool commandPool;
|
||||||
|
extern std::vector<VkCommandBuffer> commandBuffers;
|
||||||
|
extern VkQueue graphicsQueue;
|
||||||
|
extern VkQueue presentQueue;
|
||||||
|
const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||||
struct QueueFamilyIndices {
|
struct QueueFamilyIndices {
|
||||||
// We need to check that the Queue families support graphics operations and window presentation, sometimes they can support one or the other,
|
// We need to check that the Queue families support graphics operations and window presentation, sometimes they can support one or the other,
|
||||||
// therefore, we take into account both for completion.
|
// therefore, we take into account both for completion.
|
||||||
@ -24,7 +29,7 @@ namespace Global {
|
|||||||
return graphicsFamily.has_value() && presentFamily.has_value();
|
return graphicsFamily.has_value() && presentFamily.has_value();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
extern VkSwapchainKHR swapChain;
|
||||||
extern VkSurfaceKHR surface;
|
extern VkSurfaceKHR surface;
|
||||||
extern VkPhysicalDevice physicalDevice;
|
extern VkPhysicalDevice physicalDevice;
|
||||||
Global::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
Global::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
||||||
|
@ -11,8 +11,6 @@ namespace Graphics {
|
|||||||
};
|
};
|
||||||
std::vector<VkFramebuffer> swapChainFramebuffers;
|
std::vector<VkFramebuffer> swapChainFramebuffers;
|
||||||
|
|
||||||
VkCommandPool commandPool;
|
|
||||||
VkCommandBuffer commandBuffer;
|
|
||||||
|
|
||||||
VkRenderPass renderPass;
|
VkRenderPass renderPass;
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
@ -242,6 +240,7 @@ namespace Graphics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void graphicspipeline::createCommandPool() {
|
void graphicspipeline::createCommandPool() {
|
||||||
|
|
||||||
Global::QueueFamilyIndices queueFamilyIndices = Global::findQueueFamilies(Global::physicalDevice);
|
Global::QueueFamilyIndices queueFamilyIndices = Global::findQueueFamilies(Global::physicalDevice);
|
||||||
|
|
||||||
VkCommandPoolCreateInfo poolInfo{};
|
VkCommandPoolCreateInfo poolInfo{};
|
||||||
@ -249,28 +248,30 @@ namespace Graphics {
|
|||||||
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
|
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
|
||||||
|
|
||||||
if(vkCreateCommandPool(Global::device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
|
if(vkCreateCommandPool(Global::device, &poolInfo, nullptr, &Global::commandPool) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create command pool!");
|
throw std::runtime_error("Failed to create command pool!");
|
||||||
}
|
}
|
||||||
if(Global::enableValidationLayers) std::cout << "Command pool created successfully\n" << std::endl;
|
if(Global::enableValidationLayers) std::cout << "Command pool created successfully\n" << std::endl;
|
||||||
}
|
}
|
||||||
void graphicspipeline::destroyCommandPool() {
|
void graphicspipeline::destroyCommandPool() {
|
||||||
vkDestroyCommandPool(Global::device, commandPool, nullptr);
|
vkDestroyCommandPool(Global::device, Global::commandPool, nullptr);
|
||||||
}
|
}
|
||||||
void graphicspipeline::createCommandBuffer() {
|
void graphicspipeline::createCommandBuffer() {
|
||||||
|
Global::commandBuffers.resize(Global::MAX_FRAMES_IN_FLIGHT);
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo allocInfo{};
|
VkCommandBufferAllocateInfo allocInfo{};
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
allocInfo.commandPool = commandPool;
|
allocInfo.commandPool = Global::commandPool;
|
||||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
allocInfo.commandBufferCount = 1;
|
allocInfo.commandBufferCount = (uint32_t) Global::commandBuffers.size();
|
||||||
|
|
||||||
if(vkAllocateCommandBuffers(Global::device, &allocInfo, &commandBuffer) != VK_SUCCESS) {
|
if(vkAllocateCommandBuffers(Global::device, &allocInfo, Global::commandBuffers.data()) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to allocate command buffers");
|
throw std::runtime_error("Failed to allocate command buffers");
|
||||||
}
|
}
|
||||||
if(Global::enableValidationLayers) std::cout << "Allocated command buffers successfully\n" << std::endl;
|
if(Global::enableValidationLayers) std::cout << "Allocated command buffers successfully\n" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
|
void graphicspipeline::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
|
||||||
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; // Optional
|
beginInfo.flags = 0; // Optional
|
||||||
|
@ -13,5 +13,6 @@ namespace Graphics {
|
|||||||
void createCommandPool();
|
void createCommandPool();
|
||||||
void destroyCommandPool();
|
void destroyCommandPool();
|
||||||
void createCommandBuffer();
|
void createCommandBuffer();
|
||||||
|
void recordCommandBuffer(VkCommandBuffer cmndBuffer, uint32_t imageIndex);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
113
src/graphics/render.cpp
Normal file
113
src/graphics/render.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#include "render.h"
|
||||||
|
#include "graphicspipeline.h"
|
||||||
|
namespace RenderPresent {
|
||||||
|
|
||||||
|
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||||
|
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||||
|
std::vector<VkFence> inFlightFences;
|
||||||
|
Graphics::graphicspipeline pipeline;
|
||||||
|
uint32_t currentFrame = 0;
|
||||||
|
// At a high level, rendering in Vulkan consists of 5 steps:
|
||||||
|
// Wait for the previous frame, acquire a image from the swap chain
|
||||||
|
// record a comman d buffer which draws the scene onto that image
|
||||||
|
// submit the recorded command buffer and present the image!
|
||||||
|
void render::drawFrame() {
|
||||||
|
|
||||||
|
vkWaitForFences(Global::device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||||
|
vkResetFences(Global::device, 1, &inFlightFences[currentFrame]);
|
||||||
|
|
||||||
|
uint32_t imageIndex;
|
||||||
|
vkAcquireNextImageKHR(Global::device, Global::swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
||||||
|
|
||||||
|
vkResetCommandBuffer(Global::commandBuffers[currentFrame], /*VkCommandBufferResetFlagBits*/ 0);
|
||||||
|
pipeline.recordCommandBuffer(Global::commandBuffers[currentFrame], imageIndex);
|
||||||
|
|
||||||
|
VkSubmitInfo submitInfo{};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
|
||||||
|
VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame]};
|
||||||
|
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
||||||
|
submitInfo.waitSemaphoreCount = 1;
|
||||||
|
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||||
|
submitInfo.pWaitDstStageMask = waitStages;
|
||||||
|
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &Global::commandBuffers[currentFrame];
|
||||||
|
|
||||||
|
VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||||
|
|
||||||
|
if (vkQueueSubmit(Global::graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to submit draw command buffer!");
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPresentInfoKHR presentInfo{};
|
||||||
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
|
|
||||||
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
|
presentInfo.pWaitSemaphores = signalSemaphores;
|
||||||
|
|
||||||
|
VkSwapchainKHR swapChains[] = {Global::swapChain};
|
||||||
|
presentInfo.swapchainCount = 1;
|
||||||
|
presentInfo.pSwapchains = swapChains;
|
||||||
|
|
||||||
|
presentInfo.pImageIndices = &imageIndex;
|
||||||
|
|
||||||
|
vkQueuePresentKHR(Global::presentQueue, &presentInfo);
|
||||||
|
currentFrame = (currentFrame + 1) % Global::MAX_FRAMES_IN_FLIGHT;
|
||||||
|
}
|
||||||
|
#pragma info
|
||||||
|
// SEMAPHORES
|
||||||
|
// Synchronization of execution on the GPU in Vulkan is *explicit* The Order of ops is up to us to
|
||||||
|
// define the how we want things to run.
|
||||||
|
// Similarly, Semaphores are used to add order between queue ops. There are 2 kinds of Semaphores; binary, and timeline.
|
||||||
|
// We are using Binary semaphores, which can be signaled or unsignaled.
|
||||||
|
// Semaphores are initizalized unsignaled, the way we use them to order queue operations is by providing the same semaphore in one queue op and a wait in another.
|
||||||
|
// For example:
|
||||||
|
// VkCommandBuffer QueueOne, QueueTwo = ...
|
||||||
|
// VkSemaphore semaphore = ...
|
||||||
|
// enqueue QueueOne, Signal semaphore when done, start now.
|
||||||
|
// vkQueueSubmit(work: QueueOne, signal: semaphore, wait: none)
|
||||||
|
// enqueue QueueTwo, wait on semaphore to start
|
||||||
|
// vkQueueSubmit(work: QueueTwo, signal: None, wait: semaphore)
|
||||||
|
// FENCES
|
||||||
|
// Fences are basically semaphores for the CPU! Otherwise known as the host. If the host needs to know when the GPU has finished a task, we use a fence.
|
||||||
|
// VkCommandBuffer cmndBuf = ...
|
||||||
|
// VkFence fence = ...
|
||||||
|
// Start work immediately, signal fence when done.
|
||||||
|
// vkQueueSubmit(work: cmndBuf, fence: fence)
|
||||||
|
// vkWaitForFence(fence)
|
||||||
|
// doStuffOnceFenceDone()
|
||||||
|
#pragma endinfo
|
||||||
|
|
||||||
|
void render::createSyncObject() {
|
||||||
|
imageAvailableSemaphores.resize(Global::MAX_FRAMES_IN_FLIGHT);
|
||||||
|
renderFinishedSemaphores.resize(Global::MAX_FRAMES_IN_FLIGHT);
|
||||||
|
inFlightFences.resize(Global::MAX_FRAMES_IN_FLIGHT);
|
||||||
|
|
||||||
|
VkSemaphoreCreateInfo semaphoreInfo{};
|
||||||
|
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
|
||||||
|
VkFenceCreateInfo fenceInfo{};
|
||||||
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < Global::MAX_FRAMES_IN_FLIGHT; i++) {
|
||||||
|
if(vkCreateSemaphore(Global::device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS ||
|
||||||
|
vkCreateSemaphore(Global::device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) != VK_SUCCESS ||
|
||||||
|
vkCreateFence(Global::device, &fenceInfo, nullptr, &inFlightFences[i]) != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("Failed to create semaphores!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
void destroyFenceSemaphore() {
|
||||||
|
for (size_t i = 0; i < Global::MAX_FRAMES_IN_FLIGHT; i++) {
|
||||||
|
vkDestroySemaphore(Global::device, imageAvailableSemaphores[i], nullptr);
|
||||||
|
vkDestroySemaphore(Global::device, renderFinishedSemaphores[i], nullptr);
|
||||||
|
vkDestroyFence(Global::device, inFlightFences[i], nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/graphics/render.h
Normal file
11
src/graphics/render.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "../global.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace RenderPresent {
|
||||||
|
class render {
|
||||||
|
public:
|
||||||
|
void drawFrame();
|
||||||
|
void createSyncObject();
|
||||||
|
};
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#include "devicelibrary.h" // Device Library includes global, redundant to include with it here
|
#include "devicelibrary.h" // Device Library includes global, redundant to include with it here
|
||||||
#include "debug/vulkandebuglibs.h"
|
#include "debug/vulkandebuglibs.h"
|
||||||
#include "graphics/graphicspipeline.h"
|
#include "graphics/graphicspipeline.h"
|
||||||
|
#include "graphics/render.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -25,6 +26,7 @@ private:
|
|||||||
DeviceControl::devicelibrary deviceLibs;
|
DeviceControl::devicelibrary deviceLibs;
|
||||||
Debug::vulkandebuglibs debugController;
|
Debug::vulkandebuglibs debugController;
|
||||||
Graphics::graphicspipeline graphicsPipeline;
|
Graphics::graphicspipeline graphicsPipeline;
|
||||||
|
RenderPresent::render renderPresentation;
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
|
|
||||||
@ -52,6 +54,7 @@ private:
|
|||||||
graphicsPipeline.createFramebuffers();
|
graphicsPipeline.createFramebuffers();
|
||||||
graphicsPipeline.createCommandPool();
|
graphicsPipeline.createCommandPool();
|
||||||
graphicsPipeline.createCommandBuffer();
|
graphicsPipeline.createCommandBuffer();
|
||||||
|
renderPresentation.createSyncObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void createInstance() {
|
void createInstance() {
|
||||||
@ -77,7 +80,9 @@ private:
|
|||||||
void mainLoop() { // This loop just updates the GLFW window.
|
void mainLoop() { // This loop just updates the GLFW window.
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
renderPresentation.drawFrame();
|
||||||
}
|
}
|
||||||
|
vkDeviceWaitIdle(Global::device);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup() { // Similar to the last handoff, destroy the utils in a safe manner in the library!
|
void cleanup() { // Similar to the last handoff, destroy the utils in a safe manner in the library!
|
||||||
|
Loading…
Reference in New Issue
Block a user