完成vulkanbackend的对象参数化

ink-soul 2024-04-10 15:32:33 +08:00
parent 743b84a32b
commit d9cd065f35
11 changed files with 445 additions and 320 deletions

View File

@ -16,10 +16,11 @@
#define _VULKANFOUNDATION_H #define _VULKANFOUNDATION_H
#endif // !VULKANFOUNDATION_H #endif // !VULKANFOUNDATION_H
#ifndef _UI_HPP #ifndef _RENDERGUI_H
#include "ui.hpp" #include "renderUI.h"
#define _UI_HPP #define _RENDERGUI_H
#endif // !UI_HPP #endif // !_RENDERGUI_H
#ifndef _PBR_H #ifndef _PBR_H
#include "PBR.h" #include "PBR.h"
@ -36,4 +37,34 @@
#define _RENDERIO_H #define _RENDERIO_H
#endif // !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
``` ```

View File

@ -1,18 +1,31 @@
#pragma once #pragma once
#ifndef _RENDER_H #ifndef _RENDERSETTER_H
#include "render.h" #include "renderSetter.h"
#define _RENDER_H #define _RENDERSETTER_H
#endif // !RENDER_H #endif // !RENDERSETTER_H
#ifndef _VULKANFOUNDATION_H #ifndef _VULKANFOUNDATION_H
#include "vulkanFoundation.h" #include "vulkanFoundation.h"
#define _VULKANFOUNDATION_H #define _VULKANFOUNDATION_H
#endif // !VULKANFOUNDATION_H #endif // !VULKANFOUNDATION_H
#ifndef _RENDER_H
#include "render.h"
#define _RENDER_H
#endif // !RENDER_H
#include "glm/glm.hpp"
#include <VulkanTexture.hpp>
#include <glm/glm.hpp>
#ifndef _VULKANTEXTURE_HPP
#include "VulkanTexture.hpp"
#define _VULKANTEXTURE_HPP
#endif // !_VULKANTEXTURE_HPP

View File

@ -30,18 +30,25 @@
#define TINYGLTF_ANDROID_LOAD_FROM_ASSETS #define TINYGLTF_ANDROID_LOAD_FROM_ASSETS
#endif #endif
#ifndef _TINY_GLTF_H
#include "tiny_gltf.h" #include "tiny_gltf.h"
#define _TINY_GLTF_H
#endif // !_TINY_GLTF_H
#ifndef _VULKANDEVICE_HPP
#include "VulkanDevice.hpp" #include "VulkanDevice.hpp"
#define _VULKANDEVICE_HPP
#endif // !_VULKANDEVICE_HPP
//#include "VulkanUtils.hpp" //#include "VulkanUtils.hpp"
#include "vulkan/vulkan.h" #include <vulkan/vulkan.h>
#ifndef _VULKANFOUNDATION_H #ifndef _VULKANFOUNDATION_H
#include "vulkanFoundation.h" #include "vulkanFoundation.h"
#define _VULKANFOUNDATION_H #define _VULKANFOUNDATION_H
#endif // !VULKANFOUNDATION_H #endif // !VULKANFOUNDATION_H
#define ENABLE_VALIDATION false
#define MAX_NUM_JOINTS 128u #define MAX_NUM_JOINTS 128u
// Contains everything required to render a glTF model in Vulkan // Contains everything required to render a glTF model in Vulkan

View File

