Files
2025-09-04 10:54:47 +08:00

149 lines
4.8 KiB
C++

/* Copyright (c) 2018-2025, Arm Limited and Contributors
* Copyright (c) 2019-2025, Sascha Willems
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "common/vk_common.h"
#include <memory>
#include <mutex>
#define TINYGLTF_NO_STB_IMAGE
#define TINYGLTF_NO_STB_IMAGE_WRITE
#define TINYGLTF_NO_EXTERNAL_IMAGE
#include <tiny_gltf.h>
#include "timer.h"
#include "vulkan/vulkan.h"
#define KHR_LIGHTS_PUNCTUAL_EXTENSION "KHR_lights_punctual"
namespace vkb
{
namespace core
{
template <vkb::BindingType bindingType>
class Device;
using DeviceCpp = Device<vkb::BindingType::Cpp>;
using DeviceC = Device<vkb::BindingType::C>;
} // namespace core
namespace sg
{
class Camera;
class Image;
class Light;
class Mesh;
class Node;
class PBRMaterial;
class Sampler;
class Scene;
class SubMesh;
class Texture;
} // namespace sg
/**
* @brief Helper Function to change array type T to array type Y
* Create a struct that can be used with std::transform so that we do not need to recreate lambda functions
* @param T
* @param Y
*/
template <class T, class Y>
struct TypeCast
{
Y operator()(T value) const noexcept
{
return static_cast<Y>(value);
}
};
/// Read a gltf file and return a scene object. Converts the gltf objects
/// to our internal scene implementation. Mesh data is copied to vulkan buffers and
/// images are loaded from the folder of gltf file to vulkan images.
class GLTFLoader
{
public:
GLTFLoader(vkb::core::DeviceC &device);
virtual ~GLTFLoader() = default;
std::unique_ptr<sg::Scene> read_scene_from_file(const std::string &file_name, int scene_index = -1, VkBufferUsageFlags additional_buffer_usage_flags = 0);
/**
* @brief Loads the first model from a GLTF file for use in simpler samples
* makes use of the Vertex struct in vulkan_example_base.h
*/
std::unique_ptr<sg::SubMesh> read_model_from_file(const std::string &file_name, uint32_t index, bool storage_buffer = false, VkBufferUsageFlags additional_buffer_usage_flags = 0);
protected:
virtual std::unique_ptr<sg::Node> parse_node(const tinygltf::Node &gltf_node, size_t index) const;
virtual std::unique_ptr<sg::Camera> parse_camera(const tinygltf::Camera &gltf_camera) const;
virtual std::unique_ptr<sg::Mesh> parse_mesh(const tinygltf::Mesh &gltf_mesh) const;
virtual std::unique_ptr<sg::PBRMaterial> parse_material(const tinygltf::Material &gltf_material) const;
virtual std::unique_ptr<sg::Image> parse_image(tinygltf::Image &gltf_image) const;
virtual std::unique_ptr<sg::Sampler> parse_sampler(const tinygltf::Sampler &gltf_sampler) const;
virtual std::unique_ptr<sg::Texture> parse_texture(const tinygltf::Texture &gltf_texture) const;
virtual std::unique_ptr<sg::PBRMaterial> create_default_material();
virtual std::unique_ptr<sg::Sampler> create_default_sampler(int filter);
virtual std::unique_ptr<sg::Camera> create_default_camera();
/**
* @brief Parses and returns a list of scene graph lights from the KHR_lights_punctual extension
*/
std::vector<std::unique_ptr<sg::Light>> parse_khr_lights_punctual();
/**
* @brief Checks if the GLTFLoader supports an extension, and that it is present in the glTF file
* @param requested_extension The extension to check
* @returns True if the loader knows how to load the extension and it is present in the glTF file, false if not
*/
bool is_extension_enabled(const std::string &requested_extension);
/**
* @brief Finds whether an extension exists inside a tinygltf extension map and returns the result
* @param tinygltf_extensions The extension map associated with a given tinygltf object
* @param extension The extension to check
* @returns A pointer to the value of the extension object, nullptr if it isn't found
*/
tinygltf::Value *get_extension(tinygltf::ExtensionMap &tinygltf_extensions, const std::string &extension);
vkb::core::DeviceC &device;
tinygltf::Model model;
std::string model_path;
/// The extensions that the GLTFLoader can load mapped to whether they should be enabled or not
static std::unordered_map<std::string, bool> supported_extensions;
private:
sg::Scene load_scene(int scene_index = -1, VkBufferUsageFlags additional_buffer_usage_flags = 0);
std::unique_ptr<sg::SubMesh> load_model(uint32_t index, bool storage_buffer = false, VkBufferUsageFlags additional_buffer_usage_flags = 0);
};
} // namespace vkb