diff --git a/noteForDevelop.md b/noteForDevelop.md index 530fd01..9ec463b 100644 --- a/noteForDevelop.md +++ b/noteForDevelop.md @@ -16,10 +16,11 @@ #define _VULKANFOUNDATION_H #endif // !VULKANFOUNDATION_H -#ifndef _UI_HPP -#include "ui.hpp" -#define _UI_HPP -#endif // !UI_HPP +#ifndef _RENDERGUI_H +#include "renderUI.h" +#define _RENDERGUI_H +#endif // !_RENDERGUI_H + #ifndef _PBR_H #include "PBR.h" @@ -36,4 +37,34 @@ #define _RENDERIO_H #endif // !RENDERIO_H +#ifndef _UI_HPP +#include "ui.hpp" +#define _UI_HPP +#endif // !UI_HPP + +#ifndef _VULKANDEVICE_HPP +#include "VulkanDevice.hpp" +#define _VULKANDEVICE_HPP +#endif // !_VULKANDEVICE_HPP + +#ifndef _CAMERA_HPP +#include "camera.hpp" +#define _CAMERA_HPP +#endif // !_CAMERA_HPP + +#ifndef _VULKANTEXTURE_HPP +#include "VulkanTexture.hpp" +#define _VULKANTEXTURE_HPP +#endif // !_VULKANTEXTURE_HPP + +#ifndef _VULKANUTILS_HPP +#include "VulkanUtils.hpp" +#define _VULKANUTILS_HPP +#endif // !_VULKANUTILS_HPP + +#ifndef _TINY_GLTF_H +#include "tiny_gltf.h" +#define _TINY_GLTF_H +#endif // !_TINY_GLTF_H + ``` \ No newline at end of file diff --git a/src/render/PBR.h b/src/render/PBR.h index f84cec5..9e88935 100644 --- a/src/render/PBR.h +++ b/src/render/PBR.h @@ -1,18 +1,31 @@ #pragma once -#ifndef _RENDER_H -#include "render.h" -#define _RENDER_H -#endif // !RENDER_H +#ifndef _RENDERSETTER_H +#include "renderSetter.h" +#define _RENDERSETTER_H +#endif // !RENDERSETTER_H #ifndef _VULKANFOUNDATION_H #include "vulkanFoundation.h" #define _VULKANFOUNDATION_H #endif // !VULKANFOUNDATION_H +#ifndef _RENDER_H +#include "render.h" +#define _RENDER_H +#endif // !RENDER_H -#include "glm/glm.hpp" -#include + + + + + +#include + +#ifndef _VULKANTEXTURE_HPP +#include "VulkanTexture.hpp" +#define _VULKANTEXTURE_HPP +#endif // !_VULKANTEXTURE_HPP diff --git a/src/render/glTFModel.h b/src/render/glTFModel.h index be79bf9..7c2f7af 100644 --- a/src/render/glTFModel.h +++ b/src/render/glTFModel.h @@ -30,18 +30,25 @@ #define TINYGLTF_ANDROID_LOAD_FROM_ASSETS #endif - +#ifndef _TINY_GLTF_H #include "tiny_gltf.h" +#define _TINY_GLTF_H +#endif // !_TINY_GLTF_H + + +#ifndef _VULKANDEVICE_HPP #include "VulkanDevice.hpp" +#define _VULKANDEVICE_HPP +#endif // !_VULKANDEVICE_HPP //#include "VulkanUtils.hpp" -#include "vulkan/vulkan.h" +#include #ifndef _VULKANFOUNDATION_H #include "vulkanFoundation.h" #define _VULKANFOUNDATION_H #endif // !VULKANFOUNDATION_H -#define ENABLE_VALIDATION false + #define MAX_NUM_JOINTS 128u // Contains everything required to render a glTF model in Vulkan diff --git a/src/render/render.cpp b/src/render/render.cpp index b6b4b6f..a2753f2 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -36,12 +36,6 @@ void PlumageRender::renderMain::framebufferResizeCallback(GLFWwindow* window, in } -// todo:重写成glfw的 -void PlumageRender::renderMain::windowResized() - { - - } - void PlumageRender::renderMain::prepare() { //VulkanExampleBase::prepare(); @@ -94,15 +88,15 @@ void PlumageRender::renderMain::submitToPresentQueue() } -void PlumageRender::renderMain::render() +void PlumageRender::renderMain::render(Setter setter,UI* plumageGUI) { if (!prepared) { return; } - if (!PlumageRender::Setter::settings.headless) + if (!setter.settings.headless) { - renderGUI.updateUIOverlay(); + plumageGUI.updateUIOverlay(); } uint32_t imageIndex; @@ -155,11 +149,11 @@ void PlumageRender::renderMain::render() } - void PlumageRender::renderMain::renderLoop(GLFWwindow* window) + void PlumageRender::renderMain::renderLoop(GLFWwindow* window,Setter setter) { - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { - uint32_t frameRange = PlumageRender::Setter::settings.endFrameIndex - PlumageRender::Setter::settings.startFrameCount; + uint32_t frameRange =setter.getFrameRange(); for (size_t i = 0; i < frameRange; i++) { drawFrame(); diff --git a/src/render/render.h b/src/render/render.h index 601aeb0..e886f5c 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -18,7 +18,10 @@ #include +#ifndef _GLFW3_H #include "GLFW/glfw3.h" +#define _GLFW3_H +#endif // !_GLFW3_H #ifndef _GLTFMODEL_H @@ -36,21 +39,50 @@ #define _VULKANFOUNDATION_H #endif // !VULKANFOUNDATION_H +#ifndef _RENDERGUI_H +#include "renderUI.h" +#define _RENDERGUI_H +#endif // !_RENDERGUI_H + #ifndef _UI_HPP #include "ui.hpp" #define _UI_HPP #endif // !UI_HPP +#ifndef _RENDERIO_H +#include "renderIO.h" +#define _RENDERIO_H +#endif // !RENDERIO_H - +#ifndef _VULKANDEVICE_HPP #include "VulkanDevice.hpp" +#define _VULKANDEVICE_HPP +#endif // !_VULKANDEVICE_HPP -#include -#include -#include +#ifndef _CAMERA_HPP +#include "camera.hpp" +#define _CAMERA_HPP +#endif // !_CAMERA_HPP +#ifndef _VULKANTEXTURE_HPP +#include "VulkanTexture.hpp" +#define _VULKANTEXTURE_HPP +#endif // !_VULKANTEXTURE_HPP + +#ifndef _VULKANUTILS_HPP +#include "VulkanUtils.hpp" +#define _VULKANUTILS_HPP +#endif // !_VULKANUTILS_HPP + +#ifndef _STB_IMAGE_WRITE_H #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" +#define _STB_IMAGE_WRITE_H +#endif // !_STB_IMAGE_WRITE_H + + + + #define ENABLE_VALIDATION false @@ -116,7 +148,7 @@ namespace PlumageRender void submitToPresentQueue(); virtual void render(); - void renderLoop(GLFWwindow* window); + void renderLoop(GLFWwindow* window, Setter setter); void drawFrame(); private: diff --git a/src/render/renderIO.cpp b/src/render/renderIO.cpp index 249bdf2..184f369 100644 --- a/src/render/renderIO.cpp +++ b/src/render/renderIO.cpp @@ -27,7 +27,7 @@ void PlumageRender::RenderInput::loadEnvironment(std::string fileName,PBR::Mater pbrMaterial.generateCubemap(vkFoundation,setter,mainRender); } -void PlumageRender::RenderInput::loadAssets(Setter setter,renderMain mainRender,VulkanBackend::VulkanFoundation vkFoundation) +void PlumageRender::RenderInput::loadAssets(Setter setter,renderMain mainRender,VulkanBackend::VulkanFoundation vkFoundation,PBR::Material pbrMaterial) { const std::string assetpath = getAssetPath(); @@ -53,12 +53,12 @@ void PlumageRender::RenderInput::loadAssets(Setter setter,renderMain mainRender, loadScene(sceneFile.c_str(),mainRender,vkFoundation); mainRender.models.skybox.loadFromFile(setter.filePath.skyboxModleFilePath, vkFoundation.vulkanDevice, vkFoundation.graphicQueue); - loadEnvironment(envMapFile.c_str()); + loadEnvironment(envMapFile.c_str(),pbrMaterial,setter,vkFoundation,mainRender); } // todo :根据physicalDeviceIndex确定子文件夹路径,frameIndex确定fileName // 移动到fileSystem里 -void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) +void PlumageRender::RenderOutput::writeImageToFile(std::string filePath, VulkanBackend::VulkanFoundation vkFoundation,Setter setter) { bool screenshotSaved = false; @@ -68,33 +68,33 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) VkFormatProperties formatProps; // Check if the device supports blitting from optimal images (the swapchain images are in optimal format) - vkGetPhysicalDeviceFormatProperties(VulkanBackend::VulkanFoundation::physicalDevice, VulkanBackend::VulkanFoundation::swapChainImageFormat, &formatProps); + vkGetPhysicalDeviceFormatProperties(vkFoundation.physicalDevice, vkFoundation.swapChainImageFormat, &formatProps); if (!(formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT)) { std::cerr << "Device does not support blitting from optimal tiled images, using copy instead of blit!" << std::endl; supportsBlit = false; } // Check if the device supports blitting to linear images - vkGetPhysicalDeviceFormatProperties(VulkanBackend::VulkanFoundation::physicalDevice, VK_FORMAT_R8G8B8A8_UNORM, &formatProps); + vkGetPhysicalDeviceFormatProperties(vkFoundation.physicalDevice, VK_FORMAT_R8G8B8A8_UNORM, &formatProps); if (!(formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT)) { std::cerr << "Device does not support blitting to linear tiled images, using copy instead of blit!" << std::endl; supportsBlit = false; } // Source for the copy is the last rendered swapchain image - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { - VkImage srcImage = VulkanBackend::VulkanFoundation::colorAttachment.image; + VkImage srcImage = vkFoundation.colorAttachment.image; } - VkImage srcImage = VulkanBackend::VulkanFoundation::swapChainImages[PlumageRender::renderMain::currentBuffer]; + VkImage srcImage = vkFoundation.swapChainImages[PlumageRender::renderMain::currentBuffer]; // Create the linear tiled destination image to copy to and to read the memory from VkImageCreateInfo imageCreateCI(vks::initializers::imageCreateInfo()); imageCreateCI.imageType = VK_IMAGE_TYPE_2D; // Note that vkCmdBlitImage (if supported) will also do format conversions if the swapchain color format would differ imageCreateCI.format = VK_FORMAT_R8G8B8A8_UNORM; - imageCreateCI.extent.width = PlumageRender::Setter::settings.width; - imageCreateCI.extent.height = PlumageRender::Setter::settings.height; + imageCreateCI.extent.width = setter.settings.width; + imageCreateCI.extent.height = setter.settings.height; imageCreateCI.extent.depth = 1; imageCreateCI.arrayLayers = 1; imageCreateCI.mipLevels = 1; @@ -104,20 +104,20 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) imageCreateCI.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; // Create the image VkImage dstImage; - VK_CHECK_RESULT(vkCreateImage(VulkanBackend::VulkanFoundation::device, &imageCreateCI, nullptr, &dstImage)); + VK_CHECK_RESULT(vkCreateImage(vkFoundation.device, &imageCreateCI, nullptr, &dstImage)); // Create memory to back up the image VkMemoryRequirements memRequirements; VkMemoryAllocateInfo memAllocInfo(vks::initializers::memoryAllocateInfo()); VkDeviceMemory dstImageMemory; - vkGetImageMemoryRequirements(VulkanBackend::VulkanFoundation::device, dstImage, &memRequirements); + vkGetImageMemoryRequirements(vkFoundation.device, dstImage, &memRequirements); memAllocInfo.allocationSize = memRequirements.size; // Memory must be host visible to copy from - memAllocInfo.memoryTypeIndex = VulkanBackend::VulkanFoundation::vulkanDevice->getMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - VK_CHECK_RESULT(vkAllocateMemory(VulkanBackend::VulkanFoundation::device, &memAllocInfo, nullptr, &dstImageMemory)); - VK_CHECK_RESULT(vkBindImageMemory(VulkanBackend::VulkanFoundation::device, dstImage, dstImageMemory, 0)); + memAllocInfo.memoryTypeIndex = vkFoundation.vulkanDevice->getMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + VK_CHECK_RESULT(vkAllocateMemory(vkFoundation.device, &memAllocInfo, nullptr, &dstImageMemory)); + VK_CHECK_RESULT(vkBindImageMemory(vkFoundation.device, dstImage, dstImageMemory, 0)); // Do the actual blit from the swapchain image to our host visible destination image - VkCommandBuffer copyCmd = VulkanBackend::VulkanFoundation::vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); + VkCommandBuffer copyCmd = vkFoundation.vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); // Transition destination image to transfer destination layout vks::tools::insertImageMemoryBarrier( @@ -131,7 +131,7 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) VK_PIPELINE_STAGE_TRANSFER_BIT, VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); - if (!PlumageRender::Setter::settings.headless) + if (!setter.settings.headless) { // Transition swapchain image from present to transfer source layout vks::tools::insertImageMemoryBarrier( @@ -153,8 +153,8 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) { // Define the region to blit (we will blit the whole swapchain image) VkOffset3D blitSize; - blitSize.x = PlumageRender::Setter::settings.width; - blitSize.y = PlumageRender::Setter::settings.height; + blitSize.x = setter.settings.width; + blitSize.y = setter.settings.height; blitSize.z = 1; VkImageBlit imageBlitRegion{}; imageBlitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -181,8 +181,8 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) imageCopyRegion.srcSubresource.layerCount = 1; imageCopyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageCopyRegion.dstSubresource.layerCount = 1; - imageCopyRegion.extent.width = PlumageRender::Setter::settings.width; - imageCopyRegion.extent.height = PlumageRender::Setter::settings.height; + imageCopyRegion.extent.width = setter.settings.width; + imageCopyRegion.extent.height = setter.settings.height; imageCopyRegion.extent.depth = 1; // Issue the copy command @@ -206,7 +206,7 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) VK_PIPELINE_STAGE_TRANSFER_BIT, VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); - if (!PlumageRender::Setter::settings.headless) + if (!setter.settings.headless) { // Transition back the swap chain image after the blit is done vks::tools::insertImageMemoryBarrier( @@ -221,16 +221,16 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); } - VulkanBackend::VulkanFoundation::vulkanDevice->flushCommandBuffer(copyCmd, VulkanBackend::VulkanFoundation::graphicQueue); + vkFoundation.vulkanDevice->flushCommandBuffer(copyCmd, vkFoundation.graphicQueue); // Get layout of the image (including row pitch) VkImageSubresource subResource{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }; VkSubresourceLayout subResourceLayout; - vkGetImageSubresourceLayout(VulkanBackend::VulkanFoundation::device, dstImage, &subResource, &subResourceLayout); + vkGetImageSubresourceLayout(vkFoundation.device, dstImage, &subResource, &subResourceLayout); // Map image memory so we can start copying from it const char* data; - vkMapMemory(VulkanBackend::VulkanFoundation::device, dstImageMemory, 0, VK_WHOLE_SIZE, 0, (void**)&data); + vkMapMemory(vkFoundation.device, dstImageMemory, 0, VK_WHOLE_SIZE, 0, (void**)&data); data += subResourceLayout.offset; // If source is BGR (destination is always RGB) and we can't use blit (which does automatic conversion), we'll have to manually swizzle color components @@ -240,19 +240,19 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) if (!supportsBlit) { std::vector formatsBGR = { VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SNORM }; - colorSwizzle = (std::find(formatsBGR.begin(), formatsBGR.end(), VulkanBackend::VulkanFoundation::swapChainImageFormat) != formatsBGR.end()); + colorSwizzle = (std::find(formatsBGR.begin(), formatsBGR.end(), vkFoundation.swapChainImageFormat) != formatsBGR.end()); } - if (PlumageRender::Setter::settings.outputPNGimage) + if (setter.settings.outputPNGimage) { if (colorSwizzle) { // 暂时不改,此处需要将BGR通道改成RGB格式 - stbi_write_png(filePath.c_str(), PlumageRender::Setter::settings.width, PlumageRender::Setter::settings.height, 4, data, static_cast(subResourceLayout.rowPitch)); + stbi_write_png(filePath.c_str(), setter.settings.width, setter.settings.height, 4, data, static_cast(subResourceLayout.rowPitch)); } else { - stbi_write_png(filePath.c_str(), PlumageRender::Setter::settings.width, PlumageRender::Setter::settings.height, 4, data, static_cast(subResourceLayout.rowPitch)); + stbi_write_png(filePath.c_str(), setter.settings.width, setter.settings.height, 4, data, static_cast(subResourceLayout.rowPitch)); } } @@ -262,13 +262,13 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) std::ofstream file(filePath, std::ios::out | std::ios::binary); // ppm header - file << "P6\n" << PlumageRender::Setter::settings.width << "\n" << PlumageRender::Setter::settings.height << "\n" << 255 << "\n"; + file << "P6\n" << setter.settings.width << "\n" << setter.settings.height << "\n" << 255 << "\n"; // ppm binary pixel data - for (uint32_t y = 0; y < PlumageRender::Setter::settings.height; y++) + for (uint32_t y = 0; y < setter.settings.height; y++) { unsigned int* row = (unsigned int*)data; - for (uint32_t x = 0; x < PlumageRender::Setter::settings.width; x++) + for (uint32_t x = 0; x < setter.settings.width; x++) { if (colorSwizzle) { @@ -291,68 +291,68 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) std::cout << "Screenshot saved to " << filePath << std::endl; // Clean up resources - vkUnmapMemory(VulkanBackend::VulkanFoundation::device, dstImageMemory); - vkFreeMemory(VulkanBackend::VulkanFoundation::device, dstImageMemory, nullptr); - vkDestroyImage(VulkanBackend::VulkanFoundation::device, dstImage, nullptr); + vkUnmapMemory(vkFoundation.device, dstImageMemory); + vkFreeMemory(vkFoundation.device, dstImageMemory, nullptr); + vkDestroyImage(vkFoundation.device, dstImage, nullptr); screenshotSaved = true; } -void PlumageRender::RenderOutput::outputImageSequence() +void PlumageRender::RenderOutput::outputImageSequence(Setter setter,RenderOutput renderOutput, VulkanBackend::VulkanFoundation vkFoundation) { // 比较已保存的帧数和设置里的开始帧数,在生成前清理上一次生成的图片序列 - if (savedFrameCounter == PlumageRender::Setter::settings.startFrameCount) + if (savedFrameCounter == setter.settings.startFrameCount) { std::cout << "clean up directory for image sequence generation" << std::endl; - removeImageSequence(); + removeImageSequence(setter,renderOutput); } // 根据显卡编号设置输出路径(todo:提前到配置里) - PlumageRender::Setter::filePath.deviceSpecFilePath = PlumageRender::Setter::filePath.imageOutputPath + "/device" + std::to_string(PlumageRender::Setter::settings.selectedPhysicalDeviceIndex); + setter.filePath.deviceSpecFilePath = setter.filePath.imageOutputPath + "/device" + std::to_string(setter.settings.selectedPhysicalDeviceIndex); // 非第一次生成,生成结束的边界条件 - if (savedFrameCounter > PlumageRender::Setter::settings.endFrameIndex) + if (savedFrameCounter > setter.settings.endFrameIndex) { // 避免重复改变为true带来的无效性能开销 - if (PlumageRender::RenderOutput::signal.imageSequenceOutputComplete) + if (renderOutput.signal.imageSequenceOutputComplete) { return; } // 生成结束的信号标志置为true - PlumageRender::RenderOutput::signal.imageSequenceOutputComplete = true; + renderOutput.signal.imageSequenceOutputComplete = true; // 构造ffmpeg脚本需要的路径变量(提前到配置) std::string fileName = "/%dresult.ppm"; - PlumageRender::Setter::filePath.totalImageOutputPath = PlumageRender::Setter::filePath.deviceSpecFilePath + fileName; + setter.filePath.totalImageOutputPath = setter.filePath.deviceSpecFilePath + fileName; return; } // 路径存在性检查,不存在则创建 - if (!std::filesystem::exists(PlumageRender::Setter::filePath.deviceSpecFilePath.c_str())) + if (!std::filesystem::exists(setter.filePath.deviceSpecFilePath.c_str())) { - std::filesystem::create_directories(PlumageRender::Setter::filePath.deviceSpecFilePath.c_str()); + std::filesystem::create_directories(setter.filePath.deviceSpecFilePath.c_str()); } // 拼接图片序列编号到路径里 std::string fileName = "/" + std::to_string(savedFrameCounter) + "result.ppm"; - PlumageRender::Setter::filePath.totalImageOutputPath = PlumageRender::Setter::filePath.deviceSpecFilePath + fileName; + setter.filePath.totalImageOutputPath = setter.filePath.deviceSpecFilePath + fileName; //std::cout << outputPath << std::endl; // 写入文件 - writeImageToFile(PlumageRender::Setter::filePath.totalImageOutputPath.c_str()); + writeImageToFile(setter.filePath.totalImageOutputPath.c_str(),vkFoundation,setter); // 写入一帧后已保存帧数+1 savedFrameCounter++; } -void PlumageRender::RenderOutput::imageSequenceToVideo() +void PlumageRender::RenderOutput::imageSequenceToVideo(RenderOutput renderOutput,Setter setter) { // 边界条件,图片序列输出未完成 - if (!PlumageRender::RenderOutput::signal.imageSequenceOutputComplete) + if (!renderOutput.signal.imageSequenceOutputComplete) { return; } // 边界条件,图片序列到视频的输出已完成 - if (PlumageRender::RenderOutput::signal.imageSequenceToVideoComplete) + if (renderOutput.signal.imageSequenceToVideoComplete) { return; } // 拼接视频保存的设备编号路径(提前到配置文件进行) - std::string deviceFilePath = PlumageRender::Setter::filePath.videoOutputPath + "/device" + std::to_string(PlumageRender::Setter::settings.selectedPhysicalDeviceIndex); + std::string deviceFilePath = setter.filePath.videoOutputPath + "/device" + std::to_string(setter.settings.selectedPhysicalDeviceIndex); // 判断路径是否存在,不存在则创建 if (std::filesystem::exists(deviceFilePath.c_str())) { @@ -361,40 +361,40 @@ void PlumageRender::RenderOutput::imageSequenceToVideo() // 构造结果视频路径 std::string resultVideoPath = deviceFilePath + "/result.mp4"; // 构造脚本需要参数,图片序列路径和设定的帧率 - std::string commandLineImageSequencePath = PlumageRender::Setter::filePath.totalImageOutputPath; + std::string commandLineImageSequencePath = setter.filePath.totalImageOutputPath; //std::string commandLineCodecAndResultPath = resultVideoPath; - std::string commandLineFrameRate = std::to_string(PlumageRender::Setter::settings.videoFrameRate); + std::string commandLineFrameRate = std::to_string(setter.settings.videoFrameRate); // 根据不同系统使用不同脚本 #if defined(_WIN32) - std::string commandLine = PlumageRender::Setter::filePath.image2videoBatFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath; + std::string commandLine = setter.filePath.image2videoBatFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath; #else std::string commandLine = filePath.image2videoShFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath; #endif std::cout << commandLine << std::endl; std::system(commandLine.c_str()); // 视频输出完成,置标志为true - PlumageRender::RenderOutput::signal.imageSequenceToVideoComplete = true; + renderOutput.signal.imageSequenceToVideoComplete = true; std::cout << "vidoe codec complete,saved in:" << resultVideoPath << std::endl; std::cout << "star to clean up image sequence" << std::endl; - removeImageSequence(); + removeImageSequence(setter,renderOutput); } -void PlumageRender::RenderOutput::removeImageSequence() +void PlumageRender::RenderOutput::removeImageSequence(Setter setter,RenderOutput renderOutput) { // 函数非第一次运行的边界条件 - if (savedFrameCounter != PlumageRender::Setter::settings.startFrameCount) + if (savedFrameCounter != setter.settings.startFrameCount) { // 检查视频输出完成的标志位 - if (!PlumageRender::RenderOutput::signal.imageSequenceToVideoComplete) + if (!renderOutput.signal.imageSequenceToVideoComplete) { return; } } // 遍历删除图片序列文件和空文件夹 - if (std::filesystem::exists(PlumageRender::Setter::filePath.deviceSpecFilePath)) + if (std::filesystem::exists(setter.filePath.deviceSpecFilePath)) { - for (const auto& entry : std::filesystem::directory_iterator(PlumageRender::Setter::filePath.deviceSpecFilePath)) + for (const auto& entry : std::filesystem::directory_iterator(setter.filePath.deviceSpecFilePath)) { if (std::filesystem::is_directory(entry.path())) { @@ -405,7 +405,7 @@ void PlumageRender::RenderOutput::removeImageSequence() std::filesystem::remove(entry.path()); } } - std::filesystem::remove(PlumageRender::Setter::filePath.deviceSpecFilePath); + std::filesystem::remove(setter.filePath.deviceSpecFilePath); std::cout << "clean up complete" << std::endl; } return; diff --git a/src/render/renderIO.h b/src/render/renderIO.h index 17d6e1f..cce2dbd 100644 --- a/src/render/renderIO.h +++ b/src/render/renderIO.h @@ -3,15 +3,22 @@ #include #include +#ifndef _RENDER_H +#include "render.h" +#define _RENDER_H +#endif // !RENDER_H + #ifndef _PBR_H #include "PBR.h" #define _PBR_H #endif // !PBR_H -#ifndef _RENDER_H -#include "render.h" -#define _RENDER_H -#endif // !RENDER_H +#ifndef _VULKANFOUNDATION_H +#include "vulkanFoundation.h" +#define _VULKANFOUNDATION_H +#endif // !VULKANFOUNDATION_H + + @@ -34,7 +41,7 @@ namespace PlumageRender void loadEnvironment(std::string fileName, PBR::Material pbrMaterial, Setter setter, VulkanBackend::VulkanFoundation vkFoundation, renderMain& mainRender); - void loadAssets(); + void loadAssets(Setter setter, renderMain mainRender, VulkanBackend::VulkanFoundation vkFoundation, PBR::Material pbrMaterial); private: @@ -70,13 +77,13 @@ namespace PlumageRender static uint64_t savedFrameCounter; - static void writeImageToFile(std::string filePath); + static void writeImageToFile(std::string filePath, VulkanBackend::VulkanFoundation vkFoundation, Setter setter); - static void outputImageSequence(); + static void outputImageSequence(Setter setter, RenderOutput renderOutput, VulkanBackend::VulkanFoundation vkFoundation); - static void imageSequenceToVideo(); + static void imageSequenceToVideo(RenderOutput renderOutput, Setter setter); - static void removeImageSequence(); + static void removeImageSequence(Setter setter, RenderOutput renderOutput); private: diff --git a/src/render/renderSetter.cpp b/src/render/renderSetter.cpp index a291ee1..690d422 100644 --- a/src/render/renderSetter.cpp +++ b/src/render/renderSetter.cpp @@ -54,12 +54,7 @@ void PlumageRender::Setter::getSettingFromCommandLine() } -PlumageRender::Setter::Settings PlumageRender::Setter::getSettings() - { - return settings ; - } - -PlumageRender::Setter::FilePath PlumageRender::Setter::getFilePath() +inline uint32_t PlumageRender::Setter::getFrameRange() { - return filePath; + return settings.endFrameIndex - settings.startFrameCount; } \ No newline at end of file diff --git a/src/render/renderSetter.h b/src/render/renderSetter.h index 67a9f83..b00cc81 100644 --- a/src/render/renderSetter.h +++ b/src/render/renderSetter.h @@ -44,6 +44,7 @@ namespace PlumageRender VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; // 多重采样倍率 }settings; + uint32_t getFrameRange(); struct FilePath { diff --git a/src/render/vulkanFoundation.cpp b/src/render/vulkanFoundation.cpp index 3e97bab..14e7de2 100644 --- a/src/render/vulkanFoundation.cpp +++ b/src/render/vulkanFoundation.cpp @@ -1,31 +1,35 @@ #include "vulkanFoundation.h" -void VulkanBackend::VulkanFoundation::initVulkan(PlumageRender::Setter setter) +void VulkanBackend::VulkanFoundation::initVulkan(PlumageRender::Setter setter,Camera camera,PlumageRender::renderMain mainRender,UI* plumageGUI) { // 创建instance createInstance(setter); // 设置校验层消息回调 - setupDebugMessager(); + setupDebugMessager(setter); // 选择主机显卡 - pickPhysicalDevice(); + pickPhysicalDevice(setter); - // 实时显示结果的glfw surface - createSurface(); + if (!setter.settings.headless) + { + // 实时显示结果的glfw surface + createSurface(setter); + } + // 完成逻辑设备创建 - createLogicalDevice(); + createLogicalDevice(setter); // 创建交换链 - createSwapChain(); + createSwapChain(setter); // 创建交换链中的imageView - createImageView(); + createImageView(setter); // 创建renderpass - createRenderPass(); + createRenderPass(setter); // 创建资源描述符层级 createDescriptorSetLayout(); @@ -34,29 +38,29 @@ void VulkanBackend::VulkanFoundation::initVulkan(PlumageRender::Setter setter) createPipelineCache(); // 创建图形管线 - createGraphicPipeline(); + createGraphicPipeline(setter); // 创建主要帧缓冲区 - createFramebuffer(); + createFramebuffer(setter); // 创建命令缓冲池 - createCommandPool(); + createCommandPool(setter); // 创建统一缓存区 - createUniformBuffer(); + createUniformBuffer(setter,camera,mainRender); // 创建资源描述存储池 - createDescriptorPool(); + createDescriptorPool(mainRender); // 创建资源描述符集 - createDescriptorSets(); + createDescriptorSets(setter); // 分配命令缓存区 - allocateCommandBuffers(); + allocateCommandBuffers(setter); // 创建命令缓存区 - createCommandBuffer(); + createCommandBuffer(setter,mainRender,plumageGUI); } @@ -85,7 +89,7 @@ void VulkanBackend::VulkanFoundation::createInstance(PlumageRender::Setter sette createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; - auto requiredExtensions = getRequiredExtensions(); + auto requiredExtensions = getRequiredExtensions(setter); createInfo.enabledExtensionCount = static_cast(requiredExtensions.size()); createInfo.ppEnabledExtensionNames = requiredExtensions.data(); @@ -163,9 +167,9 @@ std::vector VulkanBackend::VulkanFoundation::getRequiredExtensions( -void VulkanBackend::VulkanFoundation::setupDebugMessager() +void VulkanBackend::VulkanFoundation::setupDebugMessager(PlumageRender::Setter setter) { - if (!PlumageRender::Setter::settings.validation) + if (!setter.settings.validation) { return; } @@ -219,10 +223,10 @@ VkResult VulkanBackend::VulkanFoundation::CreateDebugUtilsMessengerEXT(VkInstanc -void VulkanBackend::VulkanFoundation::createSurface() +void VulkanBackend::VulkanFoundation::createSurface(PlumageRender::Setter setter) { - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { return; } @@ -235,7 +239,7 @@ void VulkanBackend::VulkanFoundation::createSurface() -void VulkanBackend::VulkanFoundation::pickPhysicalDevice() +void VulkanBackend::VulkanFoundation::pickPhysicalDevice(PlumageRender::Setter setter) { uint32_t deviceCount = 0; @@ -247,14 +251,14 @@ void VulkanBackend::VulkanFoundation::pickPhysicalDevice() } std::vector devices(deviceCount); vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); - if (PlumageRender::Setter::settings.selectedPhysicalDeviceIndex != NULL) + if (setter.settings.selectedPhysicalDeviceIndex != NULL) { - physicalDevice = devices[PlumageRender::Setter::settings.selectedPhysicalDeviceIndex]; + physicalDevice = devices[setter.settings.selectedPhysicalDeviceIndex]; } for (const auto& device : devices) { - if (isDeviceSuitable(device)) + if (isDeviceSuitable(device,setter)) { physicalDevice = device; break; @@ -267,9 +271,9 @@ void VulkanBackend::VulkanFoundation::pickPhysicalDevice() } } -bool VulkanBackend::VulkanFoundation::isDeviceSuitable(VkPhysicalDevice device) +bool VulkanBackend::VulkanFoundation::isDeviceSuitable(VkPhysicalDevice device,PlumageRender::Setter setter) { - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { bool extensionsSupported = checkDeviceExtensionSupport(device); return extensionsSupported; @@ -278,7 +282,7 @@ bool VulkanBackend::VulkanFoundation::isDeviceSuitable(VkPhysicalDevice device) { // 非无头下在检查扩展支持的同时要检查swapchain bool extensionsSupported = checkDeviceExtensionSupport(device); bool swapChainAdequate = false; - QueueFamilyIndices indices = findQueueFamilies(device); + QueueFamilyIndices indices = findQueueFamilies(device,setter); if (extensionsSupported) { SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device); @@ -306,7 +310,7 @@ bool VulkanBackend::VulkanFoundation::checkDeviceExtensionSupport(VkPhysicalDevi } -VulkanBackend::VulkanFoundation::QueueFamilyIndices VulkanBackend::VulkanFoundation::findQueueFamilies(VkPhysicalDevice device) +VulkanBackend::VulkanFoundation::QueueFamilyIndices VulkanBackend::VulkanFoundation::findQueueFamilies(VkPhysicalDevice device,PlumageRender::Setter setter) { QueueFamilyIndices indices; @@ -320,7 +324,7 @@ VulkanBackend::VulkanFoundation::QueueFamilyIndices VulkanBackend::VulkanFoundat // 检查显示队列支持 int i = 0; - if (!PlumageRender::Setter::settings.headless) + if (!setter.settings.headless) { vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); } @@ -331,7 +335,7 @@ VulkanBackend::VulkanFoundation::QueueFamilyIndices VulkanBackend::VulkanFoundat indices.graphicsFamily = i; } // 无头下不需要检查present queue - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { if (indices.isGraphicsFamilyComplete()) { @@ -385,12 +389,12 @@ VulkanBackend::VulkanFoundation::SwapChainSupportDetails VulkanBackend::VulkanFo -void VulkanBackend::VulkanFoundation::createLogicalDevice() +void VulkanBackend::VulkanFoundation::createLogicalDevice(PlumageRender::Setter setter) { - QueueFamilyIndices indices = findQueueFamilies(physicalDevice); + QueueFamilyIndices indices = findQueueFamilies(physicalDevice,setter); std::vector queueCreateInfos; - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { VkDeviceQueueCreateInfo queueCreateInfo{}; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; @@ -423,7 +427,7 @@ void VulkanBackend::VulkanFoundation::createLogicalDevice() } std::vector enabledExtensions{}; - if (!PlumageRender::Setter::settings.headless) + if (!setter.settings.headless) { for (auto swapchainExtension: swapchainExtensions) { @@ -440,7 +444,7 @@ void VulkanBackend::VulkanFoundation::createLogicalDevice() deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data(); //新版本vulkan已不对实例和设备特定验证层做区分,此处保证兼容性 - if (PlumageRender::Setter::settings.validation) + if (setter.settings.validation) { deviceCreateInfo.enabledLayerCount = static_cast(validationLayers.size()); deviceCreateInfo.ppEnabledLayerNames = validationLayers.data(); @@ -456,7 +460,7 @@ void VulkanBackend::VulkanFoundation::createLogicalDevice() } vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicQueue); - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue); } @@ -465,10 +469,10 @@ void VulkanBackend::VulkanFoundation::createLogicalDevice() -void VulkanBackend::VulkanFoundation::createSwapChain() +void VulkanBackend::VulkanFoundation::createSwapChain(PlumageRender::Setter setter) { - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { return; } @@ -476,7 +480,7 @@ void VulkanBackend::VulkanFoundation::createSwapChain() SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); - VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); + VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes,setter); VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities); uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; @@ -497,7 +501,7 @@ void VulkanBackend::VulkanFoundation::createSwapChain() createInfo.imageArrayLayers = 1; createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - QueueFamilyIndices indices = findQueueFamilies(physicalDevice); + QueueFamilyIndices indices = findQueueFamilies(physicalDevice,setter); uint32_t queueFamilyIndices[] = { indices.graphicsFamily.value(),indices.presentFamily.value() }; if (indices.graphicsFamily != indices.presentFamily) { @@ -545,7 +549,7 @@ VkSurfaceFormatKHR VulkanBackend::VulkanFoundation::chooseSwapSurfaceFormat(cons return availableFormats[0]; } -VkPresentModeKHR VulkanBackend::VulkanFoundation::chooseSwapPresentMode(const std::vector& availablePresentModes) +VkPresentModeKHR VulkanBackend::VulkanFoundation::chooseSwapPresentMode(const std::vector& availablePresentModes, PlumageRender::Setter setter) { // Get available present modes uint32_t presentModeCount; @@ -561,7 +565,7 @@ VkPresentModeKHR VulkanBackend::VulkanFoundation::chooseSwapPresentMode(const st // If v-sync is not requested, try to find a mailbox mode // It's the lowest latency non-tearing present mode available - if (!PlumageRender::Setter::settings.vsync) + if (!setter.settings.vsync) { for (size_t i = 0; i < presentModeCount; i++) { @@ -603,27 +607,27 @@ VkExtent2D VulkanBackend::VulkanFoundation::chooseSwapExtent(const VkSurfaceCapa -void VulkanBackend::VulkanFoundation::createImageView() +void VulkanBackend::VulkanFoundation::createImageView(PlumageRender::Setter setter) { VkFormat colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM; VkFormat depthFormat = findDepthFormat(); - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { - if (PlumageRender::Setter::settings.multiSampling) + if (setter.settings.multiSampling) { VkImageCreateInfo imageCI{}; imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCI.imageType = VK_IMAGE_TYPE_2D; imageCI.format = colorAttachmentFormat; - imageCI.extent.width = PlumageRender::Setter::settings.width; - imageCI.extent.height =PlumageRender::Setter::settings.height; + imageCI.extent.width = setter.settings.width; + imageCI.extent.height = setter.settings.height; imageCI.extent.depth = 1; imageCI.mipLevels = 1; imageCI.arrayLayers = 1; imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCI.samples =PlumageRender::Setter::settings.sampleCount; + imageCI.samples = setter.settings.sampleCount; imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; @@ -660,14 +664,14 @@ void VulkanBackend::VulkanFoundation::createImageView() // Depth target imageCI.imageType = VK_IMAGE_TYPE_2D; imageCI.format = depthFormat; - imageCI.extent.width =PlumageRender::Setter::settings.width; - imageCI.extent.height =PlumageRender::Setter::settings.height; + imageCI.extent.width =setter.settings.width; + imageCI.extent.height =setter.settings.height; imageCI.extent.depth = 1; imageCI.mipLevels = 1; imageCI.arrayLayers = 1; imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCI.samples =PlumageRender::Setter::settings.sampleCount; + imageCI.samples =setter.settings.sampleCount; imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.depthAttachment.image)); @@ -700,8 +704,8 @@ void VulkanBackend::VulkanFoundation::createImageView() imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCI.imageType = VK_IMAGE_TYPE_2D; imageCI.format = colorAttachmentFormat; - imageCI.extent.width =PlumageRender::Setter::settings.width; - imageCI.extent.height =PlumageRender::Setter::settings.height; + imageCI.extent.width =setter.settings.width; + imageCI.extent.height =setter.settings.height; imageCI.extent.depth = 1; imageCI.mipLevels = 1; imageCI.arrayLayers = 1; @@ -749,8 +753,8 @@ void VulkanBackend::VulkanFoundation::createImageView() image.pNext = NULL; image.imageType = VK_IMAGE_TYPE_2D; image.format = depthFormat; - image.extent.width =PlumageRender::Setter::settings.width; - image.extent.height =PlumageRender::Setter::settings.height; + image.extent.width =setter.settings.width; + image.extent.height =setter.settings.height; image.extent.depth = 1; image.mipLevels = 1; image.arrayLayers = 1; @@ -831,12 +835,12 @@ void VulkanBackend::VulkanFoundation::createImageView() -void VulkanBackend::VulkanFoundation::createRenderPass() +void VulkanBackend::VulkanFoundation::createRenderPass(PlumageRender::Setter setter) { VkFormat colorAttachmentFormat; VkFormat depthAttachmentFormat = findDepthFormat(); VkImageLayout colorAttachmentFinallayout; - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM; colorAttachmentFinallayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; @@ -847,12 +851,12 @@ void VulkanBackend::VulkanFoundation::createRenderPass() colorAttachmentFinallayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; } - if (PlumageRender::Setter::settings.multiSampling) { + if (setter.settings.multiSampling) { std::array attachments = {}; // Multisampled attachment that we render to attachments[0].format = colorAttachmentFormat; - attachments[0].samples =PlumageRender::Setter::settings.sampleCount; + attachments[0].samples =setter.settings.sampleCount; attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -873,7 +877,7 @@ void VulkanBackend::VulkanFoundation::createRenderPass() // Multisampled depth attachment we render to attachments[2].format = depthAttachmentFormat; - attachments[2].samples =PlumageRender::Setter::settings.sampleCount; + attachments[2].samples =setter.settings.sampleCount; attachments[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachments[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -1111,7 +1115,7 @@ void VulkanBackend::VulkanFoundation::createPipelineCache() -void VulkanBackend::VulkanFoundation::createGraphicPipeline() +void VulkanBackend::VulkanFoundation::createGraphicPipeline(PlumageRender::Setter setter) { VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI{}; inputAssemblyStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; @@ -1149,8 +1153,8 @@ void VulkanBackend::VulkanFoundation::createGraphicPipeline() VkPipelineMultisampleStateCreateInfo multisampleStateCI{}; multisampleStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - if (PlumageRender::Setter::settings.multiSampling) { - multisampleStateCI.rasterizationSamples =PlumageRender::Setter::settings.sampleCount; + if (setter.settings.multiSampling) { + multisampleStateCI.rasterizationSamples =setter.settings.sampleCount; } std::vector dynamicStateEnables = { @@ -1213,14 +1217,14 @@ void VulkanBackend::VulkanFoundation::createGraphicPipeline() pipelineCI.stageCount = static_cast(shaderStages.size()); pipelineCI.pStages = shaderStages.data(); - if (PlumageRender::Setter::settings.multiSampling) { - multisampleStateCI.rasterizationSamples =PlumageRender::Setter::settings.sampleCount; + if (setter.settings.multiSampling) { + multisampleStateCI.rasterizationSamples =setter.settings.sampleCount; } // Skybox pipeline (background cube) shaderStages = { - loadShader(device,PlumageRender::Setter::filePath.skyboxVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), - loadShader(device,PlumageRender::Setter::filePath.skyboxFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) + loadShader(device,setter.filePath.skyboxVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), + loadShader(device,setter.filePath.skyboxFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) }; VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.skybox)); for (auto shaderStage : shaderStages) { @@ -1229,8 +1233,8 @@ void VulkanBackend::VulkanFoundation::createGraphicPipeline() // PBR pipeline shaderStages = { - loadShader(device,PlumageRender::Setter::filePath.pbrVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), - loadShader(device,PlumageRender::Setter::filePath.pbrFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) + loadShader(device,setter.filePath.pbrVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), + loadShader(device,setter.filePath.pbrFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) }; depthStencilStateCI.depthWriteEnable = VK_TRUE; depthStencilStateCI.depthTestEnable = VK_TRUE; @@ -1259,12 +1263,15 @@ void VulkanBackend::VulkanFoundation::createGraphicPipeline() -void VulkanBackend::VulkanFoundation::createFramebuffer() +void VulkanBackend::VulkanFoundation::createFramebuffer(PlumageRender::Setter setter) { - if (PlumageRender::Setter::settings.headless) + + if (setter.settings.headless) { - if (PlumageRender::Setter::settings.multiSampling) + auto frameRange = setter.settings.endFrameIndex - setter.settings.startFrameCount; + if (setter.settings.multiSampling) { + for (int i = 0; i < frameRange; i++) { VkImageView attachments[4]; @@ -1277,8 +1284,8 @@ void VulkanBackend::VulkanFoundation::createFramebuffer() framebufferCreateInfo.renderPass = renderPass; framebufferCreateInfo.attachmentCount = 4; framebufferCreateInfo.pAttachments = attachments; - framebufferCreateInfo.width =PlumageRender::Setter::settings.width; - framebufferCreateInfo.height =PlumageRender::Setter::settings.height; + framebufferCreateInfo.width =setter.settings.width; + framebufferCreateInfo.height =setter.settings.height; framebufferCreateInfo.layers = 1; VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffers[i])); @@ -1297,8 +1304,8 @@ void VulkanBackend::VulkanFoundation::createFramebuffer() framebufferCreateInfo.renderPass = renderPass; framebufferCreateInfo.attachmentCount = 2; framebufferCreateInfo.pAttachments = attachments; - framebufferCreateInfo.width =PlumageRender::Setter::settings.width; - framebufferCreateInfo.height =PlumageRender::Setter::settings.height; + framebufferCreateInfo.width =setter.settings.width; + framebufferCreateInfo.height =setter.settings.height; framebufferCreateInfo.layers = 1; VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffers[i])); @@ -1309,16 +1316,16 @@ void VulkanBackend::VulkanFoundation::createFramebuffer() } else { - createSwapChainFramebuffer(); + createSwapChainFramebuffer(setter); } } -void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer() +void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer(PlumageRender::Setter setter) { uint32_t attachmentCount; VkImageView attachments[attachmentCount]; - if (PlumageRender::Setter::settings.multiSampling) { + if (setter.settings.multiSampling) { attachmentCount = 4; attachments[0] = multisampleTarget.colorAttachment.view; attachments[1] = multisampleTarget.depthAttachment.view; @@ -1336,8 +1343,8 @@ void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer() frameBufferCI.renderPass = renderPass; frameBufferCI.attachmentCount = attachmentCount; frameBufferCI.pAttachments = attachments; - frameBufferCI.width =PlumageRender::Setter::settings.width; - frameBufferCI.height =PlumageRender::Setter::settings.height; + frameBufferCI.width =setter.settings.width; + frameBufferCI.height =setter.settings.height; frameBufferCI.layers = 1; @@ -1345,7 +1352,7 @@ void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer() // Create frame buffers for every swap chain image framebuffers.resize(swapChainImageViews.size()); for (uint32_t i = 0; i < swapChainImageViews.size(); i++) { - if (PlumageRender::Setter::settings.multiSampling) { + if (setter.settings.multiSampling) { attachments[3] = swapChainImageViews[i]; } else { @@ -1357,9 +1364,9 @@ void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer() -void VulkanBackend::VulkanFoundation::createCommandPool() +void VulkanBackend::VulkanFoundation::createCommandPool(PlumageRender::Setter setter) { - QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice); + QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice,setter); VkCommandPoolCreateInfo poolInfo{}; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; @@ -1376,10 +1383,11 @@ void VulkanBackend::VulkanFoundation::createCommandPool() -void VulkanBackend::VulkanFoundation::createUniformBuffer() +void VulkanBackend::VulkanFoundation::createUniformBuffer(PlumageRender::Setter setter,Camera camera,PlumageRender::renderMain mainRender) { - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { + auto frameRange = setter.settings.endFrameIndex - setter.settings.startFrameCount; uniformBuffers.resize(frameRange); } else @@ -1392,19 +1400,19 @@ void VulkanBackend::VulkanFoundation::createUniformBuffer() uniformBuffer.skybox.create(vulkanDevice, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(shaderDataSkybox)); uniformBuffer.params.create(vulkanDevice, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(PBR::Material::shaderData)); } - updateUniformBuffers(); + updateUniformBuffers(camera,mainRender); } -void VulkanBackend::VulkanFoundation::updateUniformBuffers() +void VulkanBackend::VulkanFoundation::updateUniformBuffers(Camera camera, PlumageRender::renderMain mainRender) { // Scene shaderDataScene.projection = camera.matrices.perspective; shaderDataScene.view = camera.matrices.view; // Center and scale model - float scale = (1.0f / std::max(PlumageRender::renderMain::models.scene.aabb[0][0], std::max(PlumageRender::renderMain::models.scene.aabb[1][1], PlumageRender::renderMain::models.scene.aabb[2][2]))) * 0.5f; - glm::vec3 translate = -glm::vec3(PlumageRender::renderMain::models.scene.aabb[3][0], PlumageRender::renderMain::models.scene.aabb[3][1], PlumageRender::renderMain::models.scene.aabb[3][2]); - translate += -0.5f * glm::vec3(PlumageRender::renderMain::models.scene.aabb[0][0], PlumageRender::renderMain::models.scene.aabb[1][1], PlumageRender::renderMain::models.scene.aabb[2][2]); + float scale = (1.0f / std::max(mainRender.models.scene.aabb[0][0], std::max(mainRender.models.scene.aabb[1][1], mainRender.models.scene.aabb[2][2]))) * 0.5f; + glm::vec3 translate = -glm::vec3(mainRender.models.scene.aabb[3][0], mainRender.models.scene.aabb[3][1], mainRender.models.scene.aabb[3][2]); + translate += -0.5f * glm::vec3(mainRender.models.scene.aabb[0][0], mainRender.models.scene.aabb[1][1], mainRender.models.scene.aabb[2][2]); shaderDataScene.model = glm::mat4(1.0f); shaderDataScene.model[0][0] = scale; @@ -1424,7 +1432,7 @@ void VulkanBackend::VulkanFoundation::updateUniformBuffers() shaderDataSkybox.model = glm::mat4(glm::mat3(camera.matrices.view)); } -void VulkanBackend::VulkanFoundation::createDescriptorPool() +void VulkanBackend::VulkanFoundation::createDescriptorPool(PlumageRender::renderMain mainRender) { /* Descriptor Pool @@ -1436,7 +1444,7 @@ void VulkanBackend::VulkanFoundation::createDescriptorPool() // Environment samplers (radiance, irradiance, brdflut) imageSamplerCount += 3; - std::vector modellist = { &PlumageRender::renderMain::models.skybox, &PlumageRender::renderMain::models.scene }; + std::vector modellist = { &mainRender.models.skybox, &mainRender.models.scene }; for (auto& model : modellist) { for (auto& material : model->materials) { imageSamplerCount += 5; @@ -1461,10 +1469,11 @@ void VulkanBackend::VulkanFoundation::createDescriptorPool() VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool)); } -void VulkanBackend::VulkanFoundation::createDescriptorSets() +void VulkanBackend::VulkanFoundation::createDescriptorSets(PlumageRender::Setter setter) { - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { + auto frameRange = setter.settings.endFrameIndex - setter.settings.startFrameCount; descriptorSets.resize(frameRange); } else @@ -1672,11 +1681,12 @@ void VulkanBackend::VulkanFoundation::createSkyboxDescriptorSets() -void VulkanBackend::VulkanFoundation::allocateCommandBuffers() +void VulkanBackend::VulkanFoundation::allocateCommandBuffers(PlumageRender::Setter setter) { // resize - if (PlumageRender::Setter::settings.headless) + if (setter.settings.headless) { + auto frameRange = setter.getFrameRange(); commandbuffers.resize(frameRange); } else @@ -1707,14 +1717,14 @@ void VulkanBackend::VulkanFoundation::cleanupSwapChain() vkDestroySwapchainKHR(device, swapChain, nullptr); } -void VulkanBackend::VulkanFoundation::createCommandBuffer() +void VulkanBackend::VulkanFoundation::createCommandBuffer(PlumageRender::Setter setter,PlumageRender::renderMain mainRender,UI* plumageGUI) { VkCommandBufferBeginInfo cmdBufferBeginInfo{}; cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; VkClearValue clearValues[3]; - if (PlumageRender::Setter::settings.multiSampling) { + if (setter.settings.multiSampling) { clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } }; clearValues[1].color = { { 0.0f, 0.0f, 0.0f, 1.0f } }; clearValues[2].depthStencil = { 1.0f, 0 }; @@ -1729,9 +1739,9 @@ void VulkanBackend::VulkanFoundation::createCommandBuffer() renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; - renderPassBeginInfo.renderArea.extent.width =PlumageRender::Setter::settings.width; - renderPassBeginInfo.renderArea.extent.height =PlumageRender::Setter::settings.height; - renderPassBeginInfo.clearValueCount =PlumageRender::Setter::settings.multiSampling ? 3 : 2; + renderPassBeginInfo.renderArea.extent.width =setter.settings.width; + renderPassBeginInfo.renderArea.extent.height =setter.settings.height; + renderPassBeginInfo.clearValueCount =setter.settings.multiSampling ? 3 : 2; renderPassBeginInfo.pClearValues = clearValues; for (uint32_t i = 0; i < commandbuffers.size(); ++i) @@ -1744,25 +1754,25 @@ void VulkanBackend::VulkanFoundation::createCommandBuffer() vkCmdBeginRenderPass(currentCB, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); VkViewport viewport{}; - viewport.width = (float)PlumageRender::Setter::settings.width; - viewport.height = (float)PlumageRender::Setter::settings.height; + viewport.width = (float)setter.settings.width; + viewport.height = (float)setter.settings.height; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; vkCmdSetViewport(currentCB, 0, 1, &viewport); VkRect2D scissor{}; - scissor.extent = {PlumageRender::Setter::settings.width,PlumageRender::Setter::settings.height }; + scissor.extent = {setter.settings.width,setter.settings.height }; vkCmdSetScissor(currentCB, 0, 1, &scissor); VkDeviceSize offsets[1] = { 0 }; - if (PlumageRender::Setter::settings.displayBackground) { + if (setter.settings.displayBackground) { vkCmdBindDescriptorSets(currentCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[i].skybox, 0, nullptr); vkCmdBindPipeline(currentCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.skybox); - PlumageRender::renderMain::models.skybox.draw(currentCB); + mainRender.models.skybox.draw(currentCB); } - glTFModel::Model& model = PlumageRender::renderMain::models.scene; + glTFModel::Model& model = mainRender.models.scene; vkCmdBindVertexBuffers(currentCB, 0, 1, &model.vertices.buffer, offsets); if (model.indices.buffer != VK_NULL_HANDLE) { @@ -1786,9 +1796,9 @@ void VulkanBackend::VulkanFoundation::createCommandBuffer() } // User interface - if (!PlumageRender::Setter::settings.headless) + if (!setter.settings.headless) { - plumageGui.gui->draw(currentCB); + plumageGUI->draw(currentCB); } vkCmdEndRenderPass(currentCB); @@ -1876,18 +1886,18 @@ void VulkanBackend::VulkanFoundation::createglTFNodeCommandBuffer(glTFModel::Nod } } -void VulkanBackend::VulkanFoundation::createFenceAndSemaphore() +void VulkanBackend::VulkanFoundation::createFenceAndSemaphore(PlumageRender::Setter setter) { - waitFences.resize(PlumageRender::Setter::settings.MaxFrameInFlight); - presentCompleteSemaphores.resize(PlumageRender::Setter::settings.MaxFrameInFlight); - renderCompleteSemaphores.resize(PlumageRender::Setter::settings.MaxFrameInFlight); + waitFences.resize(setter.settings.MaxFrameInFlight); + presentCompleteSemaphores.resize(setter.settings.MaxFrameInFlight); + renderCompleteSemaphores.resize(setter.settings.MaxFrameInFlight); // Command buffer execution fences for (auto& waitFence : waitFences) { VkFenceCreateInfo fenceCI{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT }; VK_CHECK_RESULT(vkCreateFence(device, &fenceCI, nullptr, &waitFence)); } - if (!PlumageRender::Setter::settings.headless) + if (!setter.settings.headless) { for (auto& semaphore : presentCompleteSemaphores) { VkSemaphoreCreateInfo semaphoreCI{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 }; @@ -1914,14 +1924,14 @@ void VulkanBackend::VulkanFoundation::DestroyDebugUtilsMessengerEXT(VkInstance i -bool VulkanBackend::VulkanFoundation::acqureNextSwapchainImage(bool framebuffeerResized,uint32_t imageIndex,uint32_t frameIndex) +bool VulkanBackend::VulkanFoundation::acqureNextSwapchainImage(bool framebuffeerResized,uint32_t imageIndex,uint32_t frameIndex,PlumageRender::Setter setter) { VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, renderCompleteSemaphores[frameIndex], VK_NULL_HANDLE, &imageIndex); if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebuffeerResized) { framebuffeerResized = false; - recreateSwapChain(); + recreateSwapChain(setter); return framebuffeerResized; } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) @@ -1945,7 +1955,7 @@ void VulkanBackend::VulkanFoundation::submitToGraphicQueue(uint32_t frameIndex, VK_CHECK_RESULT(vkQueueSubmit(graphicQueue, 1, &submitInfo, waitFences[frameIndex])); } -void VulkanBackend::VulkanFoundation::imageToQueuePresent(uint32_t frameIndex,uint32_t imageIndex,bool framebufferResized) +void VulkanBackend::VulkanFoundation::imageToQueuePresent(uint32_t frameIndex,uint32_t imageIndex,bool framebufferResized,PlumageRender::Setter setter) { //显示队列 VkSemaphore signalSemaphores[] = { renderCompleteSemaphores[frameIndex] }; @@ -1966,7 +1976,7 @@ void VulkanBackend::VulkanFoundation::imageToQueuePresent(uint32_t frameIndex,ui if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { framebufferResized = false; - recreateSwapChain(); + recreateSwapChain(setter); } else if (result != VK_SUCCESS) { @@ -1974,6 +1984,67 @@ void VulkanBackend::VulkanFoundation::imageToQueuePresent(uint32_t frameIndex,ui } } +void VulkanBackend::VulkanFoundation::destroyVulkanBackend(PlumageRender::Setter setter) +{ + // Clean up Vulkan resources + cleanupSwapChain(); + vkDestroyDescriptorPool(device, descriptorPool, nullptr); + vkDestroyRenderPass(device, renderPass, nullptr); + for (uint32_t i = 0; i < framebuffers.size(); i++) { + vkDestroyFramebuffer(device, framebuffers[i], nullptr); + } + vkDestroyImageView(device, colorAttachment.view, nullptr); + vkDestroyImage(device, colorAttachment.image, nullptr); + vkFreeMemory(device, colorAttachment.memory, nullptr); + vkDestroyImageView(device, depthAttachment.view, nullptr); + vkDestroyImage(device, depthAttachment.image, nullptr); + vkFreeMemory(device, depthAttachment.memory, nullptr); + + if (setter.settings.multiSampling) { + vkDestroyImage(device, multisampleTarget.colorAttachment.image, nullptr); + vkDestroyImageView(device, multisampleTarget.colorAttachment.view, nullptr); + vkFreeMemory(device, multisampleTarget.colorAttachment.memory, nullptr); + vkDestroyImage(device, multisampleTarget.depthAttachment.image, nullptr); + vkDestroyImageView(device, multisampleTarget.depthAttachment.view, nullptr); + vkFreeMemory(device, multisampleTarget.depthAttachment.memory, nullptr); + } + + + // Clean up used Vulkan resources + // Note : Inherited destructor cleans up resources stored in base class + vkDestroyPipeline(device, pipelines.skybox, nullptr); + vkDestroyPipeline(device, pipelines.pbr, nullptr); + vkDestroyPipeline(device, pipelines.pbrAlphaBlend, nullptr); + vkDestroyPipelineCache(device, pipelineCache, nullptr); + vkDestroyCommandPool(device, commandPool, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.scene, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.material, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.node, nullptr); + + + + for (auto buffer : uniformBuffers) { + buffer.params.destroy(); + buffer.scene.destroy(); + buffer.skybox.destroy(); + } + for (auto fence : waitFences) { + vkDestroyFence(device, fence, nullptr); + } + for (auto semaphore : renderCompleteSemaphores) { + vkDestroySemaphore(device, semaphore, nullptr); + } + for (auto semaphore : presentCompleteSemaphores) { + vkDestroySemaphore(device, semaphore, nullptr); + } + delete vulkanDevice; + if (setter.settings.validation) { + DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr); + } + vkDestroyInstance(instance, nullptr); +} + void VulkanBackend::VulkanFoundation::updateShaderData() @@ -1985,7 +2056,7 @@ void VulkanBackend::VulkanFoundation::updateShaderData() 0.0f); } -void VulkanBackend::VulkanFoundation::recreateSwapChain() +void VulkanBackend::VulkanFoundation::recreateSwapChain(PlumageRender::Setter setter) { int width = 0, height = 0; glfwGetFramebufferSize(window, &width, &height); @@ -2003,9 +2074,9 @@ void VulkanBackend::VulkanFoundation::recreateSwapChain() cleanupSwapChain(); - createSwapChain(); - createImageView(); - createFramebuffer(); + createSwapChain(setter); + createImageView(setter); + createFramebuffer(setter); } diff --git a/src/render/vulkanFoundation.h b/src/render/vulkanFoundation.h index bbe5add..3c6f2d0 100644 --- a/src/render/vulkanFoundation.h +++ b/src/render/vulkanFoundation.h @@ -1,12 +1,18 @@ #pragma once -#include "GLFW/glfw3.h" + + #include #include #include #include #include +#ifndef _RENDER_H +#include "render.h" +#define _RENDER_H +#endif // !RENDER_H + #ifndef _GLTFMODEL_H #include "glTFModel.h" #define _GLTFMODEL_H @@ -18,13 +24,33 @@ #endif // !RENDERSETTER_H +#ifndef _GLFW3_H +#include "GLFW/glfw3.h" +#define _GLFW3_H +#endif // !_GLFW3_H + +#ifndef _VULKANUTILS_HPP #include "VulkanUtils.hpp" +#define _VULKANUTILS_HPP +#endif // !_VULKANUTILS_HPP + #include +#ifndef _VULKANDEVICE_HPP #include "VulkanDevice.hpp" +#define _VULKANDEVICE_HPP +#endif // !_VULKANDEVICE_HPP +#ifndef _CAMERA_HPP +#include "camera.hpp" +#define _CAMERA_HPP +#endif // !_CAMERA_HPP +#ifndef _UI_HPP +#include "ui.hpp" +#define _UI_HPP +#endif // !UI_HPP namespace VulkanBackend @@ -33,66 +59,8 @@ namespace VulkanBackend { public: VulkanFoundation(); - ~VulkanFoundation() - { - // Clean up Vulkan resources - cleanupSwapChain(); - vkDestroyDescriptorPool(device, descriptorPool, nullptr); - vkDestroyRenderPass(device, renderPass, nullptr); - for (uint32_t i = 0; i < framebuffers.size(); i++) { - vkDestroyFramebuffer(device, framebuffers[i], nullptr); - } - vkDestroyImageView(device, colorAttachment.view, nullptr); - vkDestroyImage(device, colorAttachment.image, nullptr); - vkFreeMemory(device, colorAttachment.memory, nullptr); - vkDestroyImageView(device, depthAttachment.view, nullptr); - vkDestroyImage(device, depthAttachment.image, nullptr); - vkFreeMemory(device, depthAttachment.memory, nullptr); - - if (PlumageRender::Setter::settings.multiSampling) { - vkDestroyImage(device, multisampleTarget.colorAttachment.image, nullptr); - vkDestroyImageView(device, multisampleTarget.colorAttachment.view, nullptr); - vkFreeMemory(device, multisampleTarget.colorAttachment.memory, nullptr); - vkDestroyImage(device, multisampleTarget.depthAttachment.image, nullptr); - vkDestroyImageView(device, multisampleTarget.depthAttachment.view, nullptr); - vkFreeMemory(device, multisampleTarget.depthAttachment.memory, nullptr); - } - - - // Clean up used Vulkan resources - // Note : Inherited destructor cleans up resources stored in base class - vkDestroyPipeline(device, pipelines.skybox, nullptr); - vkDestroyPipeline(device, pipelines.pbr, nullptr); - vkDestroyPipeline(device, pipelines.pbrAlphaBlend, nullptr); - vkDestroyPipelineCache(device, pipelineCache, nullptr); - vkDestroyCommandPool(device, commandPool, nullptr); - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.scene, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.material, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.node, nullptr); - - - - for (auto buffer : uniformBuffers) { - buffer.params.destroy(); - buffer.scene.destroy(); - buffer.skybox.destroy(); - } - for (auto fence : waitFences) { - vkDestroyFence(device, fence, nullptr); - } - for (auto semaphore : renderCompleteSemaphores) { - vkDestroySemaphore(device, semaphore, nullptr); - } - for (auto semaphore : presentCompleteSemaphores) { - vkDestroySemaphore(device, semaphore, nullptr); - } - delete vulkanDevice; - if (PlumageRender::Setter::settings.validation) { - DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr); - } - vkDestroyInstance(instance, nullptr); - } + ~VulkanFoundation(); + const std::vector validationLayers = { "VK_LAYER_KHRONOS_validation" @@ -154,24 +122,26 @@ namespace VulkanBackend VkQueue presentQueue; - void initVulkan(PlumageRender::Setter setter); + void initVulkan(PlumageRender::Setter setter, Camera camera, PlumageRender::renderMain mainRender, UI* plumageGUI); // 创建描述符集合 - void createDescriptorSets(); + void createDescriptorSets(PlumageRender::Setter setter); + + void createCommandBuffer(PlumageRender::Setter setter, PlumageRender::renderMain mainRender, UI* plumageGUI); - void createCommandBuffer(); - - void updateUniformBuffers(); + void updateUniformBuffers(Camera camera, PlumageRender::renderMain mainRender); void updateShaderData(); - void recreateSwapChain(); + void recreateSwapChain(PlumageRender::Setter setter); - bool acqureNextSwapchainImage(bool framebuffeerResized, uint32_t imageIndex, uint32_t frameIndex); + bool acqureNextSwapchainImage(bool framebuffeerResized, uint32_t imageIndex, uint32_t frameIndex, PlumageRender::Setter setter); void submitToGraphicQueue(uint32_t frameIndex, uint32_t currentBuffer); - void imageToQueuePresent(uint32_t frameIndex, uint32_t imageIndex, bool framebufferResized); + void imageToQueuePresent(uint32_t frameIndex, uint32_t imageIndex, bool framebufferResized, PlumageRender::Setter setter); + + void destroyVulkanBackend(PlumageRender::Setter setter); private: @@ -292,10 +262,10 @@ namespace VulkanBackend std::vector getRequiredExtensions(PlumageRender::Setter setter); // 实时显示结果使用的glfwSurface,受headless配置项控制 - void createSurface(); + void createSurface(PlumageRender::Setter setter); // 设置校验层使用的消息回调 - void setupDebugMessager(); + void setupDebugMessager(PlumageRender::Setter setter); void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo); static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, @@ -306,27 +276,27 @@ namespace VulkanBackend void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator); // 通过检查队列、交换链、扩展支持,选择合适的显卡 - void pickPhysicalDevice(); - bool isDeviceSuitable(VkPhysicalDevice device); + void pickPhysicalDevice(PlumageRender::Setter setter); + bool isDeviceSuitable(VkPhysicalDevice device, PlumageRender::Setter setter); bool checkDeviceExtensionSupport(VkPhysicalDevice device); - VulkanBackend::VulkanFoundation::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device); + VulkanBackend::VulkanFoundation::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, PlumageRender::Setter setter); VulkanBackend::VulkanFoundation::SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device); // 创建程序使用的逻辑设备 - void createLogicalDevice(); + void createLogicalDevice(PlumageRender::Setter setter); // 创建交换链 - void createSwapChain(); + void createSwapChain(PlumageRender::Setter setter); VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats); - VkPresentModeKHR chooseSwapPresentMode(const std::vector& availablePresentModes); + VkPresentModeKHR chooseSwapPresentMode(const std::vector& availablePresentModes, PlumageRender::Setter setter); VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities); void cleanupSwapChain(); // 创建交换链中的imageView,用于访问交换链中图像 - void createImageView(); + void createImageView(PlumageRender::Setter setter); // 创建renderPass - void createRenderPass(); + void createRenderPass(PlumageRender::Setter setter); VkFormat findDepthFormat(); VkFormat findSupportedFormat(const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features); bool hasStencilComponent(VkFormat format); @@ -341,23 +311,23 @@ namespace VulkanBackend void createPipelineCache(); // 创建图形管线 - void createGraphicPipeline(); + void createGraphicPipeline(PlumageRender::Setter setter); // 创建帧缓冲区 - void createFramebuffer(); - void createSwapChainFramebuffer(); + void createFramebuffer(PlumageRender::Setter setter); + void createSwapChainFramebuffer(PlumageRender::Setter setter); // 创建命令缓冲池 - void createCommandPool(); + void createCommandPool(PlumageRender::Setter setter); // 创建统一缓冲区 - void createUniformBuffer(); + void createUniformBuffer(PlumageRender::Setter setter, Camera camera, PlumageRender::renderMain mainRender); // 创建描述符池 - void createDescriptorPool(); + void createDescriptorPool(PlumageRender::renderMain mainRender); @@ -368,12 +338,12 @@ namespace VulkanBackend void createSkyboxDescriptorSets(); // 创建命令缓存区 - void allocateCommandBuffers(); + void allocateCommandBuffers(PlumageRender::Setter setter); void createglTFNodeCommandBuffer(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode); // 创建栅栏和信号量,用于多帧并行的同步 - void createFenceAndSemaphore(); + void createFenceAndSemaphore(PlumageRender::Setter setter); @@ -384,5 +354,9 @@ namespace VulkanBackend { } + VulkanFoundation::~VulkanFoundation() + { + } + } \ No newline at end of file