reconstructed header file
parent
3ae611763e
commit
4a5cd74dc3
|
@ -148,6 +148,6 @@ ENDIF(WIN32)
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/")
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/")
|
||||||
|
|
||||||
add_subdirectory(base)
|
add_subdirectory(base)
|
||||||
add_subdirectory(homework)
|
add_subdirectory(src)
|
||||||
|
|
||||||
# add_subdirectory(examples)
|
# add_subdirectory(examples)
|
||||||
|
|
|
@ -30,7 +30,7 @@ function(buildHomework HOMEWORK_NAME)
|
||||||
# Add optional readme / tutorial
|
# Add optional readme / tutorial
|
||||||
file(GLOB README_FILES "${HOMEWORK_FOLDER}/*.md")
|
file(GLOB README_FILES "${HOMEWORK_FOLDER}/*.md")
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_executable(${HOMEWORK_NAME} WIN32 ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES})
|
add_executable(${HOMEWORK_NAME} WIN32 ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES} "render/glTFModel.h")
|
||||||
target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY} ${WINLIBS})
|
target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY} ${WINLIBS})
|
||||||
else(WIN32)
|
else(WIN32)
|
||||||
add_executable(${HOMEWORK_NAME} ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES})
|
add_executable(${HOMEWORK_NAME} ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES})
|
|
@ -1,4 +1,4 @@
|
||||||
|
#pragma once
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
#define TINYGLTF_NO_STB_IMAGE_WRITE
|
#define TINYGLTF_NO_STB_IMAGE_WRITE
|
||||||
|
|
||||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||||
#define TINYGLTF_ANDROID_LOAD_FROM_ASSETS
|
#define TINYGLTF_ANDROID_LOAD_FROM_ASSETS
|
||||||
#endif
|
#endif
|
||||||
#include "tiny_gltf.h"
|
#include "tiny_gltf.h"
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//VulkanglTFModel();
|
//VulkanglTFModel();
|
||||||
~VulkanglTFModel()
|
~VulkanglTFModel()
|
||||||
{
|
{
|
||||||
for (auto node : nodes) {
|
for (auto node : nodes) {
|
||||||
|
@ -226,179 +226,3 @@ public:
|
||||||
void drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFModel::Node* node, bool bPushConstants);
|
void drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFModel::Node* node, bool bPushConstants);
|
||||||
void draw(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, bool flag);
|
void draw(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, bool flag);
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
|
@ -5,7 +5,6 @@
|
||||||
*
|
*
|
||||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shows how to load and display a simple scene from a glTF file
|
* Shows how to load and display a simple scene from a glTF file
|
||||||
* Note that this isn't a complete glTF loader and only basic functions are shown here
|
* Note that this isn't a complete glTF loader and only basic functions are shown here
|
||||||
|
@ -17,7 +16,7 @@
|
||||||
* If you are looking for a complete glTF implementation, check out https://github.com/SaschaWillems/Vulkan-glTF-PBR/
|
* If you are looking for a complete glTF implementation, check out https://github.com/SaschaWillems/Vulkan-glTF-PBR/
|
||||||
*/
|
*/
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
#include "glTFModel.h"
|
||||||
/*
|
/*
|
||||||
glTF loading functions
|
glTF loading functions
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
/*
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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);
|
||||||
|
};
|
Loading…
Reference in New Issue