From 43821b0cffc5aa419c0218992f06f8962ae54a13 Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Wed, 8 May 2024 17:56:29 -0300 Subject: refa Rename graphical engine to BluCat --- src/blucat/framebuffer.cpp | 198 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 src/blucat/framebuffer.cpp (limited to 'src/blucat/framebuffer.cpp') diff --git a/src/blucat/framebuffer.cpp b/src/blucat/framebuffer.cpp new file mode 100644 index 0000000..e761ff2 --- /dev/null +++ b/src/blucat/framebuffer.cpp @@ -0,0 +1,198 @@ +/* + * Copyright 2022-2024 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "framebuffer.hpp" + +#include "../core.hpp" +#include "image.hpp" + +namespace +{ +void +load_depth_image(void *obj) +{ + auto self = static_cast(obj); + + VkExtent3D extent3d{}; + extent3d.width = cg_core.display_width; + extent3d.height = cg_core.display_height; + extent3d.depth = 1; + + try + { + BluCat::Image::create( + cg_core.vk_device_with_swapchain, + &self->depth_image, + &self->depth_image_memory, + VK_FORMAT_D32_SFLOAT, + extent3d, + 1, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT + ); + } + catch(BluCat::Image::Error error) + { + std::string error_message{"Failed to create depth image → "}; + error_message += error.what(); + throw CommandError{error_message}; + } +} + +void +unload_depth_image(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyImage( + cg_core.vk_device_with_swapchain->device, self->depth_image, + nullptr); + vkFreeMemory( + cg_core.vk_device_with_swapchain->device, + self->depth_image_memory, nullptr); +} + +void +load_depth_image_view(void *obj) +{ + auto self = static_cast(obj); + + try + { + BluCat::Image::create_view( + cg_core.vk_device_with_swapchain, &self->depth_image_view, + self->depth_image, + VK_FORMAT_D32_SFLOAT, VK_IMAGE_ASPECT_DEPTH_BIT); + } + catch(BluCat::Image::Error error) + { + std::string error_message{"Failed to create depth image view → "}; + error_message += error.what(); + throw CommandError{error_message}; + } +} + +void +unload_depth_image_view(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyImageView( + cg_core.vk_device_with_swapchain->device, self->depth_image_view, nullptr); +} + +void +load_3d(void *obj) +{ + auto self = static_cast(obj); + + self->pipeline_3d.resize(cg_core.vk_swapchain->images_count); + for (auto i{0}; i < cg_core.vk_swapchain->images_count; i++) + { + std::array attachments = { + cg_core.vk_swapchain->image_views[i], + self->depth_image_view + }; + + VkFramebufferCreateInfo framebuffer_info{}; + framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebuffer_info.renderPass = cg_core.vk_render_pass->pipeline_3d; + framebuffer_info.attachmentCount = attachments.size(); + framebuffer_info.pAttachments = attachments.data(); + framebuffer_info.width = cg_core.display_width; + framebuffer_info.height = cg_core.display_height; + + framebuffer_info.layers = 1; + + if(vkCreateFramebuffer( + cg_core.vk_device_with_swapchain->device, &framebuffer_info, nullptr, + &self->pipeline_3d[i]) != VK_SUCCESS) + throw CommandError{"Failed to create Vulkan Framebuffer."}; + } +} + +void +unload_3d(void *obj) +{ + auto self = static_cast(obj); + + for(auto framebuffer: self->pipeline_3d) + vkDestroyFramebuffer( + cg_core.vk_device_with_swapchain->device, framebuffer, nullptr); +} + +void +load_2d(void *obj) +{ + auto self = static_cast(obj); + + self->pipeline_2d.resize(cg_core.vk_swapchain->images_count); + for (auto i{0}; i < cg_core.vk_swapchain->images_count; i++) + { + std::array attachments = { + cg_core.vk_swapchain->image_views[i] + }; + + VkFramebufferCreateInfo framebuffer_info{}; + framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebuffer_info.renderPass = cg_core.vk_render_pass->pipeline_2d; + framebuffer_info.attachmentCount = attachments.size(); + framebuffer_info.pAttachments = attachments.data(); + framebuffer_info.width = cg_core.display_width; + framebuffer_info.height = cg_core.display_height; + framebuffer_info.layers = 1; + + if(vkCreateFramebuffer( + cg_core.vk_device_with_swapchain->device, &framebuffer_info, nullptr, + &self->pipeline_2d[i]) + != VK_SUCCESS) + throw CommandError{"Failed to create Vulkan Framebuffer."}; + } +} + +void +unload_2d(void *obj) +{ + auto self = static_cast(obj); + + for(auto framebuffer: self->pipeline_2d) + vkDestroyFramebuffer( + cg_core.vk_device_with_swapchain->device, framebuffer, nullptr); +} + +const CommandChain loader{ + {&load_depth_image, &unload_depth_image}, + {&load_depth_image_view, &unload_depth_image_view}, + {&load_3d, &unload_3d}, + {&load_2d, &unload_2d} +}; + +} + +namespace BluCat +{ + +Framebuffer::Framebuffer() +{ + loader.execute(this); +} + +Framebuffer::~Framebuffer() +{ + loader.revert(this); +} + +} -- cgit v1.2.3