@ -36,12 +36,6 @@ void PlumageRender::renderMain::framebufferResizeCallback(GLFWwindow* window, in
} }
// todo重写成glfw的
void PlumageRender::renderMain::windowResized()
{
}
void PlumageRender::renderMain::prepare() void PlumageRender::renderMain::prepare()
{ {
//VulkanExampleBase::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) { if (!prepared) {
return; return;
} }
if (!PlumageRender::Setter::settings.headless) if (!setter.settings.headless)
{ {
renderGUI.updateUIOverlay(); plumageGUI.updateUIOverlay();
} }
uint32_t imageIndex; 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++) for (size_t i = 0; i < frameRange; i++)
{ {
drawFrame(); drawFrame();

View File

@ -18,7 +18,10 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#ifndef _GLFW3_H
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
#define _GLFW3_H
#endif // !_GLFW3_H
#ifndef _GLTFMODEL_H #ifndef _GLTFMODEL_H
@ -36,21 +39,50 @@
#define _VULKANFOUNDATION_H #define _VULKANFOUNDATION_H
#endif // !VULKANFOUNDATION_H #endif // !VULKANFOUNDATION_H
#ifndef _RENDERGUI_H
#include "renderUI.h"
#define _RENDERGUI_H
#endif // !_RENDERGUI_H
#ifndef _UI_HPP #ifndef _UI_HPP
#include "ui.hpp" #include "ui.hpp"
#define _UI_HPP #define _UI_HPP
#endif // !UI_HPP #endif // !UI_HPP
#ifndef _RENDERIO_H
#include "renderIO.h"
#define _RENDERIO_H
#endif // !RENDERIO_H
#ifndef _VULKANDEVICE_HPP
#include "VulkanDevice.hpp" #include "VulkanDevice.hpp"
#define _VULKANDEVICE_HPP
#endif // !_VULKANDEVICE_HPP
#include <camera.hpp> #ifndef _CAMERA_HPP
#include <VulkanTexture.hpp> #include "camera.hpp"
#include <VulkanUtils.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 #define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h" #include "stb_image_write.h"
#define _STB_IMAGE_WRITE_H
#endif // !_STB_IMAGE_WRITE_H
#define ENABLE_VALIDATION false #define ENABLE_VALIDATION false
@ -116,7 +148,7 @@ namespace PlumageRender
void submitToPresentQueue(); void submitToPresentQueue();
virtual void render(); virtual void render();
void renderLoop(GLFWwindow* window); void renderLoop(GLFWwindow* window, Setter setter);
void drawFrame(); void drawFrame();
private: private:

View File

@ -27,7 +27,7 @@ void PlumageRender::RenderInput::loadEnvironment(std::string fileName,PBR::Mater
pbrMaterial.generateCubemap(vkFoundation,setter,mainRender); 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(); const std::string assetpath = getAssetPath();
@ -53,12 +53,12 @@ void PlumageRender::RenderInput::loadAssets(Setter setter,renderMain mainRender,
loadScene(sceneFile.c_str(),mainRender,vkFoundation); loadScene(sceneFile.c_str(),mainRender,vkFoundation);
mainRender.models.skybox.loadFromFile(setter.filePath.skyboxModleFilePath, vkFoundation.vulkanDevice, vkFoundation.graphicQueue); 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 // todo :根据physicalDeviceIndex确定子文件夹路径frameIndex确定fileName
// 移动到fileSystem里 // 移动到fileSystem里
void PlumageRender::RenderOutput::writeImageToFile(std::string filePath) void PlumageRender::RenderOutput::writeImageToFile(std::string filePath, VulkanBackend::VulkanFoundation vkFoundation,Setter setter)
{ {
bool screenshotSaved = false; bool screenshotSaved = false;
@ -68,33 +68,33 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath)
VkFormatProperties formatProps; VkFormatProperties formatProps;
// Check if the device supports blitting from optimal images (the swapchain images are in optimal format) // 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)) { 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; std::cerr << "Device does not support blitting from optimal tiled images, using copy instead of blit!" << std::endl;
supportsBlit = false; supportsBlit = false;
} }
// Check if the device supports blitting to linear images // 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)) { 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; std::cerr << "Device does not support blitting to linear tiled images, using copy instead of blit!" << std::endl;
supportsBlit = false; supportsBlit = false;
} }
// Source for the copy is the last rendered swapchain image // 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 // Create the linear tiled destination image to copy to and to read the memory from
VkImageCreateInfo imageCreateCI(vks::initializers::imageCreateInfo()); VkImageCreateInfo imageCreateCI(vks::initializers::imageCreateInfo());
imageCreateCI.imageType = VK_IMAGE_TYPE_2D; imageCreateCI.imageType = VK_IMAGE_TYPE_2D;
// Note that vkCmdBlitImage (if supported) will also do format conversions if the swapchain color format would differ // Note that vkCmdBlitImage (if supported) will also do format conversions if the swapchain color format would differ
imageCreateCI.format = VK_FORMAT_R8G8B8A8_UNORM; imageCreateCI.format = VK_FORMAT_R8G8B8A8_UNORM;
imageCreateCI.extent.width = PlumageRender::Setter::settings.width; imageCreateCI.extent.width = setter.settings.width;
imageCreateCI.extent.height = PlumageRender::Setter::settings.height; imageCreateCI.extent.height = setter.settings.height;
imageCreateCI.extent.depth = 1; imageCreateCI.extent.depth = 1;
imageCreateCI.arrayLayers = 1; imageCreateCI.arrayLayers = 1;
imageCreateCI.mipLevels = 1; imageCreateCI.mipLevels = 1;
@ -104,20 +104,20 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath)
imageCreateCI.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; imageCreateCI.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
// Create the image // Create the image
VkImage dstImage; 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 // Create memory to back up the image
VkMemoryRequirements memRequirements; VkMemoryRequirements memRequirements;
VkMemoryAllocateInfo memAllocInfo(vks::initializers::memoryAllocateInfo()); VkMemoryAllocateInfo memAllocInfo(vks::initializers::memoryAllocateInfo());
VkDeviceMemory dstImageMemory; VkDeviceMemory dstImageMemory;
vkGetImageMemoryRequirements(VulkanBackend::VulkanFoundation::device, dstImage, &memRequirements); vkGetImageMemoryRequirements(vkFoundation.device, dstImage, &memRequirements);
memAllocInfo.allocationSize = memRequirements.size; memAllocInfo.allocationSize = memRequirements.size;
// Memory must be host visible to copy from // 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); memAllocInfo.memoryTypeIndex = vkFoundation.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(vkAllocateMemory(vkFoundation.device, &memAllocInfo, nullptr, &dstImageMemory));
VK_CHECK_RESULT(vkBindImageMemory(VulkanBackend::VulkanFoundation::device, dstImage, dstImageMemory, 0)); VK_CHECK_RESULT(vkBindImageMemory(vkFoundation.device, dstImage, dstImageMemory, 0));
// Do the actual blit from the swapchain image to our host visible destination image // 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 // Transition destination image to transfer destination layout
vks::tools::insertImageMemoryBarrier( vks::tools::insertImageMemoryBarrier(
@ -131,7 +131,7 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath)
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); 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 // Transition swapchain image from present to transfer source layout
vks::tools::insertImageMemoryBarrier( 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) // Define the region to blit (we will blit the whole swapchain image)
VkOffset3D blitSize; VkOffset3D blitSize;
blitSize.x = PlumageRender::Setter::settings.width; blitSize.x = setter.settings.width;
blitSize.y = PlumageRender::Setter::settings.height; blitSize.y = setter.settings.height;
blitSize.z = 1; blitSize.z = 1;
VkImageBlit imageBlitRegion{}; VkImageBlit imageBlitRegion{};
imageBlitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageBlitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -181,8 +181,8 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath)
imageCopyRegion.srcSubresource.layerCount = 1; imageCopyRegion.srcSubresource.layerCount = 1;
imageCopyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageCopyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageCopyRegion.dstSubresource.layerCount = 1; imageCopyRegion.dstSubresource.layerCount = 1;
imageCopyRegion.extent.width = PlumageRender::Setter::settings.width; imageCopyRegion.extent.width = setter.settings.width;
imageCopyRegion.extent.height = PlumageRender::Setter::settings.height; imageCopyRegion.extent.height = setter.settings.height;
imageCopyRegion.extent.depth = 1; imageCopyRegion.extent.depth = 1;
// Issue the copy command // Issue the copy command
@ -206,7 +206,7 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath)
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); 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 // Transition back the swap chain image after the blit is done
vks::tools::insertImageMemoryBarrier( vks::tools::insertImageMemoryBarrier(
@ -221,16 +221,16 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath)
VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); 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) // Get layout of the image (including row pitch)
VkImageSubresource subResource{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }; VkImageSubresource subResource{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };
VkSubresourceLayout subResourceLayout; 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 // Map image memory so we can start copying from it
const char* data; 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; 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 // 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) if (!supportsBlit)
{ {
std::vector<VkFormat> formatsBGR = { VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SNORM }; std::vector<VkFormat> 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) if (colorSwizzle)
{ {
// 暂时不改此处需要将BGR通道改成RGB格式 // 暂时不改此处需要将BGR通道改成RGB格式
stbi_write_png(filePath.c_str(), PlumageRender::Setter::settings.width, PlumageRender::Setter::settings.height, 4, data, static_cast<int>(subResourceLayout.rowPitch)); stbi_write_png(filePath.c_str(), setter.settings.width, setter.settings.height, 4, data, static_cast<int>(subResourceLayout.rowPitch));
} }
else else
{ {
stbi_write_png(filePath.c_str(), PlumageRender::Setter::settings.width, PlumageRender::Setter::settings.height, 4, data, static_cast<int>(subResourceLayout.rowPitch)); stbi_write_png(filePath.c_str(), setter.settings.width, setter.settings.height, 4, data, static_cast<int>(subResourceLayout.rowPitch));
} }
} }
@ -262,13 +262,13 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath)
std::ofstream file(filePath, std::ios::out | std::ios::binary); std::ofstream file(filePath, std::ios::out | std::ios::binary);
// ppm header // 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 // 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; 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) if (colorSwizzle)
{ {
@ -291,68 +291,68 @@ void PlumageRender::RenderOutput::writeImageToFile(std::string filePath)
std::cout << "Screenshot saved to " << filePath << std::endl; std::cout << "Screenshot saved to " << filePath << std::endl;
// Clean up resources // Clean up resources
vkUnmapMemory(VulkanBackend::VulkanFoundation::device, dstImageMemory); vkUnmapMemory(vkFoundation.device, dstImageMemory);
vkFreeMemory(VulkanBackend::VulkanFoundation::device, dstImageMemory, nullptr); vkFreeMemory(vkFoundation.device, dstImageMemory, nullptr);
vkDestroyImage(VulkanBackend::VulkanFoundation::device, dstImage, nullptr); vkDestroyImage(vkFoundation.device, dstImage, nullptr);
screenshotSaved = true; 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; std::cout << "clean up directory for image sequence generation" << std::endl;
removeImageSequence(); removeImageSequence(setter,renderOutput);
} }
// 根据显卡编号设置输出路径todo提前到配置里 // 根据显卡编号设置输出路径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带来的无效性能开销 // 避免重复改变为true带来的无效性能开销
if (PlumageRender::RenderOutput::signal.imageSequenceOutputComplete) if (renderOutput.signal.imageSequenceOutputComplete)
{ {
return; return;
} }
// 生成结束的信号标志置为true // 生成结束的信号标志置为true
PlumageRender::RenderOutput::signal.imageSequenceOutputComplete = true; renderOutput.signal.imageSequenceOutputComplete = true;
// 构造ffmpeg脚本需要的路径变量(提前到配置) // 构造ffmpeg脚本需要的路径变量(提前到配置)
std::string fileName = "/%dresult.ppm"; std::string fileName = "/%dresult.ppm";
PlumageRender::Setter::filePath.totalImageOutputPath = PlumageRender::Setter::filePath.deviceSpecFilePath + fileName; setter.filePath.totalImageOutputPath = setter.filePath.deviceSpecFilePath + fileName;
return; 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"; 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; //std::cout << outputPath << std::endl;
// 写入文件 // 写入文件
writeImageToFile(PlumageRender::Setter::filePath.totalImageOutputPath.c_str()); writeImageToFile(setter.filePath.totalImageOutputPath.c_str(),vkFoundation,setter);
// 写入一帧后已保存帧数+1 // 写入一帧后已保存帧数+1
savedFrameCounter++; savedFrameCounter++;
} }
void PlumageRender::RenderOutput::imageSequenceToVideo() void PlumageRender::RenderOutput::imageSequenceToVideo(RenderOutput renderOutput,Setter setter)
{ {
// 边界条件,图片序列输出未完成 // 边界条件,图片序列输出未完成
if (!PlumageRender::RenderOutput::signal.imageSequenceOutputComplete) if (!renderOutput.signal.imageSequenceOutputComplete)
{ {
return; return;
} }
// 边界条件,图片序列到视频的输出已完成 // 边界条件,图片序列到视频的输出已完成
if (PlumageRender::RenderOutput::signal.imageSequenceToVideoComplete) if (renderOutput.signal.imageSequenceToVideoComplete)
{ {
return; 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())) if (std::filesystem::exists(deviceFilePath.c_str()))
{ {
@ -361,40 +361,40 @@ void PlumageRender::RenderOutput::imageSequenceToVideo()
// 构造结果视频路径 // 构造结果视频路径
std::string resultVideoPath = deviceFilePath + "/result.mp4"; 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 commandLineCodecAndResultPath = resultVideoPath;
std::string commandLineFrameRate = std::to_string(PlumageRender::Setter::settings.videoFrameRate); std::string commandLineFrameRate = std::to_string(setter.settings.videoFrameRate);
// 根据不同系统使用不同脚本 // 根据不同系统使用不同脚本
#if defined(_WIN32) #if defined(_WIN32)
std::string commandLine = PlumageRender::Setter::filePath.image2videoBatFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath; std::string commandLine = setter.filePath.image2videoBatFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath;
#else #else
std::string commandLine = filePath.image2videoShFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath; std::string commandLine = filePath.image2videoShFilePath + " " + commandLineFrameRate + " " + commandLineImageSequencePath + " " + resultVideoPath;
#endif #endif
std::cout << commandLine << std::endl; std::cout << commandLine << std::endl;
std::system(commandLine.c_str()); std::system(commandLine.c_str());
// 视频输出完成置标志为true // 视频输出完成置标志为true
PlumageRender::RenderOutput::signal.imageSequenceToVideoComplete = true; renderOutput.signal.imageSequenceToVideoComplete = true;
std::cout << "vidoe codec complete,saved in:" << resultVideoPath << std::endl; std::cout << "vidoe codec complete,saved in:" << resultVideoPath << std::endl;
std::cout << "star to clean up image sequence" << 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; 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())) if (std::filesystem::is_directory(entry.path()))
{ {
@ -405,7 +405,7 @@ void PlumageRender::RenderOutput::removeImageSequence()
std::filesystem::remove(entry.path()); 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; std::cout << "clean up complete" << std::endl;
} }
return; return;

View File

@ -3,15 +3,22 @@
#include <map> #include <map>
#include <string> #include <string>
#ifndef _RENDER_H
#include "render.h"
#define _RENDER_H
#endif // !RENDER_H
#ifndef _PBR_H #ifndef _PBR_H
#include "PBR.h" #include "PBR.h"
#define _PBR_H #define _PBR_H
#endif // !PBR_H #endif // !PBR_H
#ifndef _RENDER_H #ifndef _VULKANFOUNDATION_H
#include "render.h" #include "vulkanFoundation.h"
#define _RENDER_H #define _VULKANFOUNDATION_H
#endif // !RENDER_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 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: private:
@ -70,13 +77,13 @@ namespace PlumageRender
static uint64_t savedFrameCounter; 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: private:

View File

@ -54,12 +54,7 @@ void PlumageRender::Setter::getSettingFromCommandLine()
} }
PlumageRender::Setter::Settings PlumageRender::Setter::getSettings() inline uint32_t PlumageRender::Setter::getFrameRange()
{
return settings ;
}
PlumageRender::Setter::FilePath PlumageRender::Setter::getFilePath()
{ {
return filePath; return settings.endFrameIndex - settings.startFrameCount;
} }

