Revert "Revert "save to revert""

This reverts commit b18564c1f5.
pull/2/head
InkSoul 2023-06-05 21:31:21 +08:00
parent b18564c1f5
commit 8c857eb707
4 changed files with 1293 additions and 1563 deletions

File diff suppressed because it is too large Load Diff

View File

@ -34,35 +34,27 @@
namespace glTFModel namespace glTFModel
{ {
enum DescriptorBindingFlags { struct Node;
ImageBaseColor = 0x00000001,
ImageNormalMap = 0x00000002 struct BoundingBox {
glm::vec3 min;
glm::vec3 max;
bool valid = false;
BoundingBox();
BoundingBox(glm::vec3 min, glm::vec3 max);
BoundingBox getAABB(glm::mat4 m);
}; };
enum FileLoadingFlags { struct TextureSampler {
None = 0x00000000, VkFilter magFilter;
PreTransformVertices = 0x00000001, VkFilter minFilter;
PreMultiplyVertexColors = 0x00000002, VkSamplerAddressMode addressModeU;
FlipY = 0x00000004, VkSamplerAddressMode addressModeV;
DontLoadImages = 0x00000008 VkSamplerAddressMode addressModeW;
}; };
enum RenderFlags {
BindImages = 0x00000001,
RenderOpaqueNodes = 0x00000002,
RenderAlphaMaskedNodes = 0x00000004,
RenderAlphaBlendedNodes = 0x00000008
};
extern VkDescriptorSetLayout descriptorSetLayoutImage;
extern VkDescriptorSetLayout descriptorSetLayoutUbo;
extern VkMemoryPropertyFlags memoryPropertyFlags;
extern uint32_t descriptorBindingFlags;
// A glTF texture stores a reference to the image and a sampler
struct Texture { struct Texture {
int32_t imageIndex; vks::VulkanDevice* device;
vks::VulkanDevice* device = nullptr;
VkImage image; VkImage image;
VkImageLayout imageLayout; VkImageLayout imageLayout;
VkDeviceMemory deviceMemory; VkDeviceMemory deviceMemory;
@ -74,96 +66,85 @@ namespace glTFModel
VkSampler sampler; VkSampler sampler;
void updateDescriptor(); void updateDescriptor();
void destroy(); void destroy();
void fromglTfImage(tinygltf::Image& gltfimage, std::string path, vks::VulkanDevice* device, VkQueue copyQueue); // Load a texture from a glTF image (stored as vector of chars loaded via stb_image) and generate a full mip chaing for it
void fromglTfImage(tinygltf::Image& gltfimage, TextureSampler textureSampler, vks::VulkanDevice* device, VkQueue copyQueue);
}; };
// A glTF material stores information in e.g. the texture that is attached to it and colors
struct Material { struct Material {
vks::VulkanDevice* device = nullptr;
enum AlphaMode { ALPHAMODE_OPAQUE, ALPHAMODE_MASK, ALPHAMODE_BLEND }; enum AlphaMode { ALPHAMODE_OPAQUE, ALPHAMODE_MASK, ALPHAMODE_BLEND };
AlphaMode alphaMode = ALPHAMODE_OPAQUE; AlphaMode alphaMode = ALPHAMODE_OPAQUE;
float alphaCutoff = 1.0f; float alphaCutoff = 1.0f;
float metallicFactor = 1.0f; float metallicFactor = 1.0f;
float roughnessFactor = 1.0f; float roughnessFactor = 1.0f;
glm::vec4 baseColorFactor = glm::vec4(1.0f); glm::vec4 baseColorFactor = glm::vec4(1.0f);
glTFModel::Texture* baseColorTexture = nullptr; glm::vec4 emissiveFactor = glm::vec4(1.0f);
glTFModel::Texture* metallicRoughnessTexture = nullptr; glTFModel::Texture* baseColorTexture;
glTFModel::Texture* normalTexture = nullptr; glTFModel::Texture* metallicRoughnessTexture;
glTFModel::Texture* occlusionTexture = nullptr; glTFModel::Texture* normalTexture;
glTFModel::Texture* emissiveTexture = nullptr; glTFModel::Texture* occlusionTexture;
glTFModel::Texture* emissiveTexture;
glTFModel::Texture* specularGlossinessTexture; bool doubleSided = false;
glTFModel::Texture* diffuseTexture; struct TexCoordSets {
uint8_t baseColor = 0;
uint8_t metallicRoughness = 0;
uint8_t specularGlossiness = 0;
uint8_t normal = 0;
uint8_t occlusion = 0;
uint8_t emissive = 0;
} texCoordSets;
struct Extension {
glTFModel::Texture* specularGlossinessTexture;
glTFModel::Texture* diffuseTexture;
glm::vec4 diffuseFactor = glm::vec4(1.0f);
glm::vec3 specularFactor = glm::vec3(0.0f);
} extension;
struct PbrWorkflows {
bool metallicRoughness = true;
bool specularGlossiness = false;
} pbrWorkflows;
VkDescriptorSet descriptorSet = VK_NULL_HANDLE; VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
Material(vks::VulkanDevice* device) : device(device) {};
void createDescriptorSet(VkDescriptorPool descriptorPool, VkDescriptorSetLayout descriptorSetLayout, uint32_t descriptorBindingFlags);
}; };
// A primitive contains the data for a single draw call
struct Primitive { struct Primitive {
uint32_t firstIndex; uint32_t firstIndex;
uint32_t indexCount; uint32_t indexCount;
uint32_t firstVertex;
uint32_t vertexCount; uint32_t vertexCount;
Material& material; Material& material;
bool hasIndices;
struct Dimensions { BoundingBox bb;
glm::vec3 min = glm::vec3(FLT_MAX); Primitive(uint32_t firstIndex, uint32_t indexCount, uint32_t vertexCount, Material& material);
glm::vec3 max = glm::vec3(-FLT_MAX); void setBoundingBox(glm::vec3 min, glm::vec3 max);
glm::vec3 size;
glm::vec3 center;
float radius;
} dimensions;
void setDimensions(glm::vec3 min, glm::vec3 max);
Primitive(uint32_t firstIndex, uint32_t indexCount, Material& material) : firstIndex(firstIndex), indexCount(indexCount), material(material) {};
}; };
// Contains the node's (optional) geometry and can be made up of an arbitrary number of primitives
struct Mesh { struct Mesh {
vks::VulkanDevice* device; vks::VulkanDevice* device;
std::vector<Primitive*> primitives; std::vector<Primitive*> primitives;
std::string name; BoundingBox bb;
BoundingBox aabb;
struct UniformBuffer { struct UniformBuffer {
VkBuffer buffer; VkBuffer buffer;
VkDeviceMemory memory; VkDeviceMemory memory;
VkDescriptorBufferInfo descriptor; VkDescriptorBufferInfo descriptor;
VkDescriptorSet descriptorSet = VK_NULL_HANDLE; VkDescriptorSet descriptorSet;
void* mapped; void* mapped;
} uniformBuffer; } uniformBuffer;
struct UniformBlock { struct UniformBlock {
glm::mat4 matrix; glm::mat4 matrix;
glm::mat4 jointMatrix[64]{}; glm::mat4 jointMatrix[128]{};
float jointCount{ 0 }; float jointcount{ 0 };
} uniformBlock; } uniformBlock;
Mesh(vks::VulkanDevice* device, glm::mat4 matrix); Mesh(vks::VulkanDevice* device, glm::mat4 matrix);
~Mesh(); ~Mesh();
void setBoundingBox(glm::vec3 min, glm::vec3 max);
}; };
struct Node;
/*
glTF skin
*/
struct Skin { struct Skin {
std::string name; std::string name;
Node* skeletonRoot = nullptr; Node* skeletonRoot = nullptr;
std::vector<glm::mat4> inverseBindMatrices; std::vector<glm::mat4> inverseBindMatrices;
std::vector<Node*> joints; std::vector<Node*> joints;
}; };
// A node represents an object in the glTF scene graph
struct Node { struct Node {
Node* parent; Node* parent;
uint32_t index; uint32_t index;
@ -176,133 +157,102 @@ namespace glTFModel
glm::vec3 translation{}; glm::vec3 translation{};
glm::vec3 scale{ 1.0f }; glm::vec3 scale{ 1.0f };
glm::quat rotation{}; glm::quat rotation{};
BoundingBox bvh;
BoundingBox aabb;
glm::mat4 localMatrix(); glm::mat4 localMatrix();
glm::mat4 getMatrix(); glm::mat4 getMatrix();
void update(); void update();
~Node(); ~Node();
}; };
/* struct AnimationChannel {
glTF default vertex layout with easy Vulkan mapping functions
*/
enum class VertexComponent { Position, Normal, UV, Color, Tangent, Joint0, Weight0 };
// The vertex layout for the samples' model
struct Vertex {
glm::vec3 pos;
glm::vec3 normal;
glm::vec2 uv;
glm::vec4 color;
glm::vec4 joint0;
glm::vec4 weight0;
glm::vec4 tangent;
static VkVertexInputBindingDescription vertexInputBindingDescription;
static std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions;
static VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo;
static VkVertexInputBindingDescription inputBindingDescription(uint32_t binding);
static VkVertexInputAttributeDescription inputAttributeDescription(uint32_t binding, uint32_t location, VertexComponent component);
static std::vector<VkVertexInputAttributeDescription> inputAttributeDescriptions(uint32_t binding, const std::vector<VertexComponent> components);
/** @brief Returns the default pipeline vertex input state create info structure for the requested vertex components */
static VkPipelineVertexInputStateCreateInfo* getPipelineVertexInputState(const std::vector<VertexComponent> components);
};
struct AnimationSampler
{
enum InterpolationType { LINEAR, STEP, CUBICSPLINE };
InterpolationType interpolation;
std::vector<float> inputs;
std::vector<glm::vec4> outputsVec4;
};
struct AnimationChannel
{
enum PathType { TRANSLATION, ROTATION, SCALE }; enum PathType { TRANSLATION, ROTATION, SCALE };
PathType path; PathType path;
Node* node; Node* node;
uint32_t samplerIndex; uint32_t samplerIndex;
}; };
struct Animation struct AnimationSampler {
{ enum InterpolationType { LINEAR, STEP, CUBICSPLINE };
InterpolationType interpolation;
std::vector<float> inputs;
std::vector<glm::vec4> outputsVec4;
};
struct Animation {
std::string name; std::string name;
std::vector<AnimationSampler> samplers; std::vector<AnimationSampler> samplers;
std::vector<AnimationChannel> channels; std::vector<AnimationChannel> channels;
float start = std::numeric_limits<float>::max(); float start = std::numeric_limits<float>::max();
float end = std::numeric_limits<float>::min(); float end = std::numeric_limits<float>::min();
float currentTime = 0.0f;
}; };
/* struct Model {
glTF model loading and rendering class
*/
class Model {
private:
glTFModel::Texture* getTexture(uint32_t index);
glTFModel::Texture emptyTexture;
void createEmptyTexture(VkQueue transferQueue);
public:
vks::VulkanDevice* device; vks::VulkanDevice* device;
VkDescriptorPool descriptorPool;
struct Vertex {
glm::vec3 pos;
glm::vec3 normal;
glm::vec2 uv0;
glm::vec2 uv1;
glm::vec4 joint0;
glm::vec4 weight0;
glm::vec4 color;
};
struct Vertices { struct Vertices {
int count; VkBuffer buffer = VK_NULL_HANDLE;
VkBuffer buffer;
VkDeviceMemory memory; VkDeviceMemory memory;
} vertices; } vertices;
struct Indices { struct Indices {
int count; VkBuffer buffer = VK_NULL_HANDLE;
VkBuffer buffer;
VkDeviceMemory memory; VkDeviceMemory memory;
} indices; } indices;
glm::mat4 aabb;
std::vector<Node*> nodes; std::vector<Node*> nodes;
std::vector<Node*> linearNodes; std::vector<Node*> linearNodes;
std::vector<Skin*> skins; std::vector<Skin*> skins;
std::vector<Texture> textures; std::vector<Texture> textures;
std::vector<TextureSampler> textureSamplers;
std::vector<Material> materials; std::vector<Material> materials;
std::vector<Animation> animations; std::vector<Animation> animations;
std::vector<std::string> extensions;
struct Dimensions { struct Dimensions {
glm::vec3 min = glm::vec3(FLT_MAX); glm::vec3 min = glm::vec3(FLT_MAX);
glm::vec3 max = glm::vec3(-FLT_MAX); glm::vec3 max = glm::vec3(-FLT_MAX);
glm::vec3 size;
glm::vec3 center;
float radius;
} dimensions; } dimensions;
bool metallicRoughnessWorkflow = true; struct LoaderInfo {
bool buffersBound = false; uint32_t* indexBuffer;
std::string path; Vertex* vertexBuffer;
size_t indexPos = 0;
size_t vertexPos = 0;
};
Model() {}; void destroy(VkDevice device);
~Model(); void loadNode(glTFModel::Node* parent, const tinygltf::Node& node, uint32_t nodeIndex, const tinygltf::Model& model, LoaderInfo& loaderInfo, float globalscale);
void loadNode(glTFModel::Node* parent, const tinygltf::Node& node, uint32_t nodeIndex, const tinygltf::Model& model, std::vector<uint32_t>& indexBuffer, std::vector<Vertex>& vertexBuffer, float globalscale); void getNodeProps(const tinygltf::Node& node, const tinygltf::Model& model, size_t& vertexCount, size_t& indexCount);
void loadSkins(tinygltf::Model& gltfModel); void loadSkins(tinygltf::Model& gltfModel);
void loadImages(tinygltf::Model& gltfModel, vks::VulkanDevice* device, VkQueue transferQueue); void loadTextures(tinygltf::Model& gltfModel, vks::VulkanDevice* device, VkQueue transferQueue);
VkSamplerAddressMode getVkWrapMode(int32_t wrapMode);
VkFilter getVkFilterMode(int32_t filterMode);
void loadTextureSamplers(tinygltf::Model& gltfModel);
void loadMaterials(tinygltf::Model& gltfModel); void loadMaterials(tinygltf::Model& gltfModel);
void loadAnimations(tinygltf::Model& gltfModel); void loadAnimations(tinygltf::Model& gltfModel);
void loadFromFile(std::string filename, vks::VulkanDevice* device, VkQueue transferQueue, uint32_t fileLoadingFlags = glTFModel::FileLoadingFlags::None, float scale = 1.0f); void loadFromFile(std::string filename, vks::VulkanDevice* device, VkQueue transferQueue, float scale = 1.0f);
void bindBuffers(VkCommandBuffer commandBuffer); void drawNode(Node* node, VkCommandBuffer commandBuffer);
void drawNode(Node* node, VkCommandBuffer commandBuffer, uint32_t renderFlags = 0, VkPipelineLayout pipelineLayout = VK_NULL_HANDLE, uint32_t bindImageSet = 1); void draw(VkCommandBuffer commandBuffer);
void draw(VkCommandBuffer commandBuffer, uint32_t renderFlags = 0, VkPipelineLayout pipelineLayout = VK_NULL_HANDLE, uint32_t bindImageSet = 1); void calculateBoundingBox(Node* node, Node* parent);
void getNodeDimensions(Node* node, glm::vec3& min, glm::vec3& max);
void getSceneDimensions(); void getSceneDimensions();
void updateAnimation(uint32_t index, float time); void updateAnimation(uint32_t index, float time);
Node* findNode(Node* parent, uint32_t index); Node* findNode(Node* parent, uint32_t index);
Node* nodeFromIndex(uint32_t index); Node* nodeFromIndex(uint32_t index);
void prepareNodeDescriptor(glTFModel::Node* node, VkDescriptorSetLayout descriptorSetLayout);
}; };

