完成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
#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
```

View File

@ -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 <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
#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 <vulkan/vulkan.h>
#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

View File

@ -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();

View File

@ -18,7 +18,10 @@
#include <vulkan/vulkan.h>
#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 <camera.hpp>
#include <VulkanTexture.hpp>
#include <VulkanUtils.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 _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:

View File

@ -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<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)
{
// 暂时不改此处需要将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
{
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);
// 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;

View File

@ -3,15 +3,22 @@
#include <map>
#include <string>
#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:

View File

@ -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;
}

View File

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

View File

@ -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<uint32_t>(requiredExtensions.size());
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;
}
@ -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<VkPhysicalDevice> 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<VkDeviceQueueCreateInfo> 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<const char*> 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<uint32_t>(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<VkPresentModeKHR>& availablePresentModes)
VkPresentModeKHR VulkanBackend::VulkanFoundation::chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& 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<VkAttachmentDescription, 4> 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<VkDynamicState> dynamicStateEnables = {
@ -1213,14 +1217,14 @@ void VulkanBackend::VulkanFoundation::createGraphicPipeline()
pipelineCI.stageCount = static_cast<uint32_t>(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<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& 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);
}

View File

@ -1,12 +1,18 @@
#pragma once
#include "GLFW/glfw3.h"
#include <optional>
#include <set>
#include <stdexcept>
#include <vector>
#include <vulkan/vulkan.h>
#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 <VulkanSwapChain.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 _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<const char*> 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<const char*> 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<VkSurfaceFormatKHR>& availableFormats);
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& 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<VkFormat>& 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()
{
}
}