重构完成未debug

ink-soul 2024-04-08 18:10:00 +08:00
parent a74853688c
commit 2f5fd63dd9
8 changed files with 222 additions and 122 deletions

View File

@ -39,11 +39,7 @@ void PlumageRender::renderMain::framebufferResizeCallback(GLFWwindow* window, in
// todo重写成glfw的
void PlumageRender::renderMain::windowResized()
{
buildCommandBuffers();
vkDeviceWaitIdle(device);
updateUniformBuffers();
//update UI
updateUIOverlay();
}
void PlumageRender::renderMain::prepare()
@ -52,18 +48,18 @@ void PlumageRender::renderMain::prepare()
setupCamera();
loadAssets();
generateBRDFLUT();
generateCubemaps();
renderInput.loadAssets();
pbrMaterial.generateBRDFLUT();
pbrMaterial.generateCubemap();
//prepareUniformBuffers();
//setupDescriptors();
preparePipelines();
//preparePipelines();
if (!PlumageRender::Setter::settings.headless)
{
gui = new UI(vulkanDevice, renderPass, queue, pipelineCache,PlumageRender::Setter::settings.sampleCount);
updateUIOverlay();
auto gui = renderGUI.gui;
renderGUI.updateUIOverlay();
}
buildCommandBuffers();
;
prepared = true;
}
@ -86,12 +82,18 @@ void PlumageRender::renderMain::submitWork(VkCommandBuffer cmdBuffer, VkQueue qu
submitInfo.pCommandBuffers = &cmdBuffer;
VkFenceCreateInfo fenceInfo = vks::initializers::fenceCreateInfo();
VkFence fence;
VK_CHECK_RESULT(vkCreateFence(device, &fenceInfo, nullptr, &fence));
VK_CHECK_RESULT(vkCreateFence(VulkanBackend::VulkanFoundation::device, &fenceInfo, nullptr, &fence));
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence));
VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX));
vkDestroyFence(device, fence, nullptr);
VK_CHECK_RESULT(vkWaitForFences(VulkanBackend::VulkanFoundation::device, 1, &fence, VK_TRUE, UINT64_MAX));
vkDestroyFence(VulkanBackend::VulkanFoundation::device, fence, nullptr);
}
void PlumageRender::renderMain::submitToPresentQueue()
{
}
void PlumageRender::renderMain::render()
{
if (!prepared) {
@ -100,7 +102,7 @@ void PlumageRender::renderMain::render()
if (!PlumageRender::Setter::settings.headless)
{
updateUIOverlay();
renderGUI.updateUIOverlay();
}
//加入写到文件的函数
@ -108,92 +110,113 @@ void PlumageRender::renderMain::render()
//outputImageSequeue(swapChainImage,filePath.imageSequenceFilePath);
outputImageSequence();
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX));
uint32_t imageIndex;
imageSequenceToVideo();
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex]));
VK_CHECK_RESULT(vkWaitForFences(VulkanBackend::VulkanFoundation::device, 1, &vkFoundation.waitFences[frameIndex], VK_TRUE, UINT64_MAX));
VkResult result = vkAcquireNextImageKHR(VulkanBackend::VulkanFoundation::device, VulkanBackend::VulkanFoundation::swapChain, UINT64_MAX, vkFoundation.renderCompleteSemaphores[frameIndex], VK_NULL_HANDLE, &imageIndex);
VkResult acquire = swapChain.acquireNextImage(presentCompleteSemaphores[frameIndex], &currentBuffer);
if ((acquire == VK_ERROR_OUT_OF_DATE_KHR) || (acquire == VK_SUBOPTIMAL_KHR)) {
windowResize();
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized)
{
framebufferResized = false;
vkFoundation.recreateSwapChain();
return;
}
else {
VK_CHECK_RESULT(acquire);
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
{
throw std::runtime_error("failed to acquire swap chain image in drawFrame");
}
VK_CHECK_RESULT(vkResetFences(VulkanBackend::VulkanFoundation::device, 1, &vkFoundation.waitFences[frameIndex]));
renderOutput.outputImageSequence();
renderOutput.imageSequenceToVideo();
// Update UBOs
updateUniformBuffers();
UniformBufferSet[currentUB] = uniformBuffers[currentBuffer];
memcpy(currentUB.scene.mapped, &shaderDataScene, sizeof(shaderDataScene));
memcpy(currentUB.params.mapped, &shaderData, sizeof(shaderData));
memcpy(currentUB.skybox.mapped, &shaderDataSkybox, sizeof(shaderDataSkybox));
vkFoundation.updateUniformBuffers();
VulkanBackend::VulkanFoundation::UniformBufferSet currentUB = vkFoundation.uniformBuffers[currentBuffer];
memcpy(currentUB.scene.mapped, &vkFoundation.shaderDataScene, sizeof(vkFoundation.shaderDataScene));
memcpy(currentUB.params.mapped, &PBR::Material::shaderData, sizeof(PBR::Material::shaderData));
memcpy(currentUB.skybox.mapped, &vkFoundation.shaderDataSkybox, sizeof(vkFoundation.shaderDataSkybox));
const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pWaitDstStageMask = &waitDstStageMask;
submitInfo.pWaitSemaphores = &presentCompleteSemaphores[frameIndex];
submitInfo.pWaitSemaphores = &vkFoundation.presentCompleteSemaphores[frameIndex];
submitInfo.waitSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &renderCompleteSemaphores[frameIndex];
submitInfo.pSignalSemaphores = &vkFoundation.renderCompleteSemaphores[frameIndex];
submitInfo.signalSemaphoreCount = 1;
submitInfo.pCommandBuffers = &commandBuffers[currentBuffer];
submitInfo.pCommandBuffers = &vkFoundation.commandbuffers[currentBuffer];
submitInfo.commandBufferCount = 1;
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[frameIndex]));
VK_CHECK_RESULT(vkQueueSubmit(vkFoundation.graphicQueue, 1, &submitInfo, vkFoundation.waitFences[frameIndex]));
//显示队列
VkResult present = swapChain.queuePresent(queue, currentBuffer, renderCompleteSemaphores[frameIndex]);
if (!((present == VK_SUCCESS) || (present == VK_SUBOPTIMAL_KHR))) {
if (present == VK_ERROR_OUT_OF_DATE_KHR) {
windowResize();
return;
}
else {
VK_CHECK_RESULT(present);
}
VkSemaphore signalSemaphores[] = { vkFoundation.renderCompleteSemaphores[frameIndex] };
VkPresentInfoKHR presentInfo{};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
VkSwapchainKHR swapChains[] = { vkFoundation.swapChain };
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = &imageIndex;
presentInfo.pResults = nullptr;
result = vkQueuePresentKHR(vkFoundation.presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
{
framebufferResized = false;
vkFoundation.recreateSwapChain();
}
else if (result != VK_SUCCESS)
{
throw std::runtime_error("failed to present swap chain image in drawFrame");
}
frameIndex += 1;
frameIndex %= renderAhead;
frameIndex %= PlumageRender::Setter::settings.MaxFrameInFlight;
if (!paused) {
if (!PlumageRender::Setter::settings.pause) {
if (PlumageRender::Setter::settings.rotateModel) {
modelrot.y += frameTimer * 35.0f;
if (modelrot.y > 360.0f) {
modelrot.y -= 360.0f;
}
}
if ((animate) && (models.scene.animations.size() > 0)) {
if ((PlumageRender::Setter::settings.animate) && (models.scene.animations.size() > 0)) {
animationTimer += frameTimer;
if (animationTimer > models.scene.animations[animationIndex].end) {
animationTimer -= models.scene.animations[animationIndex].end;
}
models.scene.updateAnimation(animationIndex, animationTimer);
}
updateShaderData();
vkFoundation.updateShaderData();
if (PlumageRender::Setter::settings.rotateModel) {
updateUniformBuffers();
vkFoundation.updateUniformBuffers();
}
}
if (camera.updated) {
updateUniformBuffers();
vkFoundation.updateUniformBuffers();
}
}
void PlumageRender::renderMain::fileDropped(std::string filename)
void PlumageRender::renderMain::renderLoop(GLFWwindow* window)
{
while (!glfwWindowShouldClose(window))
{
vkDeviceWaitIdle(device);
loadScene(filename);
setupDescriptors();
buildCommandBuffers();
glfwPollEvents();
render();
}
vkDeviceWaitIdle(VulkanBackend::VulkanFoundation::device);
}
@ -233,15 +256,13 @@ PlumageRender* plumageRender;
int main()
{
PlumageRender::renderMain plumageRender;
VulkanBackend::VulkanFoundation vkFoundation;
VulkanBackend::VulkanFoundation vkFoundation;
vkFoundation.initVulkan();
if (!PlumageRender::Setter::settings.headless)
{
plumageRender.initWindow(PlumageRender::Setter::settings.width,PlumageRender::Setter::settings.height);
}
return 0;
}

View File

@ -72,7 +72,13 @@ namespace PlumageRender
uint64_t savedFrameCounter = PlumageRender::Setter::settings.startFrameCount;
bool framebufferResized = false;
uint32_t lastFPS = 0;
static const float frameTimer = 1.0f;
static int32_t animationIndex;
float animationTimer = 0.0f;
renderMain();
~renderMain()
@ -90,9 +96,26 @@ namespace PlumageRender
void prepare();
void setupCamera();
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
void submitToPresentQueue();
virtual void render();
virtual void fileDropped(std::string filename);
void renderLoop(GLFWwindow* window);
private:
PlumageRender::RenderInput renderInput;
PlumageRender::RenderOutput renderOutput;
PBR::Material pbrMaterial;
PlumageRender::PlumageGUI renderGUI;
VulkanBackend::VulkanFoundation vkFoundation;
bool framebufferResized = false;
bool prepared = false;
};

View File

@ -24,14 +24,13 @@ namespace PlumageRender
void loadEnvironment(std::string fileName);
static void loadAssets();
static int32_t animationIndex;
void loadAssets();
private:
float animationTimer = 0.0f;
};

View File

@ -33,12 +33,13 @@ namespace PlumageRender
bool outputPNGimage = false; // 输出图片序列格式为PNG四通道
bool enableSaveToImageSequeue = false; // 图片序列开关(暂时弃用)
bool animate = true; // 动画开关
bool pause = false; // 暂停模型旋转(暂时弃用)
uint32_t MaxFrameInFlight = 2; // 最大并行渲染帧数通常为2此时CPU和GPU并行处理
uint32_t endFrameIndex = 75; // 图片序列结束帧
bool enableIMGUI = false; // gui使用imgui
uint32_t startFrameCount = 1; // 图片序列开始帧
uint32_t videoFrameRate = 25; // 视频帧率
uint32_t selectedPhysicalDeviceIndex = 0;
uint32_t selectedPhysicalDeviceIndex = 0; // 选中的显卡数组形式从0开始编号
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; // 多重采样倍率
};