View File

@ -44,6 +44,7 @@ namespace PlumageRender
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; // 多重采样倍率 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; // 多重采样倍率
}settings; }settings;
uint32_t getFrameRange();
struct FilePath struct FilePath
{ {

View File

@ -1,31 +1,35 @@
#include "vulkanFoundation.h" #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 // 创建instance
createInstance(setter); createInstance(setter);
// 设置校验层消息回调 // 设置校验层消息回调
setupDebugMessager(); setupDebugMessager(setter);
// 选择主机显卡 // 选择主机显卡
pickPhysicalDevice(); pickPhysicalDevice(setter);
// 实时显示结果的glfw surface if (!setter.settings.headless)
createSurface(); {
// 实时显示结果的glfw surface
createSurface(setter);
}
// 完成逻辑设备创建 // 完成逻辑设备创建
createLogicalDevice(); createLogicalDevice(setter);
// 创建交换链 // 创建交换链
createSwapChain(); createSwapChain(setter);
// 创建交换链中的imageView // 创建交换链中的imageView
createImageView(); createImageView(setter);
// 创建renderpass // 创建renderpass
createRenderPass(); createRenderPass(setter);
// 创建资源描述符层级 // 创建资源描述符层级
createDescriptorSetLayout(); createDescriptorSetLayout();
@ -34,29 +38,29 @@ void VulkanBackend::VulkanFoundation::initVulkan(PlumageRender::Setter setter)
createPipelineCache(); 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.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo; createInfo.pApplicationInfo = &appInfo;
auto requiredExtensions = getRequiredExtensions(); auto requiredExtensions = getRequiredExtensions(setter);
createInfo.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size()); createInfo.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size());
createInfo.ppEnabledExtensionNames = requiredExtensions.data(); createInfo.ppEnabledExtensionNames = requiredExtensions.data();
@ -163,9 +167,9 @@ std::vector<const char*> VulkanBackend::VulkanFoundation::getRequiredExtensions(
void VulkanBackend::VulkanFoundation::setupDebugMessager() void VulkanBackend::VulkanFoundation::setupDebugMessager(PlumageRender::Setter setter)
{ {
if (!PlumageRender::Setter::settings.validation) if (!setter.settings.validation)
{ {
return; 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; return;
} }
@ -235,7 +239,7 @@ void VulkanBackend::VulkanFoundation::createSurface()
void VulkanBackend::VulkanFoundation::pickPhysicalDevice() void VulkanBackend::VulkanFoundation::pickPhysicalDevice(PlumageRender::Setter setter)
{ {
uint32_t deviceCount = 0; uint32_t deviceCount = 0;
@ -247,14 +251,14 @@ void VulkanBackend::VulkanFoundation::pickPhysicalDevice()
} }
std::vector<VkPhysicalDevice> devices(deviceCount); std::vector<VkPhysicalDevice> devices(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); 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) for (const auto& device : devices)
{ {
if (isDeviceSuitable(device)) if (isDeviceSuitable(device,setter))
{ {
physicalDevice = device; physicalDevice = device;
break; 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); bool extensionsSupported = checkDeviceExtensionSupport(device);
return extensionsSupported; return extensionsSupported;
@ -278,7 +282,7 @@ bool VulkanBackend::VulkanFoundation::isDeviceSuitable(VkPhysicalDevice device)
{ // 非无头下在检查扩展支持的同时要检查swapchain { // 非无头下在检查扩展支持的同时要检查swapchain
bool extensionsSupported = checkDeviceExtensionSupport(device); bool extensionsSupported = checkDeviceExtensionSupport(device);
bool swapChainAdequate = false; bool swapChainAdequate = false;
QueueFamilyIndices indices = findQueueFamilies(device); QueueFamilyIndices indices = findQueueFamilies(device,setter);
if (extensionsSupported) if (extensionsSupported)
{ {
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device); 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; QueueFamilyIndices indices;
@ -320,7 +324,7 @@ VulkanBackend::VulkanFoundation::QueueFamilyIndices VulkanBackend::VulkanFoundat
// 检查显示队列支持 // 检查显示队列支持
int i = 0; int i = 0;
if (!PlumageRender::Setter::settings.headless) if (!setter.settings.headless)
{ {
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
} }
@ -331,7 +335,7 @@ VulkanBackend::VulkanFoundation::QueueFamilyIndices VulkanBackend::VulkanFoundat
indices.graphicsFamily = i; indices.graphicsFamily = i;
} }
// 无头下不需要检查present queue // 无头下不需要检查present queue
if (PlumageRender::Setter::settings.headless) if (setter.settings.headless)
{ {
if (indices.isGraphicsFamilyComplete()) 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<VkDeviceQueueCreateInfo> queueCreateInfos; std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
if (PlumageRender::Setter::settings.headless) if (setter.settings.headless)
{ {
VkDeviceQueueCreateInfo queueCreateInfo{}; VkDeviceQueueCreateInfo queueCreateInfo{};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@ -423,7 +427,7 @@ void VulkanBackend::VulkanFoundation::createLogicalDevice()
} }
std::vector<const char*> enabledExtensions{}; std::vector<const char*> enabledExtensions{};
if (!PlumageRender::Setter::settings.headless) if (!setter.settings.headless)
{ {
for (auto swapchainExtension: swapchainExtensions) for (auto swapchainExtension: swapchainExtensions)
{ {
@ -440,7 +444,7 @@ void VulkanBackend::VulkanFoundation::createLogicalDevice()
deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data(); deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data();
//新版本vulkan已不对实例和设备特定验证层做区分此处保证兼容性 //新版本vulkan已不对实例和设备特定验证层做区分此处保证兼容性
if (PlumageRender::Setter::settings.validation) if (setter.settings.validation)
{ {
deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size()); deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
deviceCreateInfo.ppEnabledLayerNames = validationLayers.data(); deviceCreateInfo.ppEnabledLayerNames = validationLayers.data();
@ -456,7 +460,7 @@ void VulkanBackend::VulkanFoundation::createLogicalDevice()
} }
vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicQueue); vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicQueue);
if (PlumageRender::Setter::settings.headless) if (setter.settings.headless)
{ {
vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue); 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; return;
} }
@ -476,7 +480,7 @@ void VulkanBackend::VulkanFoundation::createSwapChain()
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes,setter);
VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities); VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities);
uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
@ -497,7 +501,7 @@ void VulkanBackend::VulkanFoundation::createSwapChain()
createInfo.imageArrayLayers = 1; createInfo.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 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() }; uint32_t queueFamilyIndices[] = { indices.graphicsFamily.value(),indices.presentFamily.value() };
if (indices.graphicsFamily != indices.presentFamily) if (indices.graphicsFamily != indices.presentFamily)
{ {
@ -545,7 +549,7 @@ VkSurfaceFormatKHR VulkanBackend::VulkanFoundation::chooseSwapSurfaceFormat(cons
return availableFormats[0]; return availableFormats[0];
} }
VkPresentModeKHR VulkanBackend::VulkanFoundation::chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes) VkPresentModeKHR VulkanBackend::VulkanFoundation::chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes, PlumageRender::Setter setter)
{ {
// Get available present modes // Get available present modes
uint32_t presentModeCount; 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 // If v-sync is not requested, try to find a mailbox mode
// It's the lowest latency non-tearing present mode available // 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++) 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 colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM;
VkFormat depthFormat = findDepthFormat(); VkFormat depthFormat = findDepthFormat();
if (PlumageRender::Setter::settings.headless) if (setter.settings.headless)
{ {
if (PlumageRender::Setter::settings.multiSampling) if (setter.settings.multiSampling)
{ {
VkImageCreateInfo imageCI{}; VkImageCreateInfo imageCI{};
imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCI.imageType = VK_IMAGE_TYPE_2D; imageCI.imageType = VK_IMAGE_TYPE_2D;
imageCI.format = colorAttachmentFormat; imageCI.format = colorAttachmentFormat;
imageCI.extent.width = PlumageRender::Setter::settings.width; imageCI.extent.width = setter.settings.width;
imageCI.extent.height =PlumageRender::Setter::settings.height; imageCI.extent.height = setter.settings.height;
imageCI.extent.depth = 1; imageCI.extent.depth = 1;
imageCI.mipLevels = 1; imageCI.mipLevels = 1;
imageCI.arrayLayers = 1; imageCI.arrayLayers = 1;
imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; 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.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@ -660,14 +664,14 @@ void VulkanBackend::VulkanFoundation::createImageView()
// Depth target // Depth target
imageCI.imageType = VK_IMAGE_TYPE_2D; imageCI.imageType = VK_IMAGE_TYPE_2D;
imageCI.format = depthFormat; imageCI.format = depthFormat;
imageCI.extent.width =PlumageRender::Setter::settings.width; imageCI.extent.width =setter.settings.width;
imageCI.extent.height =PlumageRender::Setter::settings.height; imageCI.extent.height =setter.settings.height;
imageCI.extent.depth = 1; imageCI.extent.depth = 1;
imageCI.mipLevels = 1; imageCI.mipLevels = 1;
imageCI.arrayLayers = 1; imageCI.arrayLayers = 1;
imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; 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.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.depthAttachment.image)); 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.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCI.imageType = VK_IMAGE_TYPE_2D; imageCI.imageType = VK_IMAGE_TYPE_2D;
imageCI.format = colorAttachmentFormat; imageCI.format = colorAttachmentFormat;
imageCI.extent.width =PlumageRender::Setter::settings.width; imageCI.extent.width =setter.settings.width;
imageCI.extent.height =PlumageRender::Setter::settings.height; imageCI.extent.height =setter.settings.height;
imageCI.extent.depth = 1; imageCI.extent.depth = 1;
imageCI.mipLevels = 1; imageCI.mipLevels = 1;
imageCI.arrayLayers = 1; imageCI.arrayLayers = 1;
@ -749,8 +753,8 @@ void VulkanBackend::VulkanFoundation::createImageView()
image.pNext = NULL; image.pNext = NULL;
image.imageType = VK_IMAGE_TYPE_2D; image.imageType = VK_IMAGE_TYPE_2D;
image.format = depthFormat; image.format = depthFormat;
image.extent.width =PlumageRender::Setter::settings.width; image.extent.width =setter.settings.width;
image.extent.height =PlumageRender::Setter::settings.height; image.extent.height =setter.settings.height;
image.extent.depth = 1; image.extent.depth = 1;
image.mipLevels = 1; image.mipLevels = 1;
image.arrayLayers = 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 colorAttachmentFormat;
VkFormat depthAttachmentFormat = findDepthFormat(); VkFormat depthAttachmentFormat = findDepthFormat();
VkImageLayout colorAttachmentFinallayout; VkImageLayout colorAttachmentFinallayout;
if (PlumageRender::Setter::settings.headless) if (setter.settings.headless)
{ {
colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM; colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM;
colorAttachmentFinallayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; colorAttachmentFinallayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
@ -847,12 +851,12 @@ void VulkanBackend::VulkanFoundation::createRenderPass()
colorAttachmentFinallayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; colorAttachmentFinallayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
} }
if (PlumageRender::Setter::settings.multiSampling) { if (setter.settings.multiSampling) {
std::array<VkAttachmentDescription, 4> attachments = {}; std::array<VkAttachmentDescription, 4> attachments = {};
// Multisampled attachment that we render to // Multisampled attachment that we render to
attachments[0].format = colorAttachmentFormat; 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].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@ -873,7 +877,7 @@ void VulkanBackend::VulkanFoundation::createRenderPass()
// Multisampled depth attachment we render to // Multisampled depth attachment we render to
attachments[2].format = depthAttachmentFormat; 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].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachments[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[2].stencilLoadOp = VK_ATTACHMENT_LOAD_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{}; VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI{};
inputAssemblyStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; inputAssemblyStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
@ -1149,8 +1153,8 @@ void VulkanBackend::VulkanFoundation::createGraphicPipeline()
VkPipelineMultisampleStateCreateInfo multisampleStateCI{}; VkPipelineMultisampleStateCreateInfo multisampleStateCI{};
multisampleStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampleStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
if (PlumageRender::Setter::settings.multiSampling) { if (setter.settings.multiSampling) {
multisampleStateCI.rasterizationSamples =PlumageRender::Setter::settings.sampleCount; multisampleStateCI.rasterizationSamples =setter.settings.sampleCount;
} }
std::vector<VkDynamicState> dynamicStateEnables = { std::vector<VkDynamicState> dynamicStateEnables = {
@ -1213,14 +1217,14 @@ void VulkanBackend::VulkanFoundation::createGraphicPipeline()
pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size()); pipelineCI.stageCount = static_cast<uint32_t>(shaderStages.size());
pipelineCI.pStages = shaderStages.data(); pipelineCI.pStages = shaderStages.data();
if (PlumageRender::Setter::settings.multiSampling) { if (setter.settings.multiSampling) {
multisampleStateCI.rasterizationSamples =PlumageRender::Setter::settings.sampleCount; multisampleStateCI.rasterizationSamples =setter.settings.sampleCount;
} }
// Skybox pipeline (background cube) // Skybox pipeline (background cube)
shaderStages = { shaderStages = {
loadShader(device,PlumageRender::Setter::filePath.skyboxVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), loadShader(device,setter.filePath.skyboxVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT),
loadShader(device,PlumageRender::Setter::filePath.skyboxFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) loadShader(device,setter.filePath.skyboxFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT)
}; };
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.skybox)); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.skybox));
for (auto shaderStage : shaderStages) { for (auto shaderStage : shaderStages) {
@ -1229,8 +1233,8 @@ void VulkanBackend::VulkanFoundation::createGraphicPipeline()
// PBR pipeline // PBR pipeline
shaderStages = { shaderStages = {
loadShader(device,PlumageRender::Setter::filePath.pbrVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT), loadShader(device,setter.filePath.pbrVertShaderPath, VK_SHADER_STAGE_VERTEX_BIT),
loadShader(device,PlumageRender::Setter::filePath.pbrFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT) loadShader(device,setter.filePath.pbrFragShaderPath, VK_SHADER_STAGE_FRAGMENT_BIT)
}; };
depthStencilStateCI.depthWriteEnable = VK_TRUE; depthStencilStateCI.depthWriteEnable = VK_TRUE;
depthStencilStateCI.depthTestEnable = 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++) for (int i = 0; i < frameRange; i++)
{ {
VkImageView attachments[4]; VkImageView attachments[4];
@ -1277,8 +1284,8 @@ void VulkanBackend::VulkanFoundation::createFramebuffer()
framebufferCreateInfo.renderPass = renderPass; framebufferCreateInfo.renderPass = renderPass;
framebufferCreateInfo.attachmentCount = 4; framebufferCreateInfo.attachmentCount = 4;
framebufferCreateInfo.pAttachments = attachments; framebufferCreateInfo.pAttachments = attachments;
framebufferCreateInfo.width =PlumageRender::Setter::settings.width; framebufferCreateInfo.width =setter.settings.width;
framebufferCreateInfo.height =PlumageRender::Setter::settings.height; framebufferCreateInfo.height =setter.settings.height;
framebufferCreateInfo.layers = 1; framebufferCreateInfo.layers = 1;
VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffers[i])); VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffers[i]));
@ -1297,8 +1304,8 @@ void VulkanBackend::VulkanFoundation::createFramebuffer()
framebufferCreateInfo.renderPass = renderPass; framebufferCreateInfo.renderPass = renderPass;
framebufferCreateInfo.attachmentCount = 2; framebufferCreateInfo.attachmentCount = 2;
framebufferCreateInfo.pAttachments = attachments; framebufferCreateInfo.pAttachments = attachments;
framebufferCreateInfo.width =PlumageRender::Setter::settings.width; framebufferCreateInfo.width =setter.settings.width;
framebufferCreateInfo.height =PlumageRender::Setter::settings.height; framebufferCreateInfo.height =setter.settings.height;
framebufferCreateInfo.layers = 1; framebufferCreateInfo.layers = 1;
VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffers[i])); VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffers[i]));
@ -1309,16 +1316,16 @@ void VulkanBackend::VulkanFoundation::createFramebuffer()
} }
else else
{ {
createSwapChainFramebuffer(); createSwapChainFramebuffer(setter);
} }
} }
void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer() void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer(PlumageRender::Setter setter)
{ {
uint32_t attachmentCount; uint32_t attachmentCount;
VkImageView attachments[attachmentCount]; VkImageView attachments[attachmentCount];
if (PlumageRender::Setter::settings.multiSampling) { if (setter.settings.multiSampling) {
attachmentCount = 4; attachmentCount = 4;
attachments[0] = multisampleTarget.colorAttachment.view; attachments[0] = multisampleTarget.colorAttachment.view;
attachments[1] = multisampleTarget.depthAttachment.view; attachments[1] = multisampleTarget.depthAttachment.view;
@ -1336,8 +1343,8 @@ void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer()
frameBufferCI.renderPass = renderPass; frameBufferCI.renderPass = renderPass;
frameBufferCI.attachmentCount = attachmentCount; frameBufferCI.attachmentCount = attachmentCount;
frameBufferCI.pAttachments = attachments; frameBufferCI.pAttachments = attachments;
frameBufferCI.width =PlumageRender::Setter::settings.width; frameBufferCI.width =setter.settings.width;
frameBufferCI.height =PlumageRender::Setter::settings.height; frameBufferCI.height =setter.settings.height;
frameBufferCI.layers = 1; frameBufferCI.layers = 1;
@ -1345,7 +1352,7 @@ void VulkanBackend::VulkanFoundation::createSwapChainFramebuffer()
// Create frame buffers for every swap chain image // Create frame buffers for every swap chain image
framebuffers.resize(swapChainImageViews.size()); framebuffers.resize(swapChainImageViews.size());
for (uint32_t i = 0; i < swapChainImageViews.size(); i++) { for (uint32_t i = 0; i < swapChainImageViews.size(); i++) {
if (PlumageRender::Setter::settings.multiSampling) { if (setter.settings.multiSampling) {
attachments[3] = swapChainImageViews[i]; attachments[3] = swapChainImageViews[i];
} }
else { 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{}; VkCommandPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 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); uniformBuffers.resize(frameRange);
} }
else 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.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)); 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 // Scene
shaderDataScene.projection = camera.matrices.perspective; shaderDataScene.projection = camera.matrices.perspective;
shaderDataScene.view = camera.matrices.view; shaderDataScene.view = camera.matrices.view;
// Center and scale model // 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; 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(PlumageRender::renderMain::models.scene.aabb[3][0], PlumageRender::renderMain::models.scene.aabb[3][1], PlumageRender::renderMain::models.scene.aabb[3][2]); 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(PlumageRender::renderMain::models.scene.aabb[0][0], PlumageRender::renderMain::models.scene.aabb[1][1], PlumageRender::renderMain::models.scene.aabb[2][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 = glm::mat4(1.0f);
shaderDataScene.model[0][0] = scale; shaderDataScene.model[0][0] = scale;
@ -1424,7 +1432,7 @@ void VulkanBackend::VulkanFoundation::updateUniformBuffers()
shaderDataSkybox.model = glm::mat4(glm::mat3(camera.matrices.view)); shaderDataSkybox.model = glm::mat4(glm::mat3(camera.matrices.view));
} }
void VulkanBackend::VulkanFoundation::createDescriptorPool() void VulkanBackend::VulkanFoundation::createDescriptorPool(PlumageRender::renderMain mainRender)
{ {
/* /*
Descriptor Pool Descriptor Pool
@ -1436,7 +1444,7 @@ void VulkanBackend::VulkanFoundation::createDescriptorPool()
// Environment samplers (radiance, irradiance, brdflut) // Environment samplers (radiance, irradiance, brdflut)
imageSamplerCount += 3; imageSamplerCount += 3;
std::vector<glTFModel::Model*> modellist = { &PlumageRender::renderMain::models.skybox, &PlumageRender::renderMain::models.scene }; std::vector<glTFModel::Model*> modellist = { &mainRender.models.skybox, &mainRender.models.scene };
for (auto& model : modellist) { for (auto& model : modellist) {
for (auto& material : model->materials) { for (auto& material : model->materials) {
imageSamplerCount += 5; imageSamplerCount += 5;
@ -1461,10 +1469,11 @@ void VulkanBackend::VulkanFoundation::createDescriptorPool()
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool)); 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); descriptorSets.resize(frameRange);
} }
else else
@ -1672,11 +1681,12 @@ void VulkanBackend::VulkanFoundation::createSkyboxDescriptorSets()
void VulkanBackend::VulkanFoundation::allocateCommandBuffers() void VulkanBackend::VulkanFoundation::allocateCommandBuffers(PlumageRender::Setter setter)
{ {
// resize // resize
if (PlumageRender::Setter::settings.headless) if (setter.settings.headless)
{ {
auto frameRange = setter.getFrameRange();
commandbuffers.resize(frameRange); commandbuffers.resize(frameRange);
} }
else else
@ -1707,14 +1717,14 @@ void VulkanBackend::VulkanFoundation::cleanupSwapChain()
vkDestroySwapchainKHR(device, swapChain, nullptr); vkDestroySwapchainKHR(device, swapChain, nullptr);
} }
void VulkanBackend::VulkanFoundation::createCommandBuffer() void VulkanBackend::VulkanFoundation::createCommandBuffer(PlumageRender::Setter setter,PlumageRender::renderMain mainRender,UI* plumageGUI)
{ {
VkCommandBufferBeginInfo cmdBufferBeginInfo{}; VkCommandBufferBeginInfo cmdBufferBeginInfo{};
cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
VkClearValue clearValues[3]; VkClearValue clearValues[3];
if (PlumageRender::Setter::settings.multiSampling) { if (setter.settings.multiSampling) {
clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } }; clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
clearValues[1].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 }; clearValues[2].depthStencil = { 1.0f, 0 };
@ -1729,9 +1739,9 @@ void VulkanBackend::VulkanFoundation::createCommandBuffer()
renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderPass = renderPass;
renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent.width =PlumageRender::Setter::settings.width; renderPassBeginInfo.renderArea.extent.width =setter.settings.width;
renderPassBeginInfo.renderArea.extent.height =PlumageRender::Setter::settings.height; renderPassBeginInfo.renderArea.extent.height =setter.settings.height;
renderPassBeginInfo.clearValueCount =PlumageRender::Setter::settings.multiSampling ? 3 : 2; renderPassBeginInfo.clearValueCount =setter.settings.multiSampling ? 3 : 2;
renderPassBeginInfo.pClearValues = clearValues; renderPassBeginInfo.pClearValues = clearValues;
for (uint32_t i = 0; i < commandbuffers.size(); ++i) for (uint32_t i = 0; i < commandbuffers.size(); ++i)
@ -1744,25 +1754,25 @@ void VulkanBackend::VulkanFoundation::createCommandBuffer()
vkCmdBeginRenderPass(currentCB, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(currentCB, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
VkViewport viewport{}; VkViewport viewport{};
viewport.width = (float)PlumageRender::Setter::settings.width; viewport.width = (float)setter.settings.width;
viewport.height = (float)PlumageRender::Setter::settings.height; viewport.height = (float)setter.settings.height;
viewport.minDepth = 0.0f; viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f; viewport.maxDepth = 1.0f;
vkCmdSetViewport(currentCB, 0, 1, &viewport); vkCmdSetViewport(currentCB, 0, 1, &viewport);
VkRect2D scissor{}; 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); vkCmdSetScissor(currentCB, 0, 1, &scissor);
VkDeviceSize offsets[1] = { 0 }; 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); vkCmdBindDescriptorSets(currentCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[i].skybox, 0, nullptr);
vkCmdBindPipeline(currentCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.skybox); 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); vkCmdBindVertexBuffers(currentCB, 0, 1, &model.vertices.buffer, offsets);
if (model.indices.buffer != VK_NULL_HANDLE) { if (model.indices.buffer != VK_NULL_HANDLE) {
@ -1786,9 +1796,9 @@ void VulkanBackend::VulkanFoundation::createCommandBuffer()
} }
// User interface // User interface
if (!PlumageRender::Setter::settings.headless) if (!setter.settings.headless)
{ {
plumageGui.gui->draw(currentCB); plumageGUI->draw(currentCB);
} }
vkCmdEndRenderPass(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); waitFences.resize(setter.settings.MaxFrameInFlight);
presentCompleteSemaphores.resize(PlumageRender::Setter::settings.MaxFrameInFlight); presentCompleteSemaphores.resize(setter.settings.MaxFrameInFlight);
renderCompleteSemaphores.resize(PlumageRender::Setter::settings.MaxFrameInFlight); renderCompleteSemaphores.resize(setter.settings.MaxFrameInFlight);
// Command buffer execution fences // Command buffer execution fences
for (auto& waitFence : waitFences) { for (auto& waitFence : waitFences) {
VkFenceCreateInfo fenceCI{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT }; VkFenceCreateInfo fenceCI{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT };
VK_CHECK_RESULT(vkCreateFence(device, &fenceCI, nullptr, &waitFence)); VK_CHECK_RESULT(vkCreateFence(device, &fenceCI, nullptr, &waitFence));
} }
if (!PlumageRender::Setter::settings.headless) if (!setter.settings.headless)
{ {
for (auto& semaphore : presentCompleteSemaphores) { for (auto& semaphore : presentCompleteSemaphores) {
VkSemaphoreCreateInfo semaphoreCI{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 }; 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); 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) if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebuffeerResized)
{ {
framebuffeerResized = false; framebuffeerResized = false;
recreateSwapChain(); recreateSwapChain(setter);
return framebuffeerResized; return framebuffeerResized;
} }
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) 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])); 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] }; 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) if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
{ {
framebufferResized = false; framebufferResized = false;
recreateSwapChain(); recreateSwapChain(setter);
} }
else if (result != VK_SUCCESS) 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() void VulkanBackend::VulkanFoundation::updateShaderData()
@ -1985,7 +2056,7 @@ void VulkanBackend::VulkanFoundation::updateShaderData()
0.0f); 0.0f);
} }
void VulkanBackend::VulkanFoundation::recreateSwapChain() void VulkanBackend::VulkanFoundation::recreateSwapChain(PlumageRender::Setter setter)
{ {
int width = 0, height = 0; int width = 0, height = 0;
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
@ -2003,9 +2074,9 @@ void VulkanBackend::VulkanFoundation::recreateSwapChain()
cleanupSwapChain(); cleanupSwapChain();
createSwapChain(); createSwapChain(setter);
createImageView(); createImageView(setter);
createFramebuffer(); createFramebuffer(setter);
} }

View File

@ -1,12 +1,18 @@
#pragma once #pragma once
#include "GLFW/glfw3.h"
#include <optional> #include <optional>
#include <set> #include <set>
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#ifndef _RENDER_H
#include "render.h"
#define _RENDER_H
#endif // !RENDER_H
#ifndef _GLTFMODEL_H #ifndef _GLTFMODEL_H
#include "glTFModel.h" #include "glTFModel.h"
#define _GLTFMODEL_H #define _GLTFMODEL_H
@ -18,13 +24,33 @@
#endif // !RENDERSETTER_H #endif // !RENDERSETTER_H
#ifndef _GLFW3_H
#include "GLFW/glfw3.h"
#define _GLFW3_H
#endif // !_GLFW3_H
#ifndef _VULKANUTILS_HPP
#include "VulkanUtils.hpp" #include "VulkanUtils.hpp"
#define _VULKANUTILS_HPP
#endif // !_VULKANUTILS_HPP
#include <VulkanSwapChain.hpp> #include <VulkanSwapChain.hpp>
#ifndef _VULKANDEVICE_HPP
#include "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 namespace VulkanBackend
@ -33,66 +59,8 @@ namespace VulkanBackend
{ {
public: public:
VulkanFoundation(); VulkanFoundation();
~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);
}
const std::vector<const char*> validationLayers = { const std::vector<const char*> validationLayers = {
"VK_LAYER_KHRONOS_validation" "VK_LAYER_KHRONOS_validation"
@ -154,24 +122,26 @@ namespace VulkanBackend
VkQueue presentQueue; 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(Camera camera, PlumageRender::renderMain mainRender);
void updateUniformBuffers();
void updateShaderData(); 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 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: private:
@ -292,10 +262,10 @@ namespace VulkanBackend
std::vector<const char*> getRequiredExtensions(PlumageRender::Setter setter); std::vector<const char*> getRequiredExtensions(PlumageRender::Setter setter);
// 实时显示结果使用的glfwSurface,受headless配置项控制 // 实时显示结果使用的glfwSurface,受headless配置项控制
void createSurface(); void createSurface(PlumageRender::Setter setter);
// 设置校验层使用的消息回调 // 设置校验层使用的消息回调
void setupDebugMessager(); void setupDebugMessager(PlumageRender::Setter setter);
void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo); void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo);
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
@ -306,27 +276,27 @@ namespace VulkanBackend
void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator); void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator);
// 通过检查队列、交换链、扩展支持,选择合适的显卡 // 通过检查队列、交换链、扩展支持,选择合适的显卡
void pickPhysicalDevice(); void pickPhysicalDevice(PlumageRender::Setter setter);
bool isDeviceSuitable(VkPhysicalDevice device); bool isDeviceSuitable(VkPhysicalDevice device, PlumageRender::Setter setter);
bool checkDeviceExtensionSupport(VkPhysicalDevice device); 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); 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<VkSurfaceFormatKHR>& availableFormats); VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes); VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes, PlumageRender::Setter setter);
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities); VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
void cleanupSwapChain(); void cleanupSwapChain();
// 创建交换链中的imageView用于访问交换链中图像 // 创建交换链中的imageView用于访问交换链中图像
void createImageView(); void createImageView(PlumageRender::Setter setter);
// 创建renderPass // 创建renderPass
void createRenderPass(); void createRenderPass(PlumageRender::Setter setter);
VkFormat findDepthFormat(); VkFormat findDepthFormat();
VkFormat findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features); VkFormat findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
bool hasStencilComponent(VkFormat format); bool hasStencilComponent(VkFormat format);
@ -341,23 +311,23 @@ namespace VulkanBackend
void createPipelineCache(); void createPipelineCache();
// 创建图形管线 // 创建图形管线
void createGraphicPipeline(); void createGraphicPipeline(PlumageRender::Setter setter);
// 创建帧缓冲区 // 创建帧缓冲区
void createFramebuffer(); void createFramebuffer(PlumageRender::Setter setter);
void createSwapChainFramebuffer(); 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 createSkyboxDescriptorSets();
// 创建命令缓存区 // 创建命令缓存区
void allocateCommandBuffers(); void allocateCommandBuffers(PlumageRender::Setter setter);
void createglTFNodeCommandBuffer(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode); 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()
{
}
} }