Add draw triangle
This commit is contained in:
+127
-4
@@ -383,6 +383,14 @@ void RenderEngine::create_render_pass()
|
||||
subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass_description.colorAttachmentCount = 1;
|
||||
subpass_description.pColorAttachments = &attachment_reference;
|
||||
|
||||
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 render_pass_info{};
|
||||
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
@@ -390,6 +398,8 @@ void RenderEngine::create_render_pass()
|
||||
render_pass_info.pAttachments = &attachment_description;
|
||||
render_pass_info.subpassCount = 1;
|
||||
render_pass_info.pSubpasses = &subpass_description;
|
||||
render_pass_info.dependencyCount = 1;
|
||||
render_pass_info.pDependencies = &dependency;
|
||||
|
||||
VK_CHECK(vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass_));
|
||||
}
|
||||
@@ -483,7 +493,7 @@ void RenderEngine::create_graphics_pipeline()
|
||||
multisample_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VkPipelineColorBlendAttachmentState color_blend_attachment_state{};
|
||||
color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
color_blend_attachment_state.blendEnable = VK_TRUE;
|
||||
color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
@@ -564,7 +574,7 @@ void RenderEngine::create_command_pool()
|
||||
|
||||
void RenderEngine::allocate_command_buffers()
|
||||
{
|
||||
command_buffers_.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
command_buffers_.resize(swapchain_images_.size());
|
||||
|
||||
VkCommandBufferAllocateInfo command_buffer_allocate_info{};
|
||||
command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
@@ -575,6 +585,104 @@ void RenderEngine::allocate_command_buffers()
|
||||
VK_CHECK(vkAllocateCommandBuffers(device_, &command_buffer_allocate_info, command_buffers_.data()));
|
||||
}
|
||||
|
||||
void RenderEngine::create_sync_objects()
|
||||
{
|
||||
image_available_semaphores_.resize(swapchain_images_.size());
|
||||
render_finished_semaphores_.resize(swapchain_images_.size());
|
||||
in_flight_fences_.resize(swapchain_images_.size());
|
||||
|
||||
VkSemaphoreCreateInfo semaphore_info{};
|
||||
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
|
||||
VkFenceCreateInfo fence_info{};
|
||||
fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
for (size_t i = 0; i < swapchain_images_.size(); ++i)
|
||||
{
|
||||
VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &image_available_semaphores_[i]));
|
||||
VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &render_finished_semaphores_[i]));
|
||||
VK_CHECK(vkCreateFence(device_, &fence_info, nullptr, &in_flight_fences_[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void RenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint32_t image_index)
|
||||
{
|
||||
VkCommandBufferBeginInfo command_buffer_begin_info{};
|
||||
command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
VK_CHECK(vkBeginCommandBuffer(command_buffer, &command_buffer_begin_info));
|
||||
|
||||
const VkClearValue clear_color = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
|
||||
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 = framebuffers_[image_index];
|
||||
render_pass_begin_info.renderArea.offset = {0, 0};
|
||||
render_pass_begin_info.renderArea.extent = swapchain_extent_;
|
||||
render_pass_begin_info.clearValueCount = 1;
|
||||
render_pass_begin_info.pClearValues = &clear_color;
|
||||
vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphycs_pipeline_);
|
||||
|
||||
VkViewport viewport{};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = static_cast<float>(swapchain_extent_.width);
|
||||
viewport.height = static_cast<float>(swapchain_extent_.height);
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor{};
|
||||
scissor.offset = {0, 0};
|
||||
scissor.extent = swapchain_extent_;
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
|
||||
vkCmdDraw(command_buffer, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRenderPass(command_buffer);
|
||||
VK_CHECK(vkEndCommandBuffer(command_buffer));
|
||||
}
|
||||
|
||||
void RenderEngine::draw_frame()
|
||||
{
|
||||
vkWaitForFences(device_, 1, &in_flight_fences_[current_frame_], VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(device_, 1, &in_flight_fences_[current_frame_]);
|
||||
|
||||
uint32_t image_index;
|
||||
vkAcquireNextImageKHR(device_, swapchain_, UINT64_MAX, image_available_semaphores_[current_frame_], VK_NULL_HANDLE, &image_index);
|
||||
|
||||
vkResetCommandBuffer(command_buffers_[current_frame_], 0);
|
||||
record_command_buffer(command_buffers_[current_frame_], image_index);
|
||||
|
||||
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
VkSubmitInfo submit_info{};
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &command_buffers_[current_frame_];
|
||||
submit_info.waitSemaphoreCount = 1;
|
||||
submit_info.pWaitSemaphores = &image_available_semaphores_[current_frame_];
|
||||
submit_info.pWaitDstStageMask = &wait_stage;
|
||||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores = &render_finished_semaphores_[current_frame_];
|
||||
|
||||
VK_CHECK(vkQueueSubmit(graphics_queue_, 1, &submit_info, in_flight_fences_[current_frame_]));
|
||||
|
||||
VkPresentInfoKHR present_info{};
|
||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
present_info.waitSemaphoreCount = 1;
|
||||
present_info.pWaitSemaphores = &render_finished_semaphores_[current_frame_];
|
||||
present_info.swapchainCount = 1;
|
||||
present_info.pSwapchains = &swapchain_;
|
||||
present_info.pImageIndices = &image_index;
|
||||
present_info.pResults = nullptr;
|
||||
|
||||
vkQueuePresentKHR(present_queue_, &present_info);
|
||||
|
||||
current_frame_ = (current_frame_ + 1) % swapchain_images_.size();
|
||||
}
|
||||
|
||||
void RenderEngine::create_surface()
|
||||
{
|
||||
VK_CHECK(glfwCreateWindowSurface(instance_, window_, nullptr, &surface_));
|
||||
@@ -595,11 +703,26 @@ window_(window)
|
||||
create_image_views();
|
||||
create_render_pass();
|
||||
create_graphics_pipeline();
|
||||
create_framebuffers();
|
||||
create_command_pool();
|
||||
allocate_command_buffers();
|
||||
create_sync_objects();
|
||||
}
|
||||
|
||||
RenderEngine::~RenderEngine()
|
||||
{
|
||||
if (command_buffers_.size() > 0)
|
||||
vkDeviceWaitIdle(device_);
|
||||
|
||||
for (auto& i : image_available_semaphores_)
|
||||
vkDestroySemaphore(device_, i, nullptr);
|
||||
|
||||
for (auto& i : render_finished_semaphores_)
|
||||
vkDestroySemaphore(device_, i, nullptr);
|
||||
|
||||
for (auto& i : in_flight_fences_)
|
||||
vkDestroyFence(device_, i, nullptr);
|
||||
|
||||
if (command_buffers_.empty() == false)
|
||||
vkFreeCommandBuffers(device_, command_pool_, static_cast<uint32_t>(command_buffers_.size()), command_buffers_.data());
|
||||
|
||||
if (command_pool_ != VK_NULL_HANDLE)
|
||||
@@ -649,8 +772,8 @@ void RenderEngine::start()
|
||||
{
|
||||
while (!glfwWindowShouldClose(window_))
|
||||
{
|
||||
glfwSwapBuffers(window_);
|
||||
glfwPollEvents();
|
||||
draw_frame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ class RenderEngine
|
||||
|
||||
static const std::vector<const char*> deviceExtensions;
|
||||
|
||||
const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
int current_frame_ = 0;
|
||||
|
||||
CoreInstance& core_;
|
||||
@@ -58,6 +57,9 @@ class RenderEngine
|
||||
VkCommandPool command_pool_ = VK_NULL_HANDLE;
|
||||
std::vector<VkCommandBuffer> command_buffers_;
|
||||
|
||||
std::vector<VkSemaphore> image_available_semaphores_, render_finished_semaphores_;
|
||||
std::vector<VkFence> in_flight_fences_;
|
||||
|
||||
#ifdef _DEBUG
|
||||
VkResult enable_layer_validation(VkDebugUtilsMessengerCreateInfoEXT* create_info);
|
||||
VkDebugUtilsMessengerEXT debug_messenger_;
|
||||
@@ -84,7 +86,10 @@ class RenderEngine
|
||||
void create_framebuffers();
|
||||
void create_command_pool();
|
||||
void allocate_command_buffers();
|
||||
|
||||
void create_sync_objects();
|
||||
|
||||
void record_command_buffer(VkCommandBuffer command_buffer, uint32_t image_index);
|
||||
void draw_frame();
|
||||
public:
|
||||
// Can throw the exception
|
||||
RenderEngine(CoreInstance& core, GLFWwindow* window, VkPresentModeKHR desired_present_mode = VK_PRESENT_MODE_MAILBOX_KHR);
|
||||
|
||||
@@ -2,7 +2,7 @@ set(GAME_NAME TestGame)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
file(GLOB_RECURSE SRC "*.cpp" "*.c" "*.h" "*.hpp" "*.res" "*.world" "*.conf")
|
||||
file(GLOB_RECURSE SRC "*.cpp" "*.c" "*.h" "*.hpp" "*.res" "*.world" "*.conf" "*.frag" "*.vert")
|
||||
|
||||
add_executable(${GAME_NAME} ${SRC})
|
||||
target_link_libraries(${GAME_NAME} PRIVATE Core)
|
||||
|
||||
Reference in New Issue
Block a user