View File

@ -8,7 +8,7 @@ void PlumageRender::PlumageGUI::updateUIOverlay()
ImVec2 lastDisplaySize = io.DisplaySize;
io.DisplaySize = ImVec2((float)PlumageRender::Setter::settings.width, (float)PlumageRender::Setter::settings.height);
io.DeltaTime = frameTimer;
io.DeltaTime = PlumageRender::renderMain::frameTimer;
io.MousePos = ImVec2(mousePos.x, mousePos.y);
io.MouseDown[0] = mouseButtons.left;
@ -57,12 +57,15 @@ void PlumageRender::PlumageGUI::updateUIOverlay()
vkDeviceWaitIdle(VulkanBackend::VulkanFoundation::device);
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
std::string stringFilename = converter.to_bytes(filename);
PlumageRender::RenderInput::loadScene(stringFilename);
PlumageRender::renderMain::vkFoundation.createDescriptorSets();
renderInput.loadScene(stringFilename);
vkFoundation.createDescriptorSets();
updateCBs = true;
PlumageRender::renderMain::renderOutput.signal.imageSequenceOutputComplete = false;
PlumageRender::renderMain::renderOutput.signal.imageSequenceToVideoComplete = false;
PlumageRender::renderMain::renderOutput.savedFrameCounter = 1;
renderOutput.signal.imageSequenceOutputComplete = false;
renderOutput.signal.imageSequenceToVideoComplete = false;
renderOutput.savedFrameCounter = 1;
}
}
gui->endMenu();
@ -71,24 +74,24 @@ void PlumageRender::PlumageGUI::updateUIOverlay()
{
if (gui->beginMenu(chineseUI.menuEnvironmentConfig))
{
auto& selectedEnvironment = PlumageRender::renderMain::renderInput.selectedEnvironment;
auto& environments = PlumageRender::renderMain::renderInput.environments;
auto& selectedEnvironment = renderInput.selectedEnvironment;
auto& environments = renderInput.environments;
if (gui->combo(chineseUI.environmentMap, selectedEnvironment, environments)) {
vkDeviceWaitIdle(PlumageRender::renderMain::vkFoundation.device);
PlumageRender::renderMain::renderInput.loadEnvironment(environments[selectedEnvironment]);
PlumageRender::renderMain::vkFoundation.createDescriptorSets();
vkDeviceWaitIdle(vkFoundation.device);
renderInput.loadEnvironment(environments[selectedEnvironment]);
vkFoundation.createDescriptorSets();
updateCBs = true;
}
if (gui->checkbox(chineseUI.environmentBackGround, &PlumageRender::Setter::settings.displayBackground)) {
updateShaderParams = true;
}
if (gui->slider("Exposure", &PlumageRender::renderMain::vkFoundation.shaderData.exposure, 0.1f, 10.0f)) {
if (gui->slider("Exposure", &PBR::Material::shaderData.exposure, 0.1f, 10.0f)) {
updateShaderParams = true;
}
if (gui->slider("Gamma", &PlumageRender::renderMain::vkFoundation.shaderData.gamma, 0.1f, 4.0f)) {
if (gui->slider("Gamma", &PBR::Material::shaderData.gamma, 0.1f, 4.0f)) {
updateShaderParams = true;
}
if (gui->slider("IBL", &PlumageRender::renderMain::vkFoundation.shaderData.scaleIBLAmbient, 0.0f, 1.0f)) {
if (gui->slider("IBL", &PBR::Material::shaderData.scaleIBLAmbient, 0.0f, 1.0f)) {
updateShaderParams = true;
}
gui->endMenu();
@ -103,7 +106,7 @@ void PlumageRender::PlumageGUI::updateUIOverlay()
"none", "Base color", "Normal", "Occlusion", "Emissive", "Metallic", "Roughness"
};
if (gui->combo(chineseUI.debugInput, &debugView.debugViewInputs, debugNamesInputs)) {
PlumageRender::renderMain::vkFoundation.shaderData.debugViewInputs = static_cast<float>(debugView.debugViewInputs);
PBR::Material::shaderData.debugViewInputs = static_cast<float>(debugView.debugViewInputs);
updateShaderParams = true;
}
gui->endMenu();
@ -114,7 +117,7 @@ void PlumageRender::PlumageGUI::updateUIOverlay()
"none", "Diff (l,n)", "F (l,h)", "G (l,v,h)", "D (h)", "Specular"
};
if (gui->combo(chineseUI.debugPBREquation, &debugView.debugViewEquation, debugNamesEquation)) {
PlumageRender::renderMain::vkFoundation.shaderData.debugViewEquation = static_cast<float>(debugView.debugViewEquation);
PBR::Material::shaderData.debugViewEquation = static_cast<float>(debugView.debugViewEquation);
updateShaderParams = true;
}
gui->endMenu();
@ -122,7 +125,7 @@ void PlumageRender::PlumageGUI::updateUIOverlay()
if (gui->beginMenu(chineseUI.menuDebugFrameRate))
{
gui->text("%.1d fps (%.2f ms)", lastFPS, (1000.0f / lastFPS));
gui->text("%.1d fps (%.2f ms)", renderMain.lastFPS, (1000.0f / renderMain.lastFPS));
gui->endMenu();
}
gui->endMenu();
@ -142,7 +145,7 @@ void PlumageRender::PlumageGUI::updateUIOverlay()
for (auto animation : PlumageRender::renderMain::models.scene.animations) {
animationNames.push_back(animation.name);
}
gui->combo(chineseUI.animationSeq, &PlumageRender::RenderInput::animationIndex, animationNames);
gui->combo(chineseUI.animationSeq, &renderMain.animationIndex, animationNames);
gui->endMenu();
}
}

View File

@ -9,13 +9,13 @@
#include "render.h"
namespace PlumageRender
{
class PlumageGUI
class PlumageGUI
{
public:
PlumageGUI();
~PlumageGUI();
UI* gui;
UI* gui = new UI(VulkanBackend::VulkanFoundation::vulkanDevice, VulkanBackend::VulkanFoundation::renderPass, VulkanBackend::VulkanFoundation::graphicQueue, VulkanBackend::VulkanFoundation::pipelineCache, PlumageRender::Setter::settings.sampleCount);
void updateUIOverlay();
@ -29,10 +29,12 @@ namespace PlumageRender
private:
PlumageRender::Setter setter;
uint32_t lastFPS = 0;
float frameTimer = 1.0f;
PlumageRender::RenderInput renderInput;
VulkanBackend::VulkanFoundation vkFoundation;
PlumageRender::RenderOutput renderOutput;
PlumageRender::renderMain renderMain;
struct GamePadState {
glm::vec2 axisLeft = glm::vec2(0.0f);

View File

@ -1679,6 +1679,21 @@ void VulkanBackend::VulkanFoundation::allocateCommandBuffers()
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, commandbuffers.data()));
}
void VulkanBackend::VulkanFoundation::cleanupSwapChain()
{
for (auto framebuffer : framebuffers)
{
vkDestroyFramebuffer(device, framebuffer, nullptr);
}
for (auto imageView : swapChainImageViews)
{
vkDestroyImageView(device, imageView, nullptr);
}
vkDestroySwapchainKHR(device, swapChain, nullptr);
}
void VulkanBackend::VulkanFoundation::createCommandBuffer()
{
@ -1883,6 +1898,29 @@ void VulkanBackend::VulkanFoundation::updateShaderData()
0.0f);
}
void VulkanBackend::VulkanFoundation::recreateSwapChain()
{
int width = 0, height = 0;
glfwGetFramebufferSize(window, &width, &height);
while (width == 0 || height == 0)
{
if (glfwWindowShouldClose(window))
{
return;
}
glfwGetFramebufferSize(window, &width, &height);
glfwWaitEvents();
}
vkDeviceWaitIdle(device);
cleanupSwapChain();
createSwapChain();
createImageView();
createFramebuffer();
}

