Rendering a triangle to the screen, phew!
This commit is contained in:
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
BIN
FirstTriangle.png
LFS
Normal file
BIN
FirstTriangle.png
LFS
Normal file
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Following the vulkan tutorial on :
|
Following the vulkan tutorial on :
|
||||||
https://vulkan-tutorial.com/en/Drawing_a_triangle/Presentation/Swap_chain
|
https://vulkan-tutorial.com/en/Drawing_a_triangle/Drawing/Frames_in_flight
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
@@ -66,6 +66,9 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
std::vector<VkFramebuffer> swapchainFrameBuffers;
|
std::vector<VkFramebuffer> swapchainFrameBuffers;
|
||||||
VkCommandPool commandPool;
|
VkCommandPool commandPool;
|
||||||
VkCommandBuffer commandBuffer;
|
VkCommandBuffer commandBuffer;
|
||||||
|
VkSemaphore imageAvailableSemaphore;
|
||||||
|
VkSemaphore renderFinishedSemaphore;
|
||||||
|
VkFence inFlightFence;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -98,6 +101,25 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
createFramebuffers();
|
createFramebuffers();
|
||||||
createCommandPool();
|
createCommandPool();
|
||||||
createCommandBuffer();
|
createCommandBuffer();
|
||||||
|
createSyncObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void createSyncObjects() {
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS ||
|
||||||
|
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS ||
|
||||||
|
vkCreateFence(device, &fenceInfo, nullptr, &inFlightFence) != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to create semaphores!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
|
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
|
||||||
@@ -324,12 +346,26 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
subpass.colorAttachmentCount = 1;
|
subpass.colorAttachmentCount = 1;
|
||||||
subpass.pColorAttachments = &colorAttachementRef;
|
subpass.pColorAttachments = &colorAttachementRef;
|
||||||
|
|
||||||
|
VkSubpassDependency dependency{};
|
||||||
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependency.dstSubpass = 0;
|
||||||
|
|
||||||
|
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependency.srcAccessMask = 0;
|
||||||
|
|
||||||
|
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
VkRenderPassCreateInfo renderPassInfo{};
|
VkRenderPassCreateInfo renderPassInfo{};
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
renderPassInfo.attachmentCount = 1;
|
renderPassInfo.attachmentCount = 1;
|
||||||
renderPassInfo.pAttachments = &colorAttachment;
|
renderPassInfo.pAttachments = &colorAttachment;
|
||||||
renderPassInfo.subpassCount = 1;
|
renderPassInfo.subpassCount = 1;
|
||||||
renderPassInfo.pSubpasses = &subpass;
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
|
renderPassInfo.dependencyCount = 1;
|
||||||
|
renderPassInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
|
if (vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create render pass!");
|
throw std::runtime_error("Failed to create render pass!");
|
||||||
@@ -815,10 +851,68 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
void mainLoop(){
|
void mainLoop(){
|
||||||
while (!glfwWindowShouldClose(window)){
|
while (!glfwWindowShouldClose(window)){
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
drawFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vkDeviceWaitIdle(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void drawFrame() {
|
||||||
|
vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
|
||||||
|
vkResetFences(device, 1, &inFlightFence);
|
||||||
|
|
||||||
|
uint32_t imageIndex;
|
||||||
|
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
|
||||||
|
|
||||||
|
vkResetCommandBuffer(commandBuffer, 0);
|
||||||
|
recordCommandBuffer(commandBuffer, imageIndex);
|
||||||
|
|
||||||
|
VkSubmitInfo submitInfo{};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
|
||||||
|
VkSemaphore waitSemaphores[] = { imageAvailableSemaphore };
|
||||||
|
VkPipelineStageFlags waitstages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||||
|
submitInfo.waitSemaphoreCount = 1;
|
||||||
|
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||||
|
submitInfo.pWaitDstStageMask = waitstages;
|
||||||
|
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &commandBuffer;
|
||||||
|
|
||||||
|
VkSemaphore signalSemaphore[] = { renderFinishedSemaphore };
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = signalSemaphore;
|
||||||
|
|
||||||
|
if (vkQueueSubmit(graphicsQueue,1, &submitInfo, inFlightFence) != 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 = signalSemaphore;
|
||||||
|
|
||||||
|
VkSwapchainKHR swapChains[] = { swapChain };
|
||||||
|
presentInfo.swapchainCount = 1;
|
||||||
|
presentInfo.pSwapchains = swapChains;
|
||||||
|
presentInfo.pImageIndices = &imageIndex;
|
||||||
|
|
||||||
|
vkQueuePresentKHR(presentQueue, &presentInfo);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cleanup(){
|
void cleanup(){
|
||||||
|
|
||||||
|
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
|
||||||
|
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
|
||||||
|
vkDestroyFence(device, inFlightFence, nullptr);
|
||||||
|
|
||||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||||
|
|
||||||
for (auto framebuffer : swapchainFrameBuffers) {
|
for (auto framebuffer : swapchainFrameBuffers) {
|
||||||
|
|||||||
Reference in New Issue
Block a user