View File

@ -49,7 +49,83 @@ PlumageRender::PlumageRender():
}; };
} }
void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode) {
if (node->mesh) {
// Render mesh primitives
for (glTFModel::Primitive* primitive : node->mesh->primitives) {
if (primitive->material.alphaMode == alphaMode) {
VkPipeline pipeline = VK_NULL_HANDLE;
switch (alphaMode) {
case glTFModel::Material::ALPHAMODE_OPAQUE:
case glTFModel::Material::ALPHAMODE_MASK:
pipeline = primitive->material.doubleSided ? pipelines.pbrDoubleSided : pipelines.pbr;
break;
case glTFModel::Material::ALPHAMODE_BLEND:
pipeline = pipelines.pbrAlphaBlend;
break;
}
if (pipeline != boundPipeline) {
vkCmdBindPipeline(commandBuffers[cbIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
boundPipeline = pipeline;
}
const std::vector<VkDescriptorSet> descriptorsets = {
descriptorSets[cbIndex].scene,
primitive->material.descriptorSet,
node->mesh->uniformBuffer.descriptorSet,
};
vkCmdBindDescriptorSets(commandBuffers[cbIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, static_cast<uint32_t>(descriptorsets.size()), descriptorsets.data(), 0, NULL);
// Pass material parameters as push constants
PushConstBlockMaterial pushConstBlockMaterial{};
pushConstBlockMaterial.emissiveFactor = primitive->material.emissiveFactor;
// To save push constant space, availabilty and texture coordiante set are combined
// -1 = texture not used for this material, >= 0 texture used and index of texture coordinate set
pushConstBlockMaterial.colorTextureSet = primitive->material.baseColorTexture != nullptr ? primitive->material.texCoordSets.baseColor : -1;
pushConstBlockMaterial.normalTextureSet = primitive->material.normalTexture != nullptr ? primitive->material.texCoordSets.normal : -1;
pushConstBlockMaterial.occlusionTextureSet = primitive->material.occlusionTexture != nullptr ? primitive->material.texCoordSets.occlusion : -1;
pushConstBlockMaterial.emissiveTextureSet = primitive->material.emissiveTexture != nullptr ? primitive->material.texCoordSets.emissive : -1;
pushConstBlockMaterial.alphaMask = static_cast<float>(primitive->material.alphaMode == vkglTF::Material::ALPHAMODE_MASK);
pushConstBlockMaterial.alphaMaskCutoff = primitive->material.alphaCutoff;
// TODO: glTF specs states that metallic roughness should be preferred, even if specular glosiness is present
if (primitive->material.pbrWorkflows.metallicRoughness) {
// Metallic roughness workflow
pushConstBlockMaterial.workflow = static_cast<float>(PBR_WORKFLOW_METALLIC_ROUGHNESS);
pushConstBlockMaterial.baseColorFactor = primitive->material.baseColorFactor;
pushConstBlockMaterial.metallicFactor = primitive->material.metallicFactor;
pushConstBlockMaterial.roughnessFactor = primitive->material.roughnessFactor;
pushConstBlockMaterial.PhysicalDescriptorTextureSet = primitive->material.metallicRoughnessTexture != nullptr ? primitive->material.texCoordSets.metallicRoughness : -1;
pushConstBlockMaterial.colorTextureSet = primitive->material.baseColorTexture != nullptr ? primitive->material.texCoordSets.baseColor : -1;
}
if (primitive->material.pbrWorkflows.specularGlossiness) {
// Specular glossiness workflow
pushConstBlockMaterial.workflow = static_cast<float>(PBR_WORKFLOW_SPECULAR_GLOSINESS);
pushConstBlockMaterial.PhysicalDescriptorTextureSet = primitive->material.extension.specularGlossinessTexture != nullptr ? primitive->material.texCoordSets.specularGlossiness : -1;
pushConstBlockMaterial.colorTextureSet = primitive->material.extension.diffuseTexture != nullptr ? primitive->material.texCoordSets.baseColor : -1;
pushConstBlockMaterial.diffuseFactor = primitive->material.extension.diffuseFactor;
pushConstBlockMaterial.specularFactor = glm::vec4(primitive->material.extension.specularFactor, 1.0f);
}
vkCmdPushConstants(commandBuffers[cbIndex], pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlockMaterial), &pushConstBlockMaterial);
if (primitive->hasIndices) {
vkCmdDrawIndexed(commandBuffers[cbIndex], primitive->indexCount, 1, primitive->firstIndex, 0, 0);
}
else {
vkCmdDraw(commandBuffers[cbIndex], primitive->vertexCount, 1, 0, 0);
}
}
}
};
for (auto child : node->children) {
renderNode(child, cbIndex, alphaMode);
}
void PlumageRender::buildCommandBuffers() void PlumageRender::buildCommandBuffers()
{ {

View File

@ -1,6 +1,18 @@
#pragma once #pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <vector>
#include <chrono>
#include <map>
#include "algorithm"
#include <vulkan/vulkan.h>
#include "vulkanexamplebase.h" #include "vulkanexamplebase.h"
#include "glTFModel.h" #include "glTFModel.h"
@ -21,7 +33,7 @@ public:
{ {
glTFModel::Model scene; glTFModel::Model scene;
glTFModel::Model skybox; glTFModel::Model skybox;
}; }models;
struct Textures { struct Textures {
vks::TextureCubeMap environmentCube; vks::TextureCubeMap environmentCube;
@ -42,9 +54,9 @@ public:
} shaderData; } shaderData;
struct UniformBufferSet { struct UniformBufferSet {
Buffer scene; vks::Buffer scene;
Buffer skybox; vks::Buffer skybox;
Buffer params; vks::Buffer params;
}; };
struct UBOMatrices { struct UBOMatrices {
@ -91,6 +103,20 @@ public:
} filePath; } filePath;
bool rotateModel = false;
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";
int32_t debugViewInputs = 0;
int32_t debugViewEquation = 0;
struct StagingBuffer { struct StagingBuffer {
VkBuffer buffer; VkBuffer buffer;
VkDeviceMemory memory; VkDeviceMemory memory;
@ -106,6 +132,8 @@ public:
VkPipeline toneMapping = VK_NULL_HANDLE; VkPipeline toneMapping = VK_NULL_HANDLE;
} pipelines; } pipelines;
VkPipeline boundPipeline = VK_NULL_HANDLE;
struct PipelineLayouts struct PipelineLayouts
{ {
VkDescriptorSetLayout scene; VkDescriptorSetLayout scene;
@ -115,23 +143,45 @@ public:
} pipelineLayouts; } pipelineLayouts;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
struct DescriptorSets { struct DescriptorSets {
VkDescriptorSet scene; VkDescriptorSet scene;
VkDescriptorSet skybox; VkDescriptorSet skybox;
VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE; VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE;
}; };
struct DescriptorSetLayouts { struct DescriptorSetLayouts {
VkDescriptorSetLayout scene; VkDescriptorSetLayout scene;
VkDescriptorSetLayout material; VkDescriptorSetLayout material;
VkDescriptorSetLayout node; VkDescriptorSetLayout node;
} descriptorSetLayouts; } 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;
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;
/*
struct OffScreen struct OffScreen
{ {
VkImage image; VkImage image;
@ -139,7 +189,7 @@ public:
VkDeviceMemory memory; VkDeviceMemory memory;
VkFramebuffer framebuffer; VkFramebuffer framebuffer;
} offscreen; } offscreen;
*/
struct IrradiancePushBlock struct IrradiancePushBlock
{ {
glm::mat4 mvp; glm::mat4 mvp;
@ -161,30 +211,42 @@ public:
{ {
// Clean up used Vulkan resources // Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class // Note : Inherited destructor cleans up resources stored in base class
vkDestroyPipeline(device, pipelines.solid, nullptr); vkDestroyPipeline(device, pipelines.skybox, nullptr);
vkDestroyPipeline(device, pipelines.toneMapping, nullptr); vkDestroyPipeline(device, pipelines.pbr, nullptr);
if (pipelines.wireframe != VK_NULL_HANDLE) { vkDestroyPipeline(device, pipelines.pbrAlphaBlend, nullptr);
vkDestroyPipeline(device, pipelines.wireframe, 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);
} }
vkDestroyPipelineLayout(device, pipelineLayouts.pbrLayout, nullptr); textures.environmentCube.destroy();
vkDestroyPipelineLayout(device, pipelineLayouts.tonemappingLayout, nullptr); textures.irradianceCube.destroy();
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.matrices, nullptr); textures.prefilteredCube.destroy();
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.textures, nullptr); textures.lutBrdf.destroy();
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.materialUniform, nullptr); textures.empty.destroy();
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.ssbo, nullptr);
pbrFrameBuffer.color.destroy(device);
pbrFrameBuffer.depth.destroy(device);
pbrFrameBuffer.fbo.destroy(device);
vkDestroySampler(device, colorSampler, nullptr);
shaderData.buffer.destroy();
shaderData.skinSSBO.destroy();
} }
virtual void getEnabledFeatures(); virtual void getEnabledFeatures();
void createAttachment(VkFormat format, VkImageUsageFlagBits usage, FrameBufferAttachment* attachment, uint32_t width, uint32_t height); void renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode);
virtual void setupFrameBuffer(); virtual void setupFrameBuffer();
void buildCommandBuffers(); void buildCommandBuffers();
void loadAssets(); void loadAssets();