#pragma once #include "vulkanexamplebase.h" #include "glTFModel.h" #define ENABLE_VALIDATION false class VulkanExample : public VulkanExampleBase { public: bool wireframe = false; bool normalMapping = true; bool ToneMapping = true; bool pbrEnabled = true; VulkanglTFModel glTFModel; struct ShaderData { vks::Buffer buffer; struct Values { glm::mat4 projection; glm::mat4 model; glm::vec4 lightPos = glm::vec4(5.0f, 5.0f, 5.0f, 1.0f); glm::vec4 viewPos; glm::vec4 bFlagSet = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f); } values; vks::Buffer skinSSBO; } shaderData; struct FilePath { std::string glTFModelFilePath = getAssetPath() + "buster_drone/busterDrone.gltf"; std::string skyboxModleFilePath = getAssetPath() + "models/cube.gltf"; std::string iblTexturesFilePath = getAssetPath() + "textures/hdr/pisa_cube.ktx"; std::string modelVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.vert.spv"; std::string modelFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.frag.spv"; 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"; std::string irradianceVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/filtercube.vert.spv"; std::string irradianceFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/irradiancecube.frag.spv"; std::string prefilterVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/filtercube.vert.spv"; std::string prefilterFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/prefilterenvmap.frag.spv"; std::string brdfVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/genbrdflut.vert.spv"; std::string brdfFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/genbrdflut.frag.spv"; } filePath; struct StagingBuffer { VkBuffer buffer; VkDeviceMemory memory; } vertexStaging, indexStaging; struct Pipelines { VkPipeline solid; VkPipeline wireframe = VK_NULL_HANDLE; VkPipeline toneMapping = VK_NULL_HANDLE; } pipelines; struct PipelineLayouts { VkPipelineLayout pbrLayout; VkPipelineLayout tonemappingLayout; } pipelineLayouts; VkPipelineLayout pipelineLayout; VkDescriptorSet descriptorSet; VkDescriptorSet skinDescriptorSet; VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE; struct FrameBufferAttachment { VkImage image; VkDeviceMemory deviceMemory; VkImageView imageView; VkFormat format; void destroy(VkDevice device) { vkDestroyImage(device, image, nullptr); vkDestroyImageView(device, imageView,nullptr); vkFreeMemory(device, deviceMemory, nullptr); } }; struct FrameBuffer { int32_t width, height; VkFramebuffer frameBuffer; VkRenderPass renderPass; void setSize(int32_t w, int32_t h) { this->width = w; this->height = h; } void destroy(VkDevice device) { vkDestroyFramebuffer(device, frameBuffer, nullptr); vkDestroyRenderPass(device, renderPass, nullptr); } }; struct PBRFrameBuffer { FrameBufferAttachment color, depth; FrameBuffer fbo; bool bCreate = false; } pbrFrameBuffer; VkSampler colorSampler; struct DescriptorSetLayouts { VkDescriptorSetLayout matrices; VkDescriptorSetLayout textures; VkDescriptorSetLayout materialUniform; VkDescriptorSetLayout ssbo; VkDescriptorSetLayout jointMatrices; } descriptorSetLayouts; struct IBLTextures { vks::TextureCubeMap skyboxCube; vks::TextureCubeMap irradianceCube; vks::TextureCubeMap prefilteredCube; vks::Texture2D lutBrdf; } ibltextures; 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; VulkanglTFModel skyboxModel; VulkanExample(); ~VulkanExample() { // Clean up used Vulkan resources // Note : Inherited destructor cleans up resources stored in base class vkDestroyPipeline(device, pipelines.solid, nullptr); vkDestroyPipeline(device, pipelines.toneMapping, nullptr); if (pipelines.wireframe != VK_NULL_HANDLE) { vkDestroyPipeline(device, pipelines.wireframe, nullptr); } vkDestroyPipelineLayout(device, pipelineLayouts.pbrLayout, nullptr); vkDestroyPipelineLayout(device, pipelineLayouts.tonemappingLayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.matrices, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.textures, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.materialUniform, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.ssbo, nullptr); ibltextures.irradianceCube.destroy(); ibltextures.skyboxCube.destroy(); ibltextures.prefilteredCube.destroy(); ibltextures.lutBrdf.destroy(); pbrFrameBuffer.color.destroy(device); pbrFrameBuffer.depth.destroy(device); pbrFrameBuffer.fbo.destroy(device); vkDestroySampler(device, colorSampler, nullptr); shaderData.buffer.destroy(); shaderData.skinSSBO.destroy(); } void loadglTFFile(std::string filename, VulkanglTFModel& model, bool bSkyboxFlag); virtual void getEnabledFeatures(); void createAttachment(VkFormat format, VkImageUsageFlagBits usage, FrameBufferAttachment* attachment, uint32_t width, uint32_t height); virtual void setupFrameBuffer(); void buildCommandBuffers(); void loadAssets(); void setupDescriptors(); void preparePipelines(); void CreateToneMappingPipeline(); void GenerateIrradianceCubemap(); void GeneratePrefilteredCubemap(); void GenerateBRDFLUT(); void prepareUniformBuffers(); void updateUniformBuffers(); void prepare(); virtual void render(); virtual void viewChanged(); virtual void OnUpdateUIOverlay(vks::UIOverlay* overlay); };