From 3d6ca447a7104c499e92fc954affdaf4bf011388 Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Fri, 16 Sep 2022 12:03:04 -0300 Subject: feat Create View --- src/vk/graphics_pipeline_3d.cpp | 281 ++++++++++++++++++---------------------- 1 file changed, 127 insertions(+), 154 deletions(-) (limited to 'src/vk/graphics_pipeline_3d.cpp') diff --git a/src/vk/graphics_pipeline_3d.cpp b/src/vk/graphics_pipeline_3d.cpp index 31e9365..02fbfd9 100644 --- a/src/vk/graphics_pipeline_3d.cpp +++ b/src/vk/graphics_pipeline_3d.cpp @@ -28,16 +28,16 @@ namespace { void -load_view_projection_uniform_buffer(void *obj) +load_world_vert_uniform_buffer(void *obj) { auto self = static_cast(obj); try { - self->ub_view_projection.reserve(cg_core.vk_swapchain->images_count); + self->ub_world_vert.reserve(cg_core.vk_swapchain->images_count); for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->ub_view_projection.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UBOViewProjection)); + self->ub_world_vert.emplace_back( + cg_core.vk_device_with_swapchain, sizeof(VK::UBOWorld3D_Vert)); } catch(const std::exception& e) { @@ -46,24 +46,24 @@ load_view_projection_uniform_buffer(void *obj) } void -unload_view_projection_uniform_buffer(void *obj) +unload_world_vert_uniform_buffer(void *obj) { auto self = static_cast(obj); - self->ub_view_projection.clear(); + self->ub_world_vert.clear(); } void -load_directional_light_uniform_buffer(void *obj) +load_world_frag_uniform_buffer(void *obj) { auto self = static_cast(obj); try { - self->ub_view_projection.reserve(cg_core.vk_swapchain->images_count); + self->ub_world_frag.reserve(cg_core.vk_swapchain->images_count); for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->ub_directional_light.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UBODirectionalLight)); + self->ub_world_frag.emplace_back( + cg_core.vk_device_with_swapchain, sizeof(VK::UBOWorld3D_Frag)); } catch(const std::exception& e) { @@ -72,11 +72,11 @@ load_directional_light_uniform_buffer(void *obj) } void -unload_directional_light_uniform_buffer(void *obj) +unload_world_frag_uniform_buffer(void *obj) { auto self = static_cast(obj); - self->ub_directional_light.clear(); + self->ub_world_frag.clear(); } void @@ -84,17 +84,18 @@ load_descriptor_pool(void *obj) { auto self = static_cast(obj); + uint32_t uniform_buffers_count = + self->ub_world_vert.size() + self->ub_world_vert.size(); + VkDescriptorPoolSize descriptor_pool_size{}; descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_size.descriptorCount = - self->ub_view_projection.size() + self->ub_directional_light.size(); + descriptor_pool_size.descriptorCount = uniform_buffers_count; VkDescriptorPoolCreateInfo pool_info{}; pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info.pNext = nullptr; pool_info.flags = 0; - pool_info.maxSets = self->ub_view_projection.size() + - self->ub_directional_light.size(); + pool_info.maxSets = uniform_buffers_count; pool_info.poolSizeCount = 1; pool_info.pPoolSizes = &descriptor_pool_size; @@ -115,26 +116,25 @@ unload_descriptor_pool(void *obj) } void -load_world_view_descriptor_sets(void *obj) +load_descriptor_sets_world(void *obj) { auto self = static_cast(obj); std::vector layouts( cg_core.vk_swapchain->images_count, - cg_core.vk_graphics_pipeline_3d_layout->descriptor_set_world_view); + cg_core.vk_graphics_pipeline_3d_layout->descriptor_set_world); VkDescriptorSetAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = self->ub_view_projection.size(); + alloc_info.descriptorSetCount = layouts.size(); alloc_info.pSetLayouts = layouts.data(); - self->world_view_descriptor_sets.resize( - cg_core.vk_swapchain->images_count); + self->descriptor_sets_world.resize(layouts.size()); if(vkAllocateDescriptorSets( cg_core.vk_device_with_swapchain->device, &alloc_info, - self->world_view_descriptor_sets.data()) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan world view descriptor set."}; + self->descriptor_sets_world.data()) != VK_SUCCESS) + throw CommandError{"Failed to create Vulkan world descriptor set."}; } void @@ -142,36 +142,36 @@ load_resources_to_descriptor_sets(void *obj) { auto self = static_cast(obj); - for(auto i{0}; i < self->ub_view_projection.size(); i++) + for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) { - VkDescriptorBufferInfo view_projection_info{}; - view_projection_info.buffer = self->ub_view_projection[i].buffer; - view_projection_info.offset = 0; - view_projection_info.range = sizeof(VK::UBOViewProjection); + VkDescriptorBufferInfo world_vert_info{}; + world_vert_info.buffer = self->ub_world_vert[i].buffer; + world_vert_info.offset = 0; + world_vert_info.range = sizeof(VK::UBOWorld3D_Vert); - VkDescriptorBufferInfo directional_light_info{}; - directional_light_info.buffer = self->ub_directional_light[i].buffer; - directional_light_info.offset = 0; - directional_light_info.range = sizeof(VK::UBODirectionalLight); + VkDescriptorBufferInfo world_frag_info{}; + world_frag_info.buffer = self->ub_world_frag[i].buffer; + world_frag_info.offset = 0; + world_frag_info.range = sizeof(VK::UBOWorld3D_Frag); std::array write_descriptors{}; write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->world_view_descriptor_sets[i]; + write_descriptors[0].dstSet = self->descriptor_sets_world[i]; write_descriptors[0].dstBinding = 0; write_descriptors[0].dstArrayElement = 0; write_descriptors[0].descriptorCount = 1; write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[0].pBufferInfo = &view_projection_info; + write_descriptors[0].pBufferInfo = &world_vert_info; write_descriptors[0].pImageInfo = nullptr; write_descriptors[0].pTexelBufferView = nullptr; write_descriptors[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[1].dstSet = self->world_view_descriptor_sets[i]; + write_descriptors[1].dstSet = self->descriptor_sets_world[i]; write_descriptors[1].dstBinding = 1; write_descriptors[1].dstArrayElement = 0; write_descriptors[1].descriptorCount = 1; write_descriptors[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[1].pBufferInfo = &directional_light_info; + write_descriptors[1].pBufferInfo = &world_frag_info; write_descriptors[1].pImageInfo = nullptr; write_descriptors[1].pTexelBufferView = nullptr; @@ -369,10 +369,10 @@ load_pipeline(void *obj) input_assembly.primitiveRestartEnable = VK_FALSE; VkViewport viewport = {}; - viewport.x = 0.0f; - viewport.y = 0.0f; - viewport.width = static_cast(cg_core.screen_width); - viewport.height = static_cast(cg_core.screen_height); + viewport.x = 0; + viewport.y = 0; + viewport.width = cg_core.screen_width; + viewport.height = cg_core.screen_height; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; @@ -505,13 +505,11 @@ unload_pipeline(void *obj) } const CommandChain loader{ - {&load_view_projection_uniform_buffer, - &unload_view_projection_uniform_buffer}, - {&load_directional_light_uniform_buffer, - &unload_directional_light_uniform_buffer}, + {&load_world_vert_uniform_buffer, &unload_world_vert_uniform_buffer}, + {&load_world_frag_uniform_buffer, &unload_world_frag_uniform_buffer}, {&load_descriptor_pool, &unload_descriptor_pool}, // By destroying the pool the sets are also destroyed. - {&load_world_view_descriptor_sets, nullptr}, + {&load_descriptor_sets_world, nullptr}, {&load_resources_to_descriptor_sets, nullptr}, {&load_depth_image, &unload_depth_image}, {&load_depth_image_view, &unload_depth_image_view}, @@ -524,10 +522,7 @@ const CommandChain loader{ namespace VK { -GraphicsPipeline3D::GraphicsPipeline3D(): - camera_position{std::make_shared(0.0f, 0.0f, 0.0f)}, - camera_rotation{std::make_shared(0.0f, 0.0f, 0.0f)}, - models_to_draw{cg_core.vk_swapchain->images_count} +GraphicsPipeline3D::GraphicsPipeline3D() { loader.execute(this); } @@ -539,138 +534,116 @@ GraphicsPipeline3D::~GraphicsPipeline3D() void GraphicsPipeline3D::draw( - const VkCommandBuffer draw_command_buffer, const size_t current_frame, - const size_t next_frame, const uint32_t image_index) + std::shared_ptr view, const VkCommandBuffer draw_command_buffer, + const size_t current_frame, const uint32_t image_index) { - // Load command. + // Set viewport { - // Dark gray blue. - std::array clear_values{}; - clear_values[0].color = {0.12f, 0.12f, 0.18f, 1.0f}; - clear_values[1].depthStencil = {1.0f, 0}; - - VkRenderPassBeginInfo render_pass_begin{}; - render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = - cg_core.vk_graphics_pipeline_3d_layout->render_pass; - render_pass_begin.framebuffer = this->swapchain_framebuffers[image_index]; - render_pass_begin.renderArea.offset = {0, 0}; - render_pass_begin.renderArea.extent = { - cg_core.screen_width, cg_core.screen_height}; - render_pass_begin.clearValueCount = clear_values.size(); - render_pass_begin.pClearValues = clear_values.data(); - - vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - VkViewport vk_viewport{}; - vk_viewport.width = static_cast(cg_core.screen_width); - vk_viewport.height = static_cast(cg_core.screen_height); + vk_viewport.x = view->region.x; + vk_viewport.y = view->region.y; + vk_viewport.width = view->region.z; + vk_viewport.height = view->region.w; vk_viewport.minDepth = 0.0f; vk_viewport.maxDepth = 1.0f; vkCmdSetViewport(draw_command_buffer, 0, 1, &vk_viewport); VkRect2D vk_scissor{}; - vk_scissor.extent.width = cg_core.screen_width; - vk_scissor.extent.height = cg_core.screen_height; - vk_scissor.offset.x = 0; - vk_scissor.offset.y = 0; + vk_scissor.offset.x = static_cast(view->region.x); + vk_scissor.offset.y = static_cast(view->region.y); + vk_scissor.extent.width = static_cast(view->region.z); + vk_scissor.extent.height = static_cast(view->region.w); vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor); + } - // Draw models - for(auto& [model, instances] : this->models_to_draw[current_frame]) + // Draw models + for(auto& [model, instances]: + cg_core.vk_renderer->models_to_draw[current_frame]) + { + // Commands { - // Commands - { - std::array vk_descriptor_sets{ - this->world_view_descriptor_sets[image_index], - model->descriptor_sets[image_index]}; - VkBuffer vertex_buffers[]{model->vertex_buffer->buffer}; - VkDeviceSize offsets[]{0}; - - vkCmdBindDescriptorSets( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - cg_core.vk_graphics_pipeline_3d_layout->pipeline, 0, - vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); - vkCmdBindPipeline( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->graphic_pipeline); - vkCmdBindVertexBuffers( - draw_command_buffer, 0, 1, vertex_buffers, offsets); - vkCmdBindIndexBuffer( - draw_command_buffer, model->index_buffer->buffer, 0, - VK_INDEX_TYPE_UINT32); - vkCmdDrawIndexed( - draw_command_buffer, model->index_count, instances.size(), 0, 0, 0); - } - - VK::UBOModelInstance ubo_model_instance; - - for(int i{0}; i < instances.size(); i++) - { - // Object matrix. - glm::mat4 instance_matrix{1.0f}; - instance_matrix = glm::translate( - instance_matrix, instances[i].position); - instance_matrix = glm::rotate( - instance_matrix, instances[i].rotation.x, glm::vec3{1.0, 0.0, 0.0}); - instance_matrix = glm::rotate( - instance_matrix, instances[i].rotation.y, glm::vec3{0.0, 1.0, 0.0}); - instance_matrix = glm::rotate( - instance_matrix, instances[i].rotation.z, glm::vec3{0.0, 0.0, 1.0}); - - ubo_model_instance.instances[i] = instance_matrix; - } - - model->ub_model_instance[image_index].copy_data(&ubo_model_instance); + std::array vk_descriptor_sets{ + this->descriptor_sets_world[image_index], + view->descriptor_sets_3d[image_index], + model->descriptor_sets[image_index]}; + VkBuffer vertex_buffers[]{model->vertex_buffer->buffer}; + VkDeviceSize offsets[]{0}; + + vkCmdBindDescriptorSets( + draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + cg_core.vk_graphics_pipeline_3d_layout->pipeline, 0, + vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); + vkCmdBindPipeline( + draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + this->graphic_pipeline); + vkCmdBindVertexBuffers( + draw_command_buffer, 0, 1, vertex_buffers, offsets); + vkCmdBindIndexBuffer( + draw_command_buffer, model->index_buffer->buffer, 0, + VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed( + draw_command_buffer, model->index_count, instances.size(), 0, 0, 0); } - vkCmdEndRenderPass(draw_command_buffer); + VK::UBOModelInstance ubo_model_instance; + + for(int i{0}; i < instances.size(); i++) + { + // Object matrix. + glm::mat4 instance_matrix{1.0f}; + instance_matrix = glm::translate( + instance_matrix, instances[i].position); + instance_matrix = glm::rotate( + instance_matrix, instances[i].rotation.x, glm::vec3{1.0, 0.0, 0.0}); + instance_matrix = glm::rotate( + instance_matrix, instances[i].rotation.y, glm::vec3{0.0, 1.0, 0.0}); + instance_matrix = glm::rotate( + instance_matrix, instances[i].rotation.z, glm::vec3{0.0, 0.0, 1.0}); + + ubo_model_instance.instances[i] = instance_matrix; + } + + model->ub_model_instance[image_index].copy_data(&ubo_model_instance); } - // Update view projection uniform buffers + // Update view uniform buffers { - VK::UBOViewProjection ubo_view_projection{}; + VK::UBOView3D ubo_view_3d{}; // View matrix. - ubo_view_projection.view = glm::mat4{1.0f}; - ubo_view_projection.view = glm::translate( - ubo_view_projection.view, *this->camera_position); - ubo_view_projection.view = glm::rotate( - ubo_view_projection.view, this->camera_rotation->y, - glm::vec3{0.0, 1.0, 0.0}); - ubo_view_projection.view = glm::rotate( - ubo_view_projection.view, this->camera_rotation->x, - glm::vec3{1.0, 0.0, 0.0}); - ubo_view_projection.view = glm::rotate( - ubo_view_projection.view, this->camera_rotation->z, - glm::vec3{0.0, 0.0, 1.0}); - ubo_view_projection.view = glm::inverse(ubo_view_projection.view); + ubo_view_3d.view = glm::mat4{1.0f}; + ubo_view_3d.view = glm::translate( + ubo_view_3d.view, *view->camera_position); + ubo_view_3d.view = glm::rotate( + ubo_view_3d.view, view->camera_rotation->y, glm::vec3{0.0, 1.0, 0.0}); + ubo_view_3d.view = glm::rotate( + ubo_view_3d.view, view->camera_rotation->x, glm::vec3{1.0, 0.0, 0.0}); + ubo_view_3d.view = glm::rotate( + ubo_view_3d.view, view->camera_rotation->z, glm::vec3{0.0, 0.0, 1.0}); + ubo_view_3d.view = glm::inverse(ubo_view_3d.view); // Projection matrix. - ubo_view_projection.proj = glm::perspective( + ubo_view_3d.proj = glm::perspective( glm::radians(45.0f), - cg_core.screen_width / static_cast(cg_core.screen_height), + view->region.z / view->region.w, 0.1f, 100.0f); - ubo_view_projection.proj[1][1] *= -1; + ubo_view_3d.proj[1][1] *= -1; - ubo_view_projection.ambient_color = glm::vec4{0.25, 0.25, 0.25, 1.0}; - - this->ub_view_projection[image_index].copy_data(&ubo_view_projection); + view->ub_3d[image_index].copy_data(&ubo_view_3d); } - // Update directional light uniform buffers + // Update world uniform buffer { - UBODirectionalLight ubo_directional_light{}; - ubo_directional_light.direction = glm::vec3{-0.57735, -0.57735, -0.57735}; - ubo_directional_light.color = glm::vec4{0.8, 0.8, 0.8, 1.0}; - - this->ub_directional_light[image_index].copy_data(&ubo_directional_light); + UBOWorld3D_Vert ubo_world_3d_vert{}; + ubo_world_3d_vert.ambient_light_color = glm::vec4{0.25, 0.25, 0.25, 1.0}; + this->ub_world_vert[image_index].copy_data(&ubo_world_3d_vert); + + UBOWorld3D_Frag ubo_world_3d_frag{}; + ubo_world_3d_frag.directional_light_direction = + glm::vec3{-0.57735, -0.57735, -0.57735}; + ubo_world_3d_frag.directional_light_color = glm::vec4{0.8, 0.8, 0.8, 1.0}; + this->ub_world_frag[image_index].copy_data(&ubo_world_3d_frag); } - - // Prepare for the next frame. - this->models_to_draw[next_frame].clear(); } } -- cgit v1.2.3