Add draw triangle
This commit is contained in:
+127
-4
@@ -384,12 +384,22 @@ void RenderEngine::create_render_pass()
|
|||||||
subpass_description.colorAttachmentCount = 1;
|
subpass_description.colorAttachmentCount = 1;
|
||||||
subpass_description.pColorAttachments = &attachment_reference;
|
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{};
|
VkRenderPassCreateInfo render_pass_info{};
|
||||||
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
render_pass_info.attachmentCount = 1;
|
render_pass_info.attachmentCount = 1;
|
||||||
render_pass_info.pAttachments = &attachment_description;
|
render_pass_info.pAttachments = &attachment_description;
|
||||||
render_pass_info.subpassCount = 1;
|
render_pass_info.subpassCount = 1;
|
||||||
render_pass_info.pSubpasses = &subpass_description;
|
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_));
|
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;
|
multisample_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState color_blend_attachment_state{};
|
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.blendEnable = VK_TRUE;
|
||||||
color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||||
color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_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()
|
void RenderEngine::allocate_command_buffers()
|
||||||
{
|
{
|
||||||
command_buffers_.resize(MAX_FRAMES_IN_FLIGHT);
|
command_buffers_.resize(swapchain_images_.size());
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo command_buffer_allocate_info{};
|
VkCommandBufferAllocateInfo command_buffer_allocate_info{};
|
||||||
command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_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()));
|
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()
|
void RenderEngine::create_surface()
|
||||||
{
|
{
|
||||||
VK_CHECK(glfwCreateWindowSurface(instance_, window_, nullptr, &surface_));
|
VK_CHECK(glfwCreateWindowSurface(instance_, window_, nullptr, &surface_));
|
||||||
@@ -595,11 +703,26 @@ window_(window)
|
|||||||
create_image_views();
|
create_image_views();
|
||||||
create_render_pass();
|
create_render_pass();
|
||||||
create_graphics_pipeline();
|
create_graphics_pipeline();
|
||||||
|
create_framebuffers();
|
||||||
|
create_command_pool();
|
||||||
|
allocate_command_buffers();
|
||||||
|
create_sync_objects();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderEngine::~RenderEngine()
|
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());
|
vkFreeCommandBuffers(device_, command_pool_, static_cast<uint32_t>(command_buffers_.size()), command_buffers_.data());
|
||||||
|
|
||||||
if (command_pool_ != VK_NULL_HANDLE)
|
if (command_pool_ != VK_NULL_HANDLE)
|
||||||
@@ -649,8 +772,8 @@ void RenderEngine::start()
|
|||||||
{
|
{
|
||||||
while (!glfwWindowShouldClose(window_))
|
while (!glfwWindowShouldClose(window_))
|
||||||
{
|
{
|
||||||
glfwSwapBuffers(window_);
|
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
draw_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ class RenderEngine
|
|||||||
|
|
||||||
static const std::vector<const char*> deviceExtensions;
|
static const std::vector<const char*> deviceExtensions;
|
||||||
|
|
||||||
const int MAX_FRAMES_IN_FLIGHT = 2;
|
|
||||||
int current_frame_ = 0;
|
int current_frame_ = 0;
|
||||||
|
|
||||||
CoreInstance& core_;
|
CoreInstance& core_;
|
||||||
@@ -58,6 +57,9 @@ class RenderEngine
|
|||||||
VkCommandPool command_pool_ = VK_NULL_HANDLE;
|
VkCommandPool command_pool_ = VK_NULL_HANDLE;
|
||||||
std::vector<VkCommandBuffer> command_buffers_;
|
std::vector<VkCommandBuffer> command_buffers_;
|
||||||
|
|
||||||
|
std::vector<VkSemaphore> image_available_semaphores_, render_finished_semaphores_;
|
||||||
|
std::vector<VkFence> in_flight_fences_;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
VkResult enable_layer_validation(VkDebugUtilsMessengerCreateInfoEXT* create_info);
|
VkResult enable_layer_validation(VkDebugUtilsMessengerCreateInfoEXT* create_info);
|
||||||
VkDebugUtilsMessengerEXT debug_messenger_;
|
VkDebugUtilsMessengerEXT debug_messenger_;
|
||||||
@@ -84,7 +86,10 @@ class RenderEngine
|
|||||||
void create_framebuffers();
|
void create_framebuffers();
|
||||||
void create_command_pool();
|
void create_command_pool();
|
||||||
void allocate_command_buffers();
|
void allocate_command_buffers();
|
||||||
|
void create_sync_objects();
|
||||||
|
|
||||||
|
void record_command_buffer(VkCommandBuffer command_buffer, uint32_t image_index);
|
||||||
|
void draw_frame();
|
||||||
public:
|
public:
|
||||||
// Can throw the exception
|
// Can throw the exception
|
||||||
RenderEngine(CoreInstance& core, GLFWwindow* window, VkPresentModeKHR desired_present_mode = VK_PRESENT_MODE_MAILBOX_KHR);
|
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)
|
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})
|
add_executable(${GAME_NAME} ${SRC})
|
||||||
target_link_libraries(${GAME_NAME} PRIVATE Core)
|
target_link_libraries(${GAME_NAME} PRIVATE Core)
|
||||||
|
|||||||
Reference in New Issue
Block a user