직렬화 함수 작성 끝
This commit is contained in:
191
impl/vulkan_engine/vulkan/drawing.cpp
Normal file
191
impl/vulkan_engine/vulkan/drawing.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "precomp.h"
|
||||
#include "vulkan_engine/vulkan/graphics.h"
|
||||
|
||||
namespace veng {
|
||||
|
||||
void Graphics::CreateFramebuffers() {
|
||||
swap_chain_framebuffers_.resize(swap_chain_image_views_.size());
|
||||
|
||||
for (std::uint32_t i = 0; i < swap_chain_image_views_.size(); i++) {
|
||||
std::array<VkImageView, 2> attachments = {swap_chain_image_views_[i],
|
||||
depth_texture_.image_view};
|
||||
|
||||
VkFramebufferCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
info.renderPass = render_pass_;
|
||||
info.attachmentCount = attachments.size();
|
||||
info.pAttachments = attachments.data();
|
||||
info.width = extent_.width;
|
||||
info.height = extent_.height;
|
||||
info.layers = 1;
|
||||
|
||||
VkResult result = vkCreateFramebuffer(logical_device_, &info, nullptr,
|
||||
&swap_chain_framebuffers_[i]);
|
||||
if (result != VK_SUCCESS) std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::CreateCommandPool() {
|
||||
QueueFamilyIndices indices = FindQueueFamilies(physical_device_);
|
||||
VkCommandPoolCreateInfo pool_info = {};
|
||||
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
pool_info.queueFamilyIndex = indices.graphics_family.value();
|
||||
|
||||
VkResult result =
|
||||
vkCreateCommandPool(logical_device_, &pool_info, nullptr, &command_pool_);
|
||||
if (result != VK_SUCCESS) std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void Graphics::CreateCommandBuffer() {
|
||||
VkCommandBufferAllocateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
info.commandPool = command_pool_;
|
||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
info.commandBufferCount = 1;
|
||||
|
||||
for (Frame& frame : frames_) {
|
||||
VkResult result =
|
||||
vkAllocateCommandBuffers(logical_device_, &info, &frame.command_buffer);
|
||||
if (result != VK_SUCCESS) std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::BeginCommands() {
|
||||
vkResetCommandBuffer(frames_[current_frame_].command_buffer, 0);
|
||||
|
||||
VkCommandBufferBeginInfo begin_info = {};
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
|
||||
VkResult result = vkBeginCommandBuffer(
|
||||
frames_[current_frame_].command_buffer, &begin_info);
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("Failed to begin command buffer!");
|
||||
|
||||
std::array<VkClearValue, 2> clear_values;
|
||||
clear_values[0].color = {{0.f, 0.f, 0.f, 1.f}};
|
||||
clear_values[1].depthStencil = {1.f, 0};
|
||||
|
||||
VkRenderPassBeginInfo render_pass_begin_info = {};
|
||||
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
render_pass_begin_info.renderPass = render_pass_;
|
||||
render_pass_begin_info.framebuffer =
|
||||
swap_chain_framebuffers_[current_image_index_];
|
||||
render_pass_begin_info.renderArea.offset = {0, 0};
|
||||
render_pass_begin_info.renderArea.extent = extent_;
|
||||
render_pass_begin_info.clearValueCount = clear_values.size();
|
||||
render_pass_begin_info.pClearValues = clear_values.data();
|
||||
|
||||
vkCmdBeginRenderPass(frames_[current_frame_].command_buffer,
|
||||
&render_pass_begin_info,
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdBindPipeline(frames_[current_frame_].command_buffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline_);
|
||||
VkViewport viewport = GetViewport();
|
||||
VkRect2D scissor = GetScissor();
|
||||
|
||||
vkCmdSetViewport(frames_[current_frame_].command_buffer, 0, 1, &viewport);
|
||||
vkCmdSetScissor(frames_[current_frame_].command_buffer, 0, 1, &scissor);
|
||||
}
|
||||
|
||||
void Graphics::EndCommands() {
|
||||
vkCmdEndRenderPass(frames_[current_frame_].command_buffer);
|
||||
VkResult result = vkEndCommandBuffer(frames_[current_frame_].command_buffer);
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("Failed to record command buffer!");
|
||||
}
|
||||
|
||||
void Graphics::CreateSignals() {
|
||||
for (Frame& frame : frames_) {
|
||||
VkSemaphoreCreateInfo semafore_info = {};
|
||||
semafore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
|
||||
if (vkCreateSemaphore(logical_device_, &semafore_info, nullptr,
|
||||
&frame.image_available_signal) !=
|
||||
VK_SUCCESS)
|
||||
std::exit(EXIT_FAILURE);
|
||||
if (vkCreateSemaphore(logical_device_, &semafore_info, nullptr,
|
||||
&frame.render_finished_signal) !=
|
||||
VK_SUCCESS)
|
||||
std::exit(EXIT_FAILURE);
|
||||
|
||||
VkFenceCreateInfo fence_info = {};
|
||||
fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
if (vkCreateFence(logical_device_, &fence_info, nullptr,
|
||||
&frame.still_rendering_fence) !=
|
||||
VK_SUCCESS)
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
bool Graphics::BeginFrame() {
|
||||
vkWaitForFences(logical_device_, 1,
|
||||
&frames_[current_frame_].still_rendering_fence, VK_TRUE,
|
||||
UINT64_MAX);
|
||||
VkResult image_acquire_result = vkAcquireNextImageKHR(logical_device_, swap_chain_, UINT64_MAX,
|
||||
frames_[current_frame_].image_available_signal,
|
||||
VK_NULL_HANDLE, ¤t_image_index_);
|
||||
|
||||
if (image_acquire_result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
RecreateSwapChain();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (image_acquire_result != VK_SUCCESS &&
|
||||
image_acquire_result != VK_SUBOPTIMAL_KHR)
|
||||
throw std::runtime_error("Couldn't acquire render image!");
|
||||
|
||||
vkResetFences(logical_device_, 1,
|
||||
&frames_[current_frame_].still_rendering_fence);
|
||||
|
||||
BeginCommands();
|
||||
SetModelMatrix(glm::mat4(1.f));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void veng::Graphics::EndFrame() {
|
||||
EndCommands();
|
||||
VkSubmitInfo submit_info = {};
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
|
||||
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
submit_info.waitSemaphoreCount = 1;
|
||||
submit_info.pWaitSemaphores = &frames_[current_frame_].image_available_signal;
|
||||
submit_info.pWaitDstStageMask = &wait_stage;
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &frames_[current_frame_].command_buffer;
|
||||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores =
|
||||
&frames_[current_frame_].render_finished_signal;
|
||||
|
||||
VkResult submit_result =
|
||||
vkQueueSubmit(graphics_queue_, 1, &submit_info,
|
||||
frames_[current_frame_].still_rendering_fence);
|
||||
if (submit_result != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to submit draw commands!");
|
||||
|
||||
VkPresentInfoKHR present_info = {};
|
||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
present_info.waitSemaphoreCount = 1;
|
||||
present_info.pWaitSemaphores =
|
||||
&frames_[current_frame_].render_finished_signal;
|
||||
present_info.swapchainCount = 1;
|
||||
present_info.pSwapchains = &swap_chain_;
|
||||
present_info.pImageIndices = ¤t_image_index_;
|
||||
|
||||
VkResult result = vkQueuePresentKHR(present_queue_, &present_info);
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
||||
RecreateSwapChain();
|
||||
else if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("Failed to present swap chain image!");
|
||||
|
||||
current_frame_ = (current_frame_++) % MAX_BUFFERED_FRAMES;
|
||||
}
|
||||
|
||||
} // namespace veng
|
||||
Reference in New Issue
Block a user