From 4bec5afd72fde8edfabba42f9a378135f8b08eed Mon Sep 17 00:00:00 2001 From: Jiga228 Date: Wed, 22 Oct 2025 22:03:34 +0700 Subject: [PATCH] Start 3D. DescriptionPool, DescriptionSets and more other --- Core/Core/CoreInstance.cpp | 2 +- Core/Core/RenderEngine/ModelManager.hpp | 2 +- Core/Core/RenderEngine/RenderEngine.cpp | 147 ++++++++++++++++++++++-- Core/Core/RenderEngine/RenderEngine.hpp | 19 +++ TestGame/Shaders/vertex.vert | 8 +- 5 files changed, 166 insertions(+), 12 deletions(-) diff --git a/Core/Core/CoreInstance.cpp b/Core/Core/CoreInstance.cpp index ae6eb40..2cf21a8 100644 --- a/Core/Core/CoreInstance.cpp +++ b/Core/Core/CoreInstance.cpp @@ -33,7 +33,7 @@ CoreInstance::CoreInstance() countCPU_ = System::getCountCPU(); memorySize_ = System::getMemorySize(); - std::ifstream main_config_file(main_config_name); + std::ifstream main_config_file(main_config_name); std::string payload; if (main_config_file.fail()) diff --git a/Core/Core/RenderEngine/ModelManager.hpp b/Core/Core/RenderEngine/ModelManager.hpp index 77fad10..de9c314 100644 --- a/Core/Core/RenderEngine/ModelManager.hpp +++ b/Core/Core/RenderEngine/ModelManager.hpp @@ -11,7 +11,7 @@ class ModelManager public: struct Voxel { - glm::ivec3 loc, color; + glm::vec3 loc, color; int mass; }; class StaticModel diff --git a/Core/Core/RenderEngine/RenderEngine.cpp b/Core/Core/RenderEngine/RenderEngine.cpp index 6fbbd8c..3eda8c7 100644 --- a/Core/Core/RenderEngine/RenderEngine.cpp +++ b/Core/Core/RenderEngine/RenderEngine.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "Core/CoreInstance.hpp" #include "Log/Log.hpp" @@ -518,6 +519,90 @@ void RenderEngine::create_render_pass() VK_CHECK(vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass_)); } +void RenderEngine::create_description_set_layout() +{ + VkDescriptorSetLayoutBinding ubo_layout_binding{}; + ubo_layout_binding.binding = 0; + ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + ubo_layout_binding.descriptorCount = 1; + ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + ubo_layout_binding.pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo ubo_layout_info{}; + ubo_layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + ubo_layout_info.bindingCount = 1; + ubo_layout_info.pBindings = &ubo_layout_binding; + + VK_CHECK(vkCreateDescriptorSetLayout(device_, &ubo_layout_info, nullptr, &ubo_layout_binding_)); +} + +void RenderEngine::create_uniform_buffers() +{ + uniform_buffers_.resize(swapchain_images_.size()); + uniform_buffers_memory_.resize(swapchain_images_.size()); + uniform_buffers_mapped_.resize(swapchain_images_.size()); + + std::vector arr_indices = get_unique_family_indices(find_queue_family_indices(physical_device_, surface_)); + for (size_t i = 0; i < swapchain_images_.size(); ++i) + { + const VkDeviceSize size = sizeof(UniformBufferObject); + create_buffer(size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, &uniform_buffers_[i], arr_indices); + allocate_memory(uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniform_buffers_memory_[i]); + vkBindBufferMemory(device_, uniform_buffers_[i], uniform_buffers_memory_[i], 0); + + vkMapMemory(device_, uniform_buffers_memory_[i], 0, size, 0, &uniform_buffers_mapped_[i]); + } +} + +void RenderEngine::create_descriptor_pool() +{ + VkDescriptorPoolSize pool_size{}; + pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + pool_size.descriptorCount = static_cast(swapchain_images_.size()); + + VkDescriptorPoolCreateInfo descriptor_pool_info{}; + descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptor_pool_info.poolSizeCount = 1; + descriptor_pool_info.pPoolSizes = &pool_size; + descriptor_pool_info.maxSets = static_cast(swapchain_images_.size()); + + VK_CHECK(vkCreateDescriptorPool(device_, &descriptor_pool_info, nullptr, &descriptor_pool_)); +} + +void RenderEngine::create_descriptor_sets() +{ + std::vector layouts(swapchain_images_.size(), ubo_layout_binding_); + VkDescriptorSetAllocateInfo descriptor_set_allocate_info{}; + descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptor_set_allocate_info.descriptorPool = descriptor_pool_; + descriptor_set_allocate_info.descriptorSetCount = static_cast(swapchain_images_.size()); + descriptor_set_allocate_info.pSetLayouts = layouts.data(); + + descriptor_sets_.resize(swapchain_images_.size()); + VK_CHECK(vkAllocateDescriptorSets(device_, &descriptor_set_allocate_info, descriptor_sets_.data())); + + for (size_t i = 0; i < swapchain_images_.size(); ++i) + { + VkDescriptorBufferInfo buffer_info{}; + buffer_info.buffer = uniform_buffers_[i]; + buffer_info.offset = 0; + buffer_info.range = sizeof(UniformBufferObject); + + VkWriteDescriptorSet write_descriptor_set{}; + write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set.dstSet = descriptor_sets_[i]; + write_descriptor_set.dstBinding = 0; + write_descriptor_set.dstArrayElement = 0; + write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + write_descriptor_set.descriptorCount = 1; + write_descriptor_set.pBufferInfo = &buffer_info; + write_descriptor_set.pImageInfo = nullptr; + write_descriptor_set.pTexelBufferView = nullptr; + + vkUpdateDescriptorSets(device_, 1, &write_descriptor_set, 0, nullptr); + } +} + void RenderEngine::create_graphics_pipeline() { std::ifstream vertex_shader_file("Shaders/vertex.spv", std::ios::binary); @@ -601,7 +686,7 @@ void RenderEngine::create_graphics_pipeline() rasterization_info.polygonMode = VK_POLYGON_MODE_FILL; rasterization_info.lineWidth = 1.0f; rasterization_info.cullMode = VK_CULL_MODE_BACK_BIT; - rasterization_info.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterization_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterization_info.depthBiasEnable = VK_FALSE; VkPipelineMultisampleStateCreateInfo multisample_info{}; @@ -631,6 +716,8 @@ void RenderEngine::create_graphics_pipeline() VkPipelineLayoutCreateInfo pipeline_layout_info{}; pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_info.setLayoutCount = 1; + pipeline_layout_info.pSetLayouts = &ubo_layout_binding_; VK_CHECK(vkCreatePipelineLayout(device_, &pipeline_layout_info, nullptr, &pipeline_layout_)); @@ -703,18 +790,26 @@ uint32_t RenderEngine::find_memory_type(uint32_t typeFilter, VkMemoryPropertyFla throw std::runtime_error("failed to find suitable memory type!"); } -void RenderEngine::allocate_vertex_buffer() +std::vector RenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices) { - QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_); std::set set_indices = {indices.graphics_family.value(), indices.present_family.value(), indices.transfer_family.value()}; + std::vector arr_indices; - std::vector transfer_index = {indices.transfer_family.value()}; arr_indices.reserve(set_indices.size()); for (auto& i : set_indices) arr_indices.push_back(i); + return arr_indices; +} +void RenderEngine::allocate_vertex_buffer() +{ + QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_); + + + std::vector arr_indices = get_unique_family_indices(indices); + std::vector transfer_index = {indices.transfer_family.value()}; VkBuffer staging_buffer = VK_NULL_HANDLE; VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE; @@ -746,11 +841,9 @@ void RenderEngine::allocate_index_buffer() std::set set_indices = {indices.graphics_family.value(), indices.present_family.value(), indices.transfer_family.value()}; - std::vector arr_indices; + + std::vector arr_indices = get_unique_family_indices(indices); std::vector transfer_index = {indices.transfer_family.value()}; - arr_indices.reserve(set_indices.size()); - for (auto& i : set_indices) - arr_indices.push_back(i); VkBuffer staging_buffer = VK_NULL_HANDLE; VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE; @@ -875,6 +968,9 @@ void RenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint32_ VkBuffer vertex_buffers[] = {vertex_buffer_}; VkDeviceSize offset[] = {0}; vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offset); + + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout_, 0, 1, &descriptor_sets_[current_frame_], 0, nullptr); + vkCmdBindIndexBuffer(command_buffer, index_buffer_, 0, VK_INDEX_TYPE_UINT16); VkViewport viewport; @@ -891,13 +987,25 @@ void RenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint32_ scissor.extent = swapchain_extent_; vkCmdSetScissor(command_buffer, 0, 1, &scissor); - //vkCmdDraw(command_buffer, static_cast(vertices_.size()), 1, 0, 0); vkCmdDrawIndexed(command_buffer, static_cast(indices_.size()), 1, 0, 0, 0); vkCmdEndRenderPass(command_buffer); VK_CHECK(vkEndCommandBuffer(command_buffer)); } +void RenderEngine::update_uniform_buffer(uint32_t current_frame) +{ + static auto start_time = std::chrono::high_resolution_clock::now(); + auto current_time = std::chrono::high_resolution_clock::now(); + float time = std::chrono::duration_cast>(current_time - start_time).count(); + UniformBufferObject ubo{}; + ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f)); + ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); + ubo.proj = glm::perspective(glm::radians(45.0f), static_cast(swapchain_extent_.width) / static_cast(swapchain_extent_.height), 0.1f, 256.0f); + ubo.proj[1][1] *= -1; + memcpy(uniform_buffers_mapped_[current_frame], &ubo, sizeof(ubo)); +} + void RenderEngine::draw_frame() { vkWaitForFences(device_, 1, &in_flight_fences_[current_frame_], VK_TRUE, UINT64_MAX); @@ -908,6 +1016,8 @@ void RenderEngine::draw_frame() vkResetCommandBuffer(command_buffers_[current_frame_], 0); record_command_buffer(command_buffers_[current_frame_], image_index); + + update_uniform_buffer(current_frame_); VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo submit_info{}; @@ -955,6 +1065,10 @@ window_(window) create_swapchain(desired_present_mode); create_image_views(); create_render_pass(); + create_description_set_layout(); + create_uniform_buffers(); + create_descriptor_pool(); + create_descriptor_sets(); create_graphics_pipeline(); create_framebuffers(); create_command_pool(); @@ -1004,6 +1118,21 @@ RenderEngine::~RenderEngine() if (pipeline_layout_ != VK_NULL_HANDLE) vkDestroyPipelineLayout(device_, pipeline_layout_, nullptr); + for (size_t i = 0; i < uniform_buffers_.size(); ++i) + { + vkUnmapMemory(device_, uniform_buffers_memory_[i]); + vkFreeMemory(device_, uniform_buffers_memory_[i], nullptr); + vkDestroyBuffer(device_, uniform_buffers_[i], nullptr); + } + uniform_buffers_.clear(); + uniform_buffers_memory_.clear(); + uniform_buffers_mapped_.clear(); + + vkDestroyDescriptorPool(device_, descriptor_pool_, nullptr); + + if (ubo_layout_binding_ != VK_NULL_HANDLE) + vkDestroyDescriptorSetLayout(device_, ubo_layout_binding_, nullptr); + if (render_pass_ != VK_NULL_HANDLE) vkDestroyRenderPass(device_, render_pass_, nullptr); diff --git a/Core/Core/RenderEngine/RenderEngine.hpp b/Core/Core/RenderEngine/RenderEngine.hpp index 2a35d9b..76a33f4 100644 --- a/Core/Core/RenderEngine/RenderEngine.hpp +++ b/Core/Core/RenderEngine/RenderEngine.hpp @@ -8,7 +8,9 @@ #define GLFW_INCLUDE_VULKAN #include +#define GLM_FORCE_RADIANS #include +#include #include "ModelManager.hpp" @@ -42,6 +44,11 @@ class RenderEngine static VkVertexInputBindingDescription get_binding_description(); static std::array get_vertex_attribute_descriptions(); }; + struct UniformBufferObject { + glm::mat4 model; + glm::mat4 view; + glm::mat4 proj; + }; const std::vector vertices_ = { {{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, @@ -76,6 +83,9 @@ class RenderEngine VkExtent2D swapchain_extent_; std::vector swapchain_image_views_; VkRenderPass render_pass_ = VK_NULL_HANDLE; + VkDescriptorSetLayout ubo_layout_binding_ = VK_NULL_HANDLE; + VkDescriptorPool descriptor_pool_ = VK_NULL_HANDLE; + std::vector descriptor_sets_; VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; VkPipeline graphics_pipeline_ = VK_NULL_HANDLE; std::vector framebuffers_; @@ -85,6 +95,9 @@ class RenderEngine VkDeviceMemory vertex_buffer_memory_ = VK_NULL_HANDLE; VkBuffer index_buffer_ = VK_NULL_HANDLE; VkDeviceMemory index_buffer_memory_ = VK_NULL_HANDLE; + std::vector uniform_buffers_; + std::vector uniform_buffers_memory_; + std::vector uniform_buffers_mapped_; // Sync objects std::vector image_available_semaphores_, render_finished_semaphores_; @@ -108,6 +121,7 @@ class RenderEngine VkBuffer* buffer, const std::vector& queue_families); void allocate_memory(VkBuffer buffer, VkMemoryPropertyFlags property, VkDeviceMemory* device_memory); uint32_t find_memory_type(uint32_t typeFilter, VkMemoryPropertyFlags properties) const; + std::vector get_unique_family_indices(const QueueFamilyIndices& indices); void create_instance(); void create_surface(); @@ -116,6 +130,10 @@ class RenderEngine void create_swapchain(VkPresentModeKHR desired_present_mode); void create_image_views(); void create_render_pass(); + void create_description_set_layout(); + void create_uniform_buffers(); + void create_descriptor_pool(); + void create_descriptor_sets(); void create_graphics_pipeline(); void create_framebuffers(); void create_command_pool(); @@ -126,6 +144,7 @@ class RenderEngine void copy_memory(VkBuffer src, VkBuffer dst, VkDeviceSize size); void record_command_buffer(VkCommandBuffer command_buffer, uint32_t image_index) const; + void update_uniform_buffer(uint32_t current_frame); void draw_frame(); public: // Can throw the exception diff --git a/TestGame/Shaders/vertex.vert b/TestGame/Shaders/vertex.vert index 92ceacd..1fdfb51 100644 --- a/TestGame/Shaders/vertex.vert +++ b/TestGame/Shaders/vertex.vert @@ -1,5 +1,11 @@ #version 450 +layout(binding = 0) uniform UniformBufferObject { + mat4 model; + mat4 view; + mat4 proj; +} ubo; + layout(location = 0) in vec2 inPosition; layout(location = 1) in vec3 inColor; @@ -7,6 +13,6 @@ layout(location = 0) out vec3 fragColor; void main() { - gl_Position = vec4(inPosition, 0.0, 1.0); + gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); fragColor = inColor; } \ No newline at end of file