View File

@ -35,8 +35,7 @@ namespace VulkanBackend
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.material, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.node, nullptr);
models.scene.destroy(device);
models.skybox.destroy(device);
for (auto buffer : uniformBuffers) {
buffer.params.destroy();
@ -81,6 +80,32 @@ namespace VulkanBackend
static std::vector<VkImage> swapChainImages;
static VkFormat swapChainImageFormat;
static VkSwapchainKHR swapChain;
static VkRenderPass renderPass;
std::vector<VkFence> waitFences;
std::vector<VkSemaphore> renderCompleteSemaphores;
std::vector<VkSemaphore> presentCompleteSemaphores;
struct UniformBufferSet {
Buffer scene;
Buffer skybox;
Buffer params;
};
struct UBOMatrices {
glm::mat4 projection;
glm::mat4 model;
glm::mat4 view;
glm::vec3 camPos;
} shaderDataScene, shaderDataSkybox;
std::vector<UniformBufferSet> uniformBuffers;
std::vector<VkCommandBuffer> commandbuffers;
VkQueue presentQueue;
void initVulkan();
@ -88,9 +113,17 @@ namespace VulkanBackend
void createDescriptorSets();
void createCommandBuffer();
void updateUniformBuffers();
void updateShaderData();
void recreateSwapChain();
private:
VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger;
@ -125,19 +158,14 @@ namespace VulkanBackend
VkPhysicalDeviceFeatures deviceFeatures;
VkQueue presentQueue;
VkSwapchainKHR swapChain;
VkExtent2D swapChainExtent;
std::vector<VkImageView> swapChainImageViews;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR;
VkRenderPass renderPass;
VkCommandPool commandPool;
@ -148,7 +176,7 @@ namespace VulkanBackend
std::vector<VkFramebuffer> framebuffers;
std::vector<VkCommandBuffer> commandbuffers;
struct FrameBufferAttachment
{
@ -201,30 +229,14 @@ namespace VulkanBackend
VkPipelineLayout pipelineLayout;
struct UniformBufferSet {
Buffer scene;
Buffer skybox;
Buffer params;
};
struct UBOMatrices {
glm::mat4 projection;
glm::mat4 model;
glm::mat4 view;
glm::vec3 camPos;
} shaderDataScene, shaderDataSkybox;
struct LightSource {
glm::vec3 color = glm::vec3(1.0f);
glm::vec3 rotation = glm::vec3(75.0f, 40.0f, 0.0f);
} lightSource;
std::vector<UniformBufferSet> uniformBuffers;
std::vector<VkFence> waitFences;
std::vector<VkSemaphore> renderCompleteSemaphores;
std::vector<VkSemaphore> presentCompleteSemaphores;
// 句柄创建,检查校验层支持和获取需要的扩展
void createInstance();
@ -259,7 +271,8 @@ namespace VulkanBackend
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
void cleanupSwapChain();
// 创建交换链中的imageView用于访问交换链中图像
void createImageView();
@ -289,7 +302,7 @@ namespace VulkanBackend
// 创建统一缓冲区
void createUniformBuffer();
void updateUniformBuffers();
// 创建描述符池
void createDescriptorPool();
@ -310,7 +323,7 @@ namespace VulkanBackend
// 创建栅栏和信号量,用于多帧并行的同步
void createFenceAndSemaphore();
void updateShaderData();
};