/* #include #include #include #include #include #define GLM_FORCE_RADIANS #define GLM_FORCE_DEPTH_ZERO_TO_ONE #include #include #include #ifdef VK_USE_PLATFORM_ANDROID_KHR #define TINYGLTF_ANDROID_LOAD_FROM_ASSETS #endif #define TINYGLTF_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION #define TINYGLTF_NO_STB_IMAGE_WRITE #include "tiny_gltf.h" */ #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 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); };