plumageRender/src/render/render.h

327 lines
7.8 KiB
C++

#pragma once
#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"
#include <iostream>
#include <sys/stat.h>
#include <filesystem>
#include <vulkan/vulkan.h>
#include "VulkanExampleBase.h"
#include "glTFModel.h"
#include <VulkanTexture.hpp>
#include "VulkanDevice.hpp"
#include "ui.hpp"
#include <VulkanUtils.hpp>
#include "renderSetter.h"
#include "GLFW/glfw3.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#define ENABLE_VALIDATION false
class PlumageRender : public VulkanExampleBase
{
public:
GLFWwindow* window;
VulkanBackend::Setter setter;
bool wireframe = false;
bool normalMapping = true;
bool ToneMapping = true;
bool pbrEnabled = true;
struct stat
{
} info ;
struct Signal
{
bool imageSequenceOutputComplete = false;
bool imageSequenceToVideoComplete = false;
}signal;
struct Models
{
glTFModel::Model scene;
glTFModel::Model skybox;
} models;
struct Textures {
vks::TextureCubeMap environmentCube;
vks::Texture2D empty;
vks::Texture2D lutBrdf;
vks::TextureCubeMap irradianceCube;
vks::TextureCubeMap prefilteredCube;
} textures;
struct ShaderData {
glm::vec4 lightDir;
float exposure = 4.5f;
float gamma = 2.2f;
float prefilteredCubeMipLevels;
float scaleIBLAmbient = 1.0f;
float debugViewInputs = 0;
float debugViewEquation = 0;
} shaderData;
struct ChinesesUI
{
const char * model = "模型";
const char* environmentMap = "环境贴图";
const char* environmentBackGround = "启用背景贴图";
const char* debugInput = "输入";
const char* debugPBREquation = "PBR计算参数";
const char* animation = "动画";
const char* pauseAnimation = "启用动画";
const char* animationSeq = "动画序列";
// menu item
const char* menuFile = "文件";
const char* menuOpenNewModel = "新模型..";
const char* menuEnvironment = "环境光照";
const char* menuEnvironmentConfig = "设置";
const char* menuAnimation = "动画";
const char* menuDebugFrameRate = "fps";
const char* menuDebugInput = "输入";
const char* menuAnimationNoAnimation = "当前模型没有动画!";
const char* menuAnimationActivation = "开关";
const char* menuAnimationAnimationSequence = "动画序列";
}chineseUI;
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 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;
glm::vec3 modelrot = glm::vec3(0.0f);
glm::vec3 modelPos = glm::vec3(0.0f);
enum PBRWorkflows { PBR_WORKFLOW_METALLIC_ROUGHNESS = 0, PBR_WORKFLOW_SPECULAR_GLOSINESS = 1 };
std::map<std::string, std::string> environments;
std::string selectedEnvironment = "papermill";
std::map<std::string, std::string> scenes;
std::string selectedScene = "DamagedHelmet";
int32_t debugViewInputs = 0;
int32_t debugViewEquation = 0;
struct StagingBuffer {
VkBuffer buffer;
VkDeviceMemory memory;
} vertexStaging, indexStaging;
struct Pipelines {
VkPipeline skybox;
VkPipeline pbr;
VkPipeline pbrDoubleSided;
VkPipeline pbrAlphaBlend;
VkPipeline solid;
VkPipeline wireframe = VK_NULL_HANDLE;
VkPipeline toneMapping = VK_NULL_HANDLE;
} pipelines;
VkPipeline boundPipeline = VK_NULL_HANDLE;
struct PipelineLayouts
{
VkDescriptorSetLayout scene;
VkDescriptorSetLayout material;
VkDescriptorSetLayout node;
VkPipelineLayout tonemappingLayout;
} pipelineLayouts;
VkPipelineLayout pipelineLayout;
struct DescriptorSets {
VkDescriptorSet scene;
VkDescriptorSet skybox;
VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE;
};
struct DescriptorSetLayouts {
VkDescriptorSetLayout scene;
VkDescriptorSetLayout material;
VkDescriptorSetLayout node;
} descriptorSetLayouts;
std::vector<DescriptorSets> descriptorSets;
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;
//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;
//cube map generation
struct OffScreen
{
VkImage image;
VkImageView view;
VkDeviceMemory memory;
VkFramebuffer framebuffer;
} offscreen;
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;
UI* gui;
uint64_t savedFrameCounter = setter.settings.startFrameCount;
bool framebufferResized = false;
PlumageRender();
~PlumageRender()
{
// 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);
}
textures.environmentCube.destroy();
textures.irradianceCube.destroy();
textures.prefilteredCube.destroy();
textures.lutBrdf.destroy();
textures.empty.destroy();
delete gui;
}
void initWindow(int width, int height);
static void framebufferResizeCallback(GLFWwindow* window, int width, int height);
void renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode);
void loadScene(std::string filename);
void loadEnvironment(std::string filename);
void buildCommandBuffers();
void loadAssets();
void setupNodeDescriptorSet(glTFModel::Node* node);
void setupDescriptors();
void preparePipelines();
// void tonemappingPipelin();
void generateCubemaps();
void generateBRDFLUT();
void prepareUniformBuffers();
void updateUniformBuffers();
void updateShaderData();
void windowResized();
void prepare();
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
void writeImageToFile(std::string filePath);
void outputImageSequence();
void imageSequenceToVideo();
void removeImageSequence();
//void outputScreenShot();
//uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
virtual void render();
virtual void updateUIOverlay();
virtual void fileDropped(std::string filename);
};