Merge pull request #3 from Jiga228/render

Render
This commit is contained in:
Danil
2025-10-22 22:06:39 +07:00
committed by GitHub
5 changed files with 219 additions and 15 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ class ModelManager
public:
struct Voxel
{
glm::ivec3 loc, color;
glm::vec3 loc, color;
int mass;
};
class StaticModel
+177 -5
View File
@@ -4,6 +4,7 @@
#include <set>
#include <stdexcept>
#include <fstream>
#include <chrono>
#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<uint32_t> 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<uint32_t>(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<uint32_t>(swapchain_images_.size());
VK_CHECK(vkCreateDescriptorPool(device_, &descriptor_pool_info, nullptr, &descriptor_pool_));
}
void RenderEngine::create_descriptor_sets()
{
std::vector<VkDescriptorSetLayout> 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<uint32_t>(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<uint32_t> RenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices)
{
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_);
std::set<uint32_t> set_indices = {indices.graphics_family.value(),
indices.present_family.value(),
indices.transfer_family.value()};
std::vector<uint32_t> arr_indices;
std::vector<uint32_t> 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<uint32_t> arr_indices = get_unique_family_indices(indices);
std::vector<uint32_t> transfer_index = {indices.transfer_family.value()};
VkBuffer staging_buffer = VK_NULL_HANDLE;
VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE;
@@ -740,6 +835,38 @@ void RenderEngine::allocate_vertex_buffer()
vkDestroyBuffer(device_, staging_buffer, nullptr);
}
void RenderEngine::allocate_index_buffer()
{
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_);
std::set<uint32_t> set_indices = {indices.graphics_family.value(),
indices.present_family.value(),
indices.transfer_family.value()};
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
std::vector<uint32_t> transfer_index = {indices.transfer_family.value()};
VkBuffer staging_buffer = VK_NULL_HANDLE;
VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE;
VkDeviceSize size_buffer = sizeof(indices_[0]) * indices_.size();
create_buffer(size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &staging_buffer, transfer_index);
allocate_memory(staging_buffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &staging_buffer_memory);
vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0);
void* data;
vkMapMemory(device_, staging_buffer_memory, 0, size_buffer, 0, &data);
memcpy(data, indices_.data(), size_buffer);
vkUnmapMemory(device_, staging_buffer_memory);
create_buffer(size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, &index_buffer_, arr_indices);
allocate_memory(index_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &index_buffer_memory_);
vkBindBufferMemory(device_, index_buffer_, index_buffer_memory_, 0);
copy_memory(staging_buffer, index_buffer_, size_buffer);
vkDestroyBuffer(device_, staging_buffer, nullptr);
vkFreeMemory(device_, staging_buffer_memory, nullptr);
}
void RenderEngine::copy_memory(VkBuffer src, VkBuffer dst, VkDeviceSize size)
{
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_);
@@ -842,6 +969,10 @@ void RenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint32_
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;
viewport.x = 0.0f;
viewport.y = 0.0f;
@@ -856,12 +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<uint32_t>(vertices_.size()), 1, 0, 0);
vkCmdDrawIndexed(command_buffer, static_cast<uint32_t>(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<std::chrono::duration<float>>(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<float>(swapchain_extent_.width) / static_cast<float>(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);
@@ -873,6 +1017,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{};
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@@ -919,11 +1065,16 @@ 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();
allocate_vertex_buffer();
allocate_command_buffers();
allocate_index_buffer();
create_sync_objects();
}
@@ -931,6 +1082,12 @@ RenderEngine::~RenderEngine()
{
vkDeviceWaitIdle(device_);
if (index_buffer_memory_ != VK_NULL_HANDLE)
vkFreeMemory(device_, index_buffer_memory_, nullptr);
if (index_buffer_ != VK_NULL_HANDLE)
vkDestroyBuffer(device_, index_buffer_, nullptr);
if (vertex_buffer_memory_ != VK_NULL_HANDLE)
vkFreeMemory(device_, vertex_buffer_memory_, nullptr);
@@ -961,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);
+32 -6
View File
@@ -8,7 +8,9 @@
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "ModelManager.hpp"
@@ -35,7 +37,6 @@ class RenderEngine
std::vector<VkSurfaceFormatKHR> formats;
std::vector<VkPresentModeKHR> present_modes;
};
struct Vertex
{
glm::vec2 pos;
@@ -43,10 +44,20 @@ class RenderEngine
static VkVertexInputBindingDescription get_binding_description();
static std::array<VkVertexInputAttributeDescription, 2> get_vertex_attribute_descriptions();
};
std::vector<Vertex> vertices_ = {
{{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}},
{{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}},
{{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}
struct UniformBufferObject {
glm::mat4 model;
glm::mat4 view;
glm::mat4 proj;
};
const std::vector<Vertex> vertices_ = {
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},
{{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}},
{{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}},
{{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}}
};
const std::vector<uint16_t> indices_ = {
0, 1, 2, 2, 3, 0
};
ModelManager model_manager_;
@@ -72,6 +83,9 @@ class RenderEngine
VkExtent2D swapchain_extent_;
std::vector<VkImageView> swapchain_image_views_;
VkRenderPass render_pass_ = VK_NULL_HANDLE;
VkDescriptorSetLayout ubo_layout_binding_ = VK_NULL_HANDLE;
VkDescriptorPool descriptor_pool_ = VK_NULL_HANDLE;
std::vector<VkDescriptorSet> descriptor_sets_;
VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE;
VkPipeline graphics_pipeline_ = VK_NULL_HANDLE;
std::vector<VkFramebuffer> framebuffers_;
@@ -79,6 +93,11 @@ class RenderEngine
std::vector<VkCommandBuffer> command_buffers_;
VkBuffer vertex_buffer_ = VK_NULL_HANDLE;
VkDeviceMemory vertex_buffer_memory_ = VK_NULL_HANDLE;
VkBuffer index_buffer_ = VK_NULL_HANDLE;
VkDeviceMemory index_buffer_memory_ = VK_NULL_HANDLE;
std::vector<VkBuffer> uniform_buffers_;
std::vector<VkDeviceMemory> uniform_buffers_memory_;
std::vector<void*> uniform_buffers_mapped_;
// Sync objects
std::vector<VkSemaphore> image_available_semaphores_, render_finished_semaphores_;
@@ -102,6 +121,7 @@ class RenderEngine
VkBuffer* buffer, const std::vector<uint32_t>& 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<uint32_t> get_unique_family_indices(const QueueFamilyIndices& indices);
void create_instance();
void create_surface();
@@ -110,15 +130,21 @@ 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();
void allocate_command_buffers();
void create_sync_objects();
void allocate_vertex_buffer();
void copy_memory(VkBuffer src, VkBuffer dst, VkDeviceSize size);
void allocate_index_buffer();
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
+7 -1
View File
@@ -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;
}