plumageRender/src/render/render.h

376 lines
10 KiB
C
Raw Normal View History

#pragma once
2023-05-26 15:20:44 +08:00
#if defined(_WIN32)
#include <io.h>
#include <direct.h>
#else
#include<sys/io.h>
#include<dirent.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <cstdio>
#include <string.h>
#include <assert.h>
#include <vector>
#include <chrono>
#include <map>
#include <locale>
#include <codecvt>
#include "algorithm"
2024-03-26 18:04:18 +08:00
#include <iostream>
#include <sys/stat.h>
#include <filesystem>
#include <vulkan/vulkan.h>
2023-06-06 11:40:59 +08:00
#include "VulkanExampleBase.h"
2023-05-26 15:20:44 +08:00
#include "glTFModel.h"
2023-06-07 10:52:04 +08:00
#include <VulkanTexture.hpp>
#include "VulkanDevice.hpp"
2023-06-07 10:52:04 +08:00
#include "ui.hpp"
#include <VulkanUtils.hpp>
2023-05-26 15:20:44 +08:00
#define ENABLE_VALIDATION false
2023-06-02 09:56:49 +08:00
class PlumageRender : public VulkanExampleBase
2023-05-26 15:20:44 +08:00
{
public:
bool wireframe = false;
bool normalMapping = true;
bool ToneMapping = true;
bool pbrEnabled = true;
2023-06-06 11:40:59 +08:00
struct stat
{
} info ;
struct Signal
{
bool imageSequenceOutputComplete = false;
bool imageSequenceToVideoComplete = false;
}signal;
2023-06-06 11:40:59 +08:00
2023-06-05 16:40:39 +08:00
struct Models
{
glTFModel::Model scene;
glTFModel::Model skybox;
2023-06-05 22:37:31 +08:00
} models;
2023-06-05 16:40:39 +08:00
struct Textures {
vks::TextureCubeMap environmentCube;
vks::Texture2D empty;
vks::Texture2D lutBrdf;
vks::TextureCubeMap irradianceCube;
vks::TextureCubeMap prefilteredCube;
} textures;
2023-05-26 15:20:44 +08:00
struct ShaderData {
2023-06-05 16:40:39 +08:00
glm::vec4 lightDir;
float exposure = 4.5f;
float gamma = 2.2f;
float prefilteredCubeMipLevels;
float scaleIBLAmbient = 1.0f;
float debugViewInputs = 0;
float debugViewEquation = 0;
2023-05-26 15:20:44 +08:00
} shaderData;
struct ChinesesUI
{
const char * model = "模型";
2023-06-19 09:47:00 +08:00
const char* environmentMap = "环境贴图";
2023-06-19 10:09:08 +08:00
const char* environmentBackGround = "启用背景贴图";
const char* debugInput = "输入";
const char* debugPBREquation = "PBR计算参数";
const char* animation = "动画";
const char* pauseAnimation = "启用动画";
const char* animationSeq = "动画序列";
2023-06-19 09:47:00 +08:00
// menu item
const char* menuFile = "文件";
const char* menuOpenNewModel = "新模型..";
const char* menuEnvironment = "环境光照";
const char* menuEnvironmentConfig = "设置";
const char* menuAnimation = "动画";
2023-06-19 10:09:08 +08:00
const char* menuDebugFrameRate = "fps";
2023-06-19 09:47:00 +08:00
const char* menuDebugInput = "输入";
const char* menuAnimationNoAnimation = "当前模型没有动画!";
const char* menuAnimationActivation = "开关";
const char* menuAnimationAnimationSequence = "动画序列";
2023-05-26 15:20:44 +08:00
}chineseUI;
2023-06-05 16:40:39 +08:00
struct UniformBufferSet {
2023-06-06 15:52:39 +08:00
Buffer scene;
Buffer skybox;
Buffer params;
2023-06-05 16:40:39 +08:00
};
struct UBOMatrices {
glm::mat4 projection;
glm::mat4 model;
glm::mat4 view;
glm::vec3 camPos;
2023-06-06 15:52:39 +08:00
} shaderDataScene, shaderDataSkybox;
2023-06-05 16:40:39 +08:00
struct PushConstBlockMaterial {
glm::vec4 baseColorFactor;
glm::vec4 emissiveFactor;
glm::vec4 diffuseFactor;
glm::vec4 specularFactor;
float workflow;
int colorTextureSet;
int PhysicalDescriptorTextureSet;
int normalTextureSet;
int occlusionTextureSet;
int emissiveTextureSet;
float metallicFactor;
float roughnessFactor;
float alphaMask;
float alphaMaskCutoff;
} pushConstBlockMaterial;
2023-06-01 15:32:08 +08:00
struct FilePath
2023-06-06 11:40:59 +08:00
{ //model path
2023-06-08 00:52:02 +08:00
std::string glTFModelFilePath = getAssetPath() + "models/DamagedHelmet/DamagedHelmet.gltf";
2023-06-01 15:32:08 +08:00
std::string modelVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.vert.spv";
std::string modelFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.frag.spv";
2023-06-06 11:40:59 +08:00
2023-06-07 10:52:04 +08:00
//ui
std::string uiVertShaderPath = getAssetPath() + "shaders/ui.vert.spv";
std::string uiFragShaderPath = getAssetPath() + "shaders/ui.frag.spv";
2023-06-06 11:40:59 +08:00
// skybox path
std::string skyboxModleFilePath = getAssetPath() + "models/cube.gltf";
std::string skyboxVertShaderPath = getAssetPath() + "shaders/skybox.vert.spv";
std::string skyboxFragShaderPath = getAssetPath() + "shaders/skybox.frag.spv";
std::string iblTexturesFilePath = getAssetPath() + "textures/hdr/gcanyon_cube.ktx";
2023-06-06 11:40:59 +08:00
//tonemapping
2023-06-01 15:32:08 +08:00
std::string tonemappingVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/genbrdflut.vert.spv";
std::string tonemappingEnableFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/tonemapping_enable.frag.spv";
std::string tonemappingDisableFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/tonemapping_disable.frag.spv";
2023-06-06 11:40:59 +08:00
// cube map
std::string irradianceFragShaderPath = getAssetPath() + "shaders/irradiancecube.frag.spv";
2023-06-07 10:52:04 +08:00
2023-06-06 11:40:59 +08:00
std::string filterVertShaderPath = getAssetPath() + "shaders/filtercube.vert.spv";
2023-06-07 10:52:04 +08:00
2023-06-06 11:40:59 +08:00
std::string prefilterEnvmapFragShaderPath = getAssetPath() + "shaders/prefilterenvmap.frag.spv";
//brdf cube map
2023-06-06 15:52:39 +08:00
std::string brdfVertShaderPath = getAssetPath() + "shaders/genbrdflut.vert.spv";
std::string brdfFragShaderPath = getAssetPath() + "shaders/genbrdflut.frag.spv";
2023-06-06 11:40:59 +08:00
// environment map texture
std::string envMapFilePath = getAssetPath() + "environments/papermill.ktx";
2023-06-07 10:52:04 +08:00
std::string emptyEnvmapFilePath = getAssetPath() + "textures/empty.ktx";
2023-06-06 11:40:59 +08:00
// pbr shader
std::string pbrVertShaderPath = getAssetPath() + "shaders/pbr.vert.spv";
std::string pbrFragShaderPath = getAssetPath() + "shaders/pbr_khr.frag.spv";
2023-06-01 15:32:08 +08:00
2023-06-07 10:52:04 +08:00
//ttf file path
std::string ttfFilePath = getAssetPath() + "/data/Roboto-Medium.ttf";
2024-03-22 18:05:18 +08:00
// output file path
2024-03-25 11:51:10 +08:00
std::string imageOutputPath = getAssetPath() + "output/imageSequence";
std::string videoOutputPath = getAssetPath() + "output/video";
std::string totalImageOutputPath;
std::string deviceSpecFilePath;
// script file path
std::string image2videoBatFilePath = getAssetPath() + "script/image2video.bat";
std::string image2videoShFilePath = getAssetPath() + "script/image2video.sh";
2024-03-22 18:05:18 +08:00
2023-06-01 15:32:08 +08:00
} filePath;
2024-03-22 18:05:18 +08:00
glm::vec3 modelrot = glm::vec3(0.0f);
glm::vec3 modelPos = glm::vec3(0.0f);
2024-03-22 18:05:18 +08:00
enum PBRWorkflows { PBR_WORKFLOW_METALLIC_ROUGHNESS = 0, PBR_WORKFLOW_SPECULAR_GLOSINESS = 1 };
std::map<std::string, std::string> environments;
std::string selectedEnvironment = "papermill";
2023-06-07 13:52:08 +08:00
std::map<std::string, std::string> scenes;
std::string selectedScene = "DamagedHelmet";
int32_t debugViewInputs = 0;
int32_t debugViewEquation = 0;
2023-05-26 15:20:44 +08:00
struct StagingBuffer {
VkBuffer buffer;
VkDeviceMemory memory;
} vertexStaging, indexStaging;
struct Pipelines {
2023-06-05 16:40:39 +08:00
VkPipeline skybox;
VkPipeline pbr;
VkPipeline pbrDoubleSided;
VkPipeline pbrAlphaBlend;
2023-05-26 15:20:44 +08:00
VkPipeline solid;
VkPipeline wireframe = VK_NULL_HANDLE;
VkPipeline toneMapping = VK_NULL_HANDLE;
} pipelines;
VkPipeline boundPipeline = VK_NULL_HANDLE;
2023-05-26 15:20:44 +08:00
struct PipelineLayouts
{
2023-06-05 16:40:39 +08:00
VkDescriptorSetLayout scene;
VkDescriptorSetLayout material;
VkDescriptorSetLayout node;
2023-05-26 15:20:44 +08:00
VkPipelineLayout tonemappingLayout;
} pipelineLayouts;
VkPipelineLayout pipelineLayout;
2023-06-05 16:40:39 +08:00
struct DescriptorSets {
VkDescriptorSet scene;
VkDescriptorSet skybox;
VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE;
2023-05-26 15:20:44 +08:00
};
2023-06-05 16:40:39 +08:00
2024-03-26 15:48:30 +08:00
2023-05-26 15:20:44 +08:00
struct DescriptorSetLayouts {
2023-06-05 16:40:39 +08:00
VkDescriptorSetLayout scene;
VkDescriptorSetLayout material;
VkDescriptorSetLayout node;
2023-05-26 15:20:44 +08:00
} descriptorSetLayouts;
std::vector<DescriptorSets> descriptorSets;
2023-05-26 15:20:44 +08:00
std::vector<VkCommandBuffer> commandBuffers;
std::vector<UniformBufferSet> uniformBuffers;
std::vector<VkFence> waitFences;
std::vector<VkSemaphore> renderCompleteSemaphores;
std::vector<VkSemaphore> presentCompleteSemaphores;
const uint32_t renderAhead = 2;
uint32_t frameIndex = 0;
2024-03-22 18:05:18 +08:00
//VkImage swapChainImage;
int32_t animationIndex = 0;
float animationTimer = 0.0f;
bool animate = true;
bool displayBackground = true;
struct LightSource {
glm::vec3 color = glm::vec3(1.0f);
glm::vec3 rotation = glm::vec3(75.0f, 40.0f, 0.0f);
} lightSource;
2023-06-06 11:40:59 +08:00
//cube map generation
2023-05-26 15:20:44 +08:00
struct OffScreen
{
VkImage image;
VkImageView view;
VkDeviceMemory memory;
VkFramebuffer framebuffer;
} offscreen;
2023-06-06 11:40:59 +08:00
2023-05-26 15:20:44 +08:00
struct IrradiancePushBlock
{
glm::mat4 mvp;
// Sampling deltas
float deltaPhi = (2.0f * float(M_PI)) / 180.0f;
float deltaTheta = (0.5f * float(M_PI)) / 64.0f;
} irradiancePushBlock;
struct PrefilterPushBlock {
glm::mat4 mvp;
float roughness;
uint32_t numSamples = 32u;
} prefilterPushBlock;
2023-06-07 10:52:04 +08:00
UI* gui;
2024-03-26 18:04:18 +08:00
uint64_t savedFrameCounter = settings.startFrameCount;
2023-05-26 15:20:44 +08:00
2023-06-02 09:56:49 +08:00
PlumageRender();
~PlumageRender()
2023-05-26 15:20:44 +08:00
{
// 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);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.scene, nullptr);
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();
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);
2023-05-26 15:20:44 +08:00
}
textures.environmentCube.destroy();
textures.irradianceCube.destroy();
textures.prefilteredCube.destroy();
textures.lutBrdf.destroy();
textures.empty.destroy();
2023-06-07 11:29:44 +08:00
delete gui;
2023-05-26 15:20:44 +08:00
}
2023-06-05 10:38:28 +08:00
void renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode);
2023-06-05 22:37:31 +08:00
void loadScene(std::string filename);
void loadEnvironment(std::string filename);
2023-05-26 15:20:44 +08:00
void buildCommandBuffers();
void loadAssets();
2023-06-06 11:40:59 +08:00
void setupNodeDescriptorSet(glTFModel::Node* node);
void setupDescriptors();
2023-05-26 15:20:44 +08:00
void preparePipelines();
2023-06-08 00:52:02 +08:00
// void tonemappingPipelin();
2023-06-06 11:40:59 +08:00
void generateCubemaps();
2023-06-06 15:52:39 +08:00
void generateBRDFLUT();
2023-05-26 15:20:44 +08:00
void prepareUniformBuffers();
void updateUniformBuffers();
2023-06-06 15:52:39 +08:00
void updateShaderData();
void windowResized();
2023-05-26 15:20:44 +08:00
void prepare();
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
2024-03-25 11:51:10 +08:00
void writeImageToFile(std::string filePath);
void outputImageSequence();
void imageSequenceToVideo();
void removeImageSequence();
//void outputScreenShot();
2024-03-22 18:05:18 +08:00
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
2023-05-26 15:20:44 +08:00
virtual void render();
virtual void updateUIOverlay();
virtual void fileDropped(std::string filename);
2023-05-26 15:20:44 +08:00
};