hello triangle!
This commit is contained in:
parent
cd28277aaf
commit
0b7d1b65c8
99
main.cpp
99
main.cpp
@ -80,6 +80,10 @@ private:
|
|||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
VkPipeline graphicsPipeline;
|
VkPipeline graphicsPipeline;
|
||||||
|
|
||||||
|
VkSemaphore imageAvailableSemaphore;
|
||||||
|
VkSemaphore renderFinishedSemaphore;
|
||||||
|
VkFence inFlightFence;
|
||||||
|
|
||||||
std::vector<VkDynamicState> dynamicStates = {
|
std::vector<VkDynamicState> dynamicStates = {
|
||||||
VK_DYNAMIC_STATE_VIEWPORT,
|
VK_DYNAMIC_STATE_VIEWPORT,
|
||||||
VK_DYNAMIC_STATE_SCISSOR
|
VK_DYNAMIC_STATE_SCISSOR
|
||||||
@ -106,6 +110,69 @@ private:
|
|||||||
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 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 signalSemaphores[] = {renderFinishedSemaphore};
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||||
|
|
||||||
|
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 = signalSemaphores;
|
||||||
|
|
||||||
|
VkSwapchainKHR swapChains[] = {swapChain};
|
||||||
|
presentInfo.swapchainCount = 1;
|
||||||
|
presentInfo.pSwapchains = swapChains;
|
||||||
|
presentInfo.pImageIndices = &imageIndex;
|
||||||
|
|
||||||
|
presentInfo.pResults = nullptr;
|
||||||
|
|
||||||
|
VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
std::cout << "error presenting to queue: " << result << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
|
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
|
||||||
@ -211,6 +278,14 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createRenderPass() {
|
void createRenderPass() {
|
||||||
|
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;
|
||||||
|
|
||||||
VkAttachmentDescription colorAttachment{};
|
VkAttachmentDescription colorAttachment{};
|
||||||
colorAttachment.format = swapChainImageFormat;
|
colorAttachment.format = swapChainImageFormat;
|
||||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
@ -236,6 +311,8 @@ private:
|
|||||||
renderPassInfo.pAttachments = &colorAttachment;
|
renderPassInfo.pAttachments = &colorAttachment;
|
||||||
renderPassInfo.subpassCount = 1;
|
renderPassInfo.subpassCount = 1;
|
||||||
renderPassInfo.pSubpasses = &subpass;
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
|
renderPassInfo.dependencyCount = 1;
|
||||||
|
renderPassInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
VkResult result = vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass);
|
VkResult result = vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass);
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
@ -282,24 +359,10 @@ private:
|
|||||||
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
inputAssembly.primitiveRestartEnable = VK_FALSE;
|
inputAssembly.primitiveRestartEnable = VK_FALSE;
|
||||||
|
|
||||||
VkViewport viewport{};
|
|
||||||
viewport.x = 0.0f;
|
|
||||||
viewport.y = 0.0f;
|
|
||||||
viewport.width = (float) swapChainExtent.width;
|
|
||||||
viewport.height = (float) swapChainExtent.height;
|
|
||||||
viewport.minDepth = 0.0f;
|
|
||||||
viewport.maxDepth = 1.0f;
|
|
||||||
|
|
||||||
VkRect2D scissor{};
|
|
||||||
scissor.offset = {0, 0};
|
|
||||||
scissor.extent = swapChainExtent;
|
|
||||||
|
|
||||||
VkPipelineViewportStateCreateInfo viewportState{};
|
VkPipelineViewportStateCreateInfo viewportState{};
|
||||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||||
viewportState.viewportCount = 1;
|
viewportState.viewportCount = 1;
|
||||||
viewportState.pViewports = &viewport;
|
|
||||||
viewportState.scissorCount = 1;
|
viewportState.scissorCount = 1;
|
||||||
viewportState.pScissors = &scissor;
|
|
||||||
|
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizer{};
|
VkPipelineRasterizationStateCreateInfo rasterizer{};
|
||||||
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||||
@ -575,6 +638,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
|
vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
|
||||||
|
vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pickPhysicalDevice() {
|
void pickPhysicalDevice() {
|
||||||
@ -812,10 +876,17 @@ private:
|
|||||||
void mainLoop() {
|
void mainLoop() {
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
drawFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vkDeviceWaitIdle(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 fragColor;
|
||||||
|
|
||||||
vec2 positions[3] = vec2[](
|
vec2 positions[3] = vec2[](
|
||||||
vec2(0.0, -0.5),
|
vec2(0.0, -0.5),
|
||||||
vec2(0.5, 0.5),
|
vec2(0.5, 0.5),
|
||||||
@ -12,9 +14,7 @@ vec3 colors[3] = vec3[](
|
|||||||
vec3(0.0, 0.0, 1.0)
|
vec3(0.0, 0.0, 1.0)
|
||||||
);
|
);
|
||||||
|
|
||||||
layout(location = 0) out vec3 fragColor;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 0.1);
|
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||||
fragColor = colors[gl_VertexIndex];
|
fragColor = colors[gl_VertexIndex];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user