加入volk 和 wma 后 编译不通过, 先保存代码
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/* Copyright (c) 2018-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "aabb.h"
|
||||
|
||||
#include "core/util/logging.hpp"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
AABB::AABB()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
AABB::AABB(const glm::vec3 &min, const glm::vec3 &max) :
|
||||
min{min},
|
||||
max{max}
|
||||
{
|
||||
}
|
||||
|
||||
std::type_index AABB::get_type()
|
||||
{
|
||||
return typeid(AABB);
|
||||
}
|
||||
|
||||
void AABB::update(const glm::vec3 &point)
|
||||
{
|
||||
min = glm::min(min, point);
|
||||
max = glm::max(max, point);
|
||||
}
|
||||
|
||||
void AABB::update(const std::vector<glm::vec3> &vertex_data, const std::vector<uint16_t> &index_data)
|
||||
{
|
||||
// Check if submesh is indexed
|
||||
if (index_data.size() > 0)
|
||||
{
|
||||
// Update bounding box for each indexed vertex
|
||||
for (size_t index_id = 0; index_id < index_data.size(); index_id++)
|
||||
{
|
||||
update(vertex_data[index_data[index_id]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update bounding box for each vertex
|
||||
for (size_t vertex_id = 0; vertex_id < vertex_data.size(); vertex_id++)
|
||||
{
|
||||
update(vertex_data[vertex_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AABB::transform(glm::mat4 &transform)
|
||||
{
|
||||
min = max = glm::vec4(min, 1.0f) * transform;
|
||||
|
||||
// Update bounding box for the remaining 7 corners of the box
|
||||
update(glm::vec4(min.x, min.y, max.z, 1.0f) * transform);
|
||||
update(glm::vec4(min.x, max.y, min.z, 1.0f) * transform);
|
||||
update(glm::vec4(min.x, max.y, max.z, 1.0f) * transform);
|
||||
update(glm::vec4(max.x, min.y, min.z, 1.0f) * transform);
|
||||
update(glm::vec4(max.x, min.y, max.z, 1.0f) * transform);
|
||||
update(glm::vec4(max.x, max.y, min.z, 1.0f) * transform);
|
||||
update(glm::vec4(max, 1.0f) * transform);
|
||||
}
|
||||
|
||||
glm::vec3 AABB::get_scale() const
|
||||
{
|
||||
return (max - min);
|
||||
}
|
||||
|
||||
glm::vec3 AABB::get_center() const
|
||||
{
|
||||
return (min + max) * 0.5f;
|
||||
}
|
||||
|
||||
glm::vec3 AABB::get_min() const
|
||||
{
|
||||
return min;
|
||||
}
|
||||
|
||||
glm::vec3 AABB::get_max() const
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
void AABB::reset()
|
||||
{
|
||||
min = std::numeric_limits<glm::vec3>::max();
|
||||
|
||||
max = std::numeric_limits<glm::vec3>::min();
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,104 @@
|
||||
/* Copyright (c) 2018-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
|
||||
#include "scene_graph/component.h"
|
||||
#include "scene_graph/components/sub_mesh.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
/**
|
||||
* @brief Axis Aligned Bounding Box
|
||||
*/
|
||||
class AABB : public Component
|
||||
{
|
||||
public:
|
||||
AABB();
|
||||
|
||||
AABB(const glm::vec3 &min, const glm::vec3 &max);
|
||||
|
||||
virtual ~AABB() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
/**
|
||||
* @brief Update the bounding box based on the given vertex position
|
||||
* @param point The 3D position of a point
|
||||
*/
|
||||
void update(const glm::vec3 &point);
|
||||
|
||||
/**
|
||||
* @brief Update the bounding box based on the given submesh vertices
|
||||
* @param vertex_data The position vertex data
|
||||
* @param index_data The index vertex data
|
||||
*/
|
||||
void update(const std::vector<glm::vec3> &vertex_data, const std::vector<uint16_t> &index_data);
|
||||
|
||||
/**
|
||||
* @brief Apply a given matrix transformation to the bounding box
|
||||
* @param transform The matrix transform to apply
|
||||
*/
|
||||
void transform(glm::mat4 &transform);
|
||||
|
||||
/**
|
||||
* @brief Scale vector of the bounding box
|
||||
* @return vector in 3D space
|
||||
*/
|
||||
glm::vec3 get_scale() const;
|
||||
|
||||
/**
|
||||
* @brief Center position of the bounding box
|
||||
* @return vector in 3D space
|
||||
*/
|
||||
glm::vec3 get_center() const;
|
||||
|
||||
/**
|
||||
* @brief Minimum position of the bounding box
|
||||
* @return vector in 3D space
|
||||
*/
|
||||
glm::vec3 get_min() const;
|
||||
|
||||
/**
|
||||
* @brief Maximum position of the bounding box
|
||||
* @return vector in 3D space
|
||||
*/
|
||||
glm::vec3 get_max() const;
|
||||
|
||||
/**
|
||||
* @brief Resets the min and max position coordinates
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
glm::vec3 min;
|
||||
|
||||
glm::vec3 max;
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,67 @@
|
||||
/* Copyright (c) 2019-2020, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
#include "scene_graph/components/transform.h"
|
||||
#include "scene_graph/node.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
Camera::Camera(const std::string &name) :
|
||||
Component{name}
|
||||
{}
|
||||
|
||||
std::type_index Camera::get_type()
|
||||
{
|
||||
return typeid(Camera);
|
||||
}
|
||||
|
||||
glm::mat4 Camera::get_view()
|
||||
{
|
||||
if (!node)
|
||||
{
|
||||
throw std::runtime_error{"Camera component is not attached to a node"};
|
||||
}
|
||||
|
||||
auto &transform = node->get_component<Transform>();
|
||||
return glm::inverse(transform.get_world_matrix());
|
||||
}
|
||||
|
||||
void Camera::set_node(Node &n)
|
||||
{
|
||||
node = &n;
|
||||
}
|
||||
|
||||
Node *Camera::get_node()
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
const glm::mat4 Camera::get_pre_rotation()
|
||||
{
|
||||
return pre_rotation;
|
||||
}
|
||||
|
||||
void Camera::set_pre_rotation(const glm::mat4 &pr)
|
||||
{
|
||||
pre_rotation = pr;
|
||||
}
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Copyright (c) 2019-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
|
||||
#include "common/helpers.h"
|
||||
#include "scene_graph/component.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class Camera : public Component
|
||||
{
|
||||
public:
|
||||
Camera(const std::string &name);
|
||||
|
||||
virtual ~Camera() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
virtual glm::mat4 get_projection() = 0;
|
||||
|
||||
glm::mat4 get_view();
|
||||
|
||||
void set_node(Node &node);
|
||||
|
||||
Node *get_node();
|
||||
|
||||
const glm::mat4 get_pre_rotation();
|
||||
|
||||
void set_pre_rotation(const glm::mat4 &pre_rotation);
|
||||
|
||||
private:
|
||||
Node *node{nullptr};
|
||||
|
||||
glm::mat4 pre_rotation{1.0f};
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,379 @@
|
||||
/* Copyright (c) 2023-2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hpp_image.h"
|
||||
|
||||
#include "common/hpp_utils.h"
|
||||
#include "filesystem/legacy.h"
|
||||
#include "scene_graph/components/image/astc.h"
|
||||
#include "scene_graph/components/image/ktx.h"
|
||||
#include "scene_graph/components/image/stb.h"
|
||||
#include <stb_image_resize.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vulkan/vulkan_format_traits.hpp>
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace scene_graph
|
||||
{
|
||||
namespace components
|
||||
{
|
||||
bool is_astc(const vk::Format format)
|
||||
{
|
||||
return strncmp(vk::compressionScheme(format), "ASTC", 4) == 0;
|
||||
}
|
||||
|
||||
HPPImage::HPPImage(const std::string &name, std::vector<uint8_t> &&d, std::vector<vkb::scene_graph::components::HPPMipmap> &&m) :
|
||||
Component{name},
|
||||
data{std::move(d)},
|
||||
format{vk::Format::eR8G8B8A8Unorm},
|
||||
mipmaps{std::move(m)}
|
||||
{
|
||||
update_hash();
|
||||
}
|
||||
|
||||
std::unique_ptr<vkb::scene_graph::components::HPPImage> HPPImage::load(const std::string &name, const std::string &uri,
|
||||
ContentType content_type)
|
||||
{
|
||||
std::unique_ptr<vkb::scene_graph::components::HPPImage> image{nullptr};
|
||||
|
||||
auto data = fs::read_asset(uri);
|
||||
|
||||
// Get extension
|
||||
auto extension = get_extension(uri);
|
||||
|
||||
// the derived classes Stb, Astc, and Ktx are not transcoded (yet), so we need some more complex casting here...
|
||||
if (extension == "png" || extension == "jpg")
|
||||
{
|
||||
image = std::unique_ptr<vkb::scene_graph::components::HPPImage>(reinterpret_cast<vkb::scene_graph::components::HPPImage *>(
|
||||
std::make_unique<vkb::sg::Stb>(name, data, static_cast<vkb::sg::Image::ContentType>(content_type)).release()));
|
||||
}
|
||||
else if (extension == "astc")
|
||||
{
|
||||
image = std::unique_ptr<vkb::scene_graph::components::HPPImage>(
|
||||
reinterpret_cast<vkb::scene_graph::components::HPPImage *>(std::make_unique<vkb::sg::Astc>(name, data).release()));
|
||||
}
|
||||
else if ((extension == "ktx") || (extension == "ktx2"))
|
||||
{
|
||||
image = std::unique_ptr<vkb::scene_graph::components::HPPImage>(reinterpret_cast<vkb::scene_graph::components::HPPImage *>(
|
||||
std::make_unique<vkb::sg::Ktx>(name, data, static_cast<vkb::sg::Image::ContentType>(content_type)).release()));
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
std::type_index HPPImage::get_type()
|
||||
{
|
||||
return typeid(HPPImage);
|
||||
}
|
||||
|
||||
void HPPImage::clear_data()
|
||||
{
|
||||
data.clear();
|
||||
data.shrink_to_fit();
|
||||
}
|
||||
|
||||
void HPPImage::coerce_format_to_srgb()
|
||||
{
|
||||
// When the color-space of a loaded image is unknown (from KTX1 for example) we
|
||||
// may want to assume that the loaded data is in sRGB format (since it usually is).
|
||||
// In those cases, this helper will get called which will force an existing unorm
|
||||
// format to become an srgb format where one exists. If none exist, the format will
|
||||
// remain unmodified.
|
||||
switch (format)
|
||||
{
|
||||
case vk::Format::eR8Unorm:
|
||||
format = vk::Format::eR8Srgb;
|
||||
break;
|
||||
case vk::Format::eR8G8Unorm:
|
||||
format = vk::Format::eR8G8Srgb;
|
||||
break;
|
||||
case vk::Format::eR8G8B8Unorm:
|
||||
format = vk::Format::eR8G8B8Srgb;
|
||||
break;
|
||||
case vk::Format::eB8G8R8Unorm:
|
||||
format = vk::Format::eB8G8R8Srgb;
|
||||
break;
|
||||
case vk::Format::eR8G8B8A8Unorm:
|
||||
format = vk::Format::eR8G8B8A8Srgb;
|
||||
break;
|
||||
case vk::Format::eB8G8R8A8Unorm:
|
||||
format = vk::Format::eB8G8R8A8Srgb;
|
||||
break;
|
||||
case vk::Format::eA8B8G8R8UnormPack32:
|
||||
format = vk::Format::eA8B8G8R8SrgbPack32;
|
||||
break;
|
||||
case vk::Format::eBc1RgbUnormBlock:
|
||||
format = vk::Format::eBc1RgbSrgbBlock;
|
||||
break;
|
||||
case vk::Format::eBc1RgbaUnormBlock:
|
||||
format = vk::Format::eBc1RgbaSrgbBlock;
|
||||
break;
|
||||
case vk::Format::eBc2UnormBlock:
|
||||
format = vk::Format::eBc2SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eBc3UnormBlock:
|
||||
format = vk::Format::eBc3SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eBc7UnormBlock:
|
||||
format = vk::Format::eBc7SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eEtc2R8G8B8UnormBlock:
|
||||
format = vk::Format::eEtc2R8G8B8SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eEtc2R8G8B8A1UnormBlock:
|
||||
format = vk::Format::eEtc2R8G8B8A1SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eEtc2R8G8B8A8UnormBlock:
|
||||
format = vk::Format::eEtc2R8G8B8A8SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc4x4UnormBlock:
|
||||
format = vk::Format::eAstc4x4SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc5x4UnormBlock:
|
||||
format = vk::Format::eAstc5x4SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc5x5UnormBlock:
|
||||
format = vk::Format::eAstc5x5SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc6x5UnormBlock:
|
||||
format = vk::Format::eAstc6x5SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc6x6UnormBlock:
|
||||
format = vk::Format::eAstc6x6SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc8x5UnormBlock:
|
||||
format = vk::Format::eAstc8x5SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc8x6UnormBlock:
|
||||
format = vk::Format::eAstc8x6SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc8x8UnormBlock:
|
||||
format = vk::Format::eAstc8x8SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc10x5UnormBlock:
|
||||
format = vk::Format::eAstc10x5SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc10x6UnormBlock:
|
||||
format = vk::Format::eAstc10x6SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc10x8UnormBlock:
|
||||
format = vk::Format::eAstc10x8SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc10x10UnormBlock:
|
||||
format = vk::Format::eAstc10x10SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc12x10UnormBlock:
|
||||
format = vk::Format::eAstc12x10SrgbBlock;
|
||||
break;
|
||||
case vk::Format::eAstc12x12UnormBlock:
|
||||
format = vk::Format::eAstc12x12SrgbBlock;
|
||||
break;
|
||||
case vk::Format::ePvrtc12BppUnormBlockIMG:
|
||||
format = vk::Format::ePvrtc12BppSrgbBlockIMG;
|
||||
break;
|
||||
case vk::Format::ePvrtc14BppUnormBlockIMG:
|
||||
format = vk::Format::ePvrtc14BppSrgbBlockIMG;
|
||||
break;
|
||||
case vk::Format::ePvrtc22BppUnormBlockIMG:
|
||||
format = vk::Format::ePvrtc22BppSrgbBlockIMG;
|
||||
break;
|
||||
case vk::Format::ePvrtc24BppUnormBlockIMG:
|
||||
format = vk::Format::ePvrtc24BppSrgbBlockIMG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HPPImage::create_vk_image(vkb::core::DeviceCpp &device, vk::ImageViewType image_view_type, vk::ImageCreateFlags flags)
|
||||
{
|
||||
assert(!vk_image && !vk_image_view && "Vulkan HPPImage already constructed");
|
||||
|
||||
vk_image = std::make_unique<vkb::core::HPPImage>(device,
|
||||
get_extent(),
|
||||
format,
|
||||
vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
|
||||
VMA_MEMORY_USAGE_GPU_ONLY,
|
||||
vk::SampleCountFlagBits::e1,
|
||||
to_u32(mipmaps.size()),
|
||||
layers,
|
||||
vk::ImageTiling::eOptimal,
|
||||
flags);
|
||||
vk_image->set_debug_name(get_name());
|
||||
|
||||
vk_image_view = std::make_unique<vkb::core::HPPImageView>(*vk_image, image_view_type);
|
||||
vk_image_view->set_debug_name("View on " + get_name());
|
||||
}
|
||||
|
||||
void HPPImage::generate_mipmaps()
|
||||
{
|
||||
assert(mipmaps.size() == 1 && "Mipmaps already generated");
|
||||
|
||||
if (mipmaps.size() > 1)
|
||||
{
|
||||
return; // Do not generate again
|
||||
}
|
||||
|
||||
auto extent = get_extent();
|
||||
auto next_width = std::max<uint32_t>(1u, extent.width / 2);
|
||||
auto next_height = std::max<uint32_t>(1u, extent.height / 2);
|
||||
auto channels = 4;
|
||||
auto next_size = next_width * next_height * channels;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Make space for next mipmap
|
||||
auto old_size = to_u32(data.size());
|
||||
data.resize(old_size + next_size);
|
||||
|
||||
auto &prev_mipmap = mipmaps.back();
|
||||
// Update mipmaps
|
||||
vkb::scene_graph::components::HPPMipmap next_mipmap{};
|
||||
next_mipmap.level = prev_mipmap.level + 1;
|
||||
next_mipmap.offset = old_size;
|
||||
next_mipmap.extent = vk::Extent3D{next_width, next_height, 1u};
|
||||
|
||||
// Fill next mipmap memory
|
||||
stbir_resize_uint8(data.data() + prev_mipmap.offset, prev_mipmap.extent.width, prev_mipmap.extent.height, 0,
|
||||
data.data() + next_mipmap.offset, next_mipmap.extent.width, next_mipmap.extent.height, 0, channels);
|
||||
|
||||
mipmaps.emplace_back(std::move(next_mipmap));
|
||||
|
||||
// Next mipmap values
|
||||
next_width = std::max<uint32_t>(1u, next_width / 2);
|
||||
next_height = std::max<uint32_t>(1u, next_height / 2);
|
||||
next_size = next_width * next_height * channels;
|
||||
|
||||
if (next_width == 1 && next_height == 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HPPImage::update_hash()
|
||||
{
|
||||
data_hash = vkb::calculate_hash(data);
|
||||
}
|
||||
|
||||
void HPPImage::update_hash(size_t hash)
|
||||
{
|
||||
data_hash = hash;
|
||||
}
|
||||
const std::vector<uint8_t> &HPPImage::get_data() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
const vk::Extent3D &HPPImage::get_extent() const
|
||||
{
|
||||
assert(!mipmaps.empty());
|
||||
return mipmaps[0].extent;
|
||||
}
|
||||
|
||||
vk::Format HPPImage::get_format() const
|
||||
{
|
||||
return format;
|
||||
}
|
||||
|
||||
const uint32_t HPPImage::get_layers() const
|
||||
{
|
||||
return layers;
|
||||
}
|
||||
|
||||
const std::vector<vkb::scene_graph::components::HPPMipmap> &HPPImage::get_mipmaps() const
|
||||
{
|
||||
return mipmaps;
|
||||
}
|
||||
|
||||
const std::vector<std::vector<vk::DeviceSize>> &HPPImage::get_offsets() const
|
||||
{
|
||||
return offsets;
|
||||
}
|
||||
|
||||
const vkb::core::HPPImage &HPPImage::get_vk_image() const
|
||||
{
|
||||
assert(vk_image && "Vulkan HPPImage was not created");
|
||||
return *vk_image;
|
||||
}
|
||||
|
||||
const vkb::core::HPPImageView &HPPImage::get_vk_image_view() const
|
||||
{
|
||||
assert(vk_image_view && "Vulkan HPPImage view was not created");
|
||||
return *vk_image_view;
|
||||
}
|
||||
|
||||
vkb::scene_graph::components::HPPMipmap &HPPImage::get_mipmap(const size_t index)
|
||||
{
|
||||
assert(index < mipmaps.size());
|
||||
return mipmaps[index];
|
||||
}
|
||||
|
||||
std::vector<uint8_t> &HPPImage::get_mut_data()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
std::vector<vkb::scene_graph::components::HPPMipmap> &HPPImage::get_mut_mipmaps()
|
||||
{
|
||||
return mipmaps;
|
||||
}
|
||||
|
||||
void HPPImage::set_data(const uint8_t *raw_data, size_t size)
|
||||
{
|
||||
assert(data.empty() && "HPPImage data already set");
|
||||
data = {raw_data, raw_data + size};
|
||||
update_hash();
|
||||
}
|
||||
|
||||
void HPPImage::set_depth(const uint32_t depth)
|
||||
{
|
||||
assert(!mipmaps.empty());
|
||||
mipmaps[0].extent.depth = depth;
|
||||
}
|
||||
|
||||
void HPPImage::set_format(const vk::Format f)
|
||||
{
|
||||
format = f;
|
||||
}
|
||||
|
||||
void HPPImage::set_height(const uint32_t height)
|
||||
{
|
||||
assert(!mipmaps.empty());
|
||||
mipmaps[0].extent.height = height;
|
||||
}
|
||||
|
||||
void HPPImage::set_layers(uint32_t l)
|
||||
{
|
||||
layers = l;
|
||||
}
|
||||
|
||||
void HPPImage::set_offsets(const std::vector<std::vector<vk::DeviceSize>> &o)
|
||||
{
|
||||
offsets = o;
|
||||
}
|
||||
|
||||
void HPPImage::set_width(const uint32_t width)
|
||||
{
|
||||
assert(!mipmaps.empty());
|
||||
mipmaps[0].extent.width = width;
|
||||
}
|
||||
|
||||
} // namespace components
|
||||
} // namespace scene_graph
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,117 @@
|
||||
/* Copyright (c) 2021-2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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 "core/hpp_image.h"
|
||||
#include "scene_graph/component.h"
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
template <vkb::BindingType bindingType>
|
||||
class Device;
|
||||
using DeviceCpp = Device<vkb::BindingType::Cpp>;
|
||||
} // namespace core
|
||||
|
||||
namespace scene_graph::components
|
||||
{
|
||||
/**
|
||||
* @param format Vulkan format
|
||||
* @return Whether the vulkan format is ASTC
|
||||
*/
|
||||
bool is_astc(vk::Format format);
|
||||
|
||||
/**
|
||||
* @brief Mipmap information
|
||||
*/
|
||||
struct HPPMipmap
|
||||
{
|
||||
uint32_t level = 0; /// Mipmap level
|
||||
uint32_t offset = 0; /// Byte offset used for uploading
|
||||
vk::Extent3D extent = {0, 0, 0}; /// Width depth and height of the mipmap
|
||||
};
|
||||
|
||||
class HPPImage : public vkb::sg::Component
|
||||
{
|
||||
public:
|
||||
HPPImage(const std::string &name, std::vector<uint8_t> &&data = {}, std::vector<vkb::scene_graph::components::HPPMipmap> &&mipmaps = {{}});
|
||||
virtual ~HPPImage() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Type of content held in image.
|
||||
* This helps to steer the image loaders when deciding what the format should be.
|
||||
* Some image containers don't know whether the data they contain is sRGB or not.
|
||||
* Since most applications save color images in sRGB, knowing that an image
|
||||
* contains color data helps us to better guess its format when unknown.
|
||||
*/
|
||||
enum ContentType
|
||||
{
|
||||
Unknown,
|
||||
Color,
|
||||
Other
|
||||
};
|
||||
|
||||
static std::unique_ptr<vkb::scene_graph::components::HPPImage> load(const std::string &name, const std::string &uri, ContentType content_type);
|
||||
|
||||
// from Component
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
void clear_data();
|
||||
void coerce_format_to_srgb();
|
||||
void create_vk_image(vkb::core::DeviceCpp &device, vk::ImageViewType image_view_type = vk::ImageViewType::e2D, vk::ImageCreateFlags flags = {});
|
||||
void generate_mipmaps();
|
||||
const std::vector<uint8_t> &get_data() const;
|
||||
const vk::Extent3D &get_extent() const;
|
||||
vk::Format get_format() const;
|
||||
const uint32_t get_layers() const;
|
||||
const std::vector<vkb::scene_graph::components::HPPMipmap> &get_mipmaps() const;
|
||||
const std::vector<std::vector<vk::DeviceSize>> &get_offsets() const;
|
||||
const vkb::core::HPPImage &get_vk_image() const;
|
||||
const vkb::core::HPPImageView &get_vk_image_view() const;
|
||||
void update_hash(size_t data_hash);
|
||||
void update_hash();
|
||||
|
||||
protected:
|
||||
vkb::scene_graph::components::HPPMipmap &get_mipmap(size_t index);
|
||||
std::vector<uint8_t> &get_mut_data();
|
||||
std::vector<vkb::scene_graph::components::HPPMipmap> &get_mut_mipmaps();
|
||||
void set_data(const uint8_t *raw_data, size_t size);
|
||||
void set_depth(uint32_t depth);
|
||||
void set_format(vk::Format format);
|
||||
void set_height(uint32_t height);
|
||||
void set_layers(uint32_t layers);
|
||||
void set_offsets(const std::vector<std::vector<vk::DeviceSize>> &offsets);
|
||||
void set_width(uint32_t width);
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> data;
|
||||
size_t data_hash{0};
|
||||
vk::Format format = vk::Format::eUndefined;
|
||||
uint32_t layers = 1;
|
||||
std::vector<vkb::scene_graph::components::HPPMipmap> mipmaps{{}};
|
||||
std::vector<std::vector<vk::DeviceSize>> offsets; // Offsets stored like offsets[array_layer][mipmap_layer]
|
||||
std::unique_ptr<vkb::core::HPPImage> vk_image;
|
||||
std::unique_ptr<vkb::core::HPPImageView> vk_image_view;
|
||||
};
|
||||
|
||||
} // namespace scene_graph::components
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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 "hpp_texture.h"
|
||||
#include "material.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace scene_graph
|
||||
{
|
||||
namespace components
|
||||
{
|
||||
/**
|
||||
* @brief facade class around vkb::sg::Material, providing a vulkan.hpp-based interface
|
||||
*
|
||||
* See vkb::sb::Material for documentation
|
||||
*/
|
||||
class HPPMaterial : private vkb::sg::Material
|
||||
{
|
||||
public:
|
||||
std::unordered_map<std::string, vkb::scene_graph::components::HPPTexture *> const &get_textures() const
|
||||
{
|
||||
return reinterpret_cast<std::unordered_map<std::string, vkb::scene_graph::components::HPPTexture *> const &>(vkb::sg::Material::textures);
|
||||
}
|
||||
};
|
||||
} // namespace components
|
||||
} // namespace scene_graph
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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 "hpp_sub_mesh.h"
|
||||
#include "mesh.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace scene_graph
|
||||
{
|
||||
namespace components
|
||||
{
|
||||
/**
|
||||
* @brief facade class around vkb::sg::Mesh, providing a vulkan.hpp-based interface
|
||||
*
|
||||
* See vkb::sb::Mesh for documentation
|
||||
*/
|
||||
class HPPMesh : private vkb::sg::Mesh
|
||||
{
|
||||
public:
|
||||
std::vector<vkb::scene_graph::components::HPPSubMesh *> const &get_submeshes() const
|
||||
{
|
||||
return reinterpret_cast<std::vector<vkb::scene_graph::components::HPPSubMesh *> const &>(vkb::sg::Mesh::get_submeshes());
|
||||
}
|
||||
};
|
||||
} // namespace components
|
||||
} // namespace scene_graph
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,61 @@
|
||||
/* Copyright (c) 2021-2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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 <scene_graph/components/hpp_material.h>
|
||||
#include <scene_graph/components/sub_mesh.h>
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace scene_graph
|
||||
{
|
||||
namespace components
|
||||
{
|
||||
/**
|
||||
* @brief facade class around vkb::sg::SubMesh, providing a vulkan.hpp-based interface
|
||||
*
|
||||
* See vkb::sb::SubMeshfor for documentation
|
||||
*/
|
||||
class HPPSubMesh : private vkb::sg::SubMesh
|
||||
{
|
||||
public:
|
||||
using vkb::sg::SubMesh::vertex_indices;
|
||||
|
||||
vkb::core::BufferCpp const &get_index_buffer() const
|
||||
{
|
||||
return reinterpret_cast<vkb::core::BufferCpp const &>(*vkb::sg::SubMesh::index_buffer);
|
||||
}
|
||||
|
||||
vk::IndexType get_index_type() const
|
||||
{
|
||||
return static_cast<vk::IndexType>(vkb::sg::SubMesh::index_type);
|
||||
}
|
||||
|
||||
const HPPMaterial *get_material() const
|
||||
{
|
||||
return reinterpret_cast<vkb::scene_graph::components::HPPMaterial const *>(vkb::sg::SubMesh::get_material());
|
||||
}
|
||||
|
||||
vkb::core::BufferCpp const &get_vertex_buffer(std::string const &name) const
|
||||
{
|
||||
return reinterpret_cast<vkb::core::BufferCpp const &>(vkb::sg::SubMesh::vertex_buffers.at(name));
|
||||
}
|
||||
};
|
||||
} // namespace components
|
||||
} // namespace scene_graph
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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 "hpp_image.h"
|
||||
#include "texture.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace scene_graph
|
||||
{
|
||||
namespace components
|
||||
{
|
||||
/**
|
||||
* @brief facade class around vkb::sg::Texture, providing a vulkan.hpp-based interface
|
||||
*
|
||||
* See vkb::sb::Texture for documentation
|
||||
*/
|
||||
class HPPTexture : private vkb::sg::Texture
|
||||
{
|
||||
public:
|
||||
vkb::scene_graph::components::HPPImage *get_image()
|
||||
{
|
||||
return reinterpret_cast<vkb::scene_graph::components::HPPImage *>(vkb::sg::Texture::get_image());
|
||||
}
|
||||
|
||||
void set_image(vkb::scene_graph::components::HPPImage &image)
|
||||
{
|
||||
vkb::sg::Texture::set_image(reinterpret_cast<vkb::sg::Image &>(image));
|
||||
}
|
||||
};
|
||||
} // namespace components
|
||||
} // namespace scene_graph
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,408 @@
|
||||
/* Copyright (c) 2018-2025, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "image.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <mutex>
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include <stb_image_resize.h>
|
||||
|
||||
#include "common/utils.h"
|
||||
#include "filesystem/legacy.h"
|
||||
#include "scene_graph/components/image/astc.h"
|
||||
#include "scene_graph/components/image/ktx.h"
|
||||
#include "scene_graph/components/image/stb.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
bool is_astc(const VkFormat format)
|
||||
{
|
||||
return (format == VK_FORMAT_ASTC_4x4_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_4x4_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_5x4_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_5x4_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_5x5_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_5x5_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_6x5_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_6x5_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_6x6_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_6x6_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_8x5_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_8x5_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_8x6_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_8x6_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_8x8_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_8x8_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_10x5_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_10x5_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_10x6_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_10x6_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_10x8_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_10x8_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_10x10_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_10x10_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_12x10_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_12x10_SRGB_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_12x12_UNORM_BLOCK ||
|
||||
format == VK_FORMAT_ASTC_12x12_SRGB_BLOCK);
|
||||
}
|
||||
|
||||
// When the color-space of a loaded image is unknown (from KTX1 for example) we
|
||||
// may want to assume that the loaded data is in sRGB format (since it usually is).
|
||||
// In those cases, this helper will get called which will force an existing unorm
|
||||
// format to become an srgb format where one exists. If none exist, the format will
|
||||
// remain unmodified.
|
||||
static VkFormat maybe_coerce_to_srgb(VkFormat fmt)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case VK_FORMAT_R8_UNORM:
|
||||
return VK_FORMAT_R8_SRGB;
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
return VK_FORMAT_R8G8_SRGB;
|
||||
case VK_FORMAT_R8G8B8_UNORM:
|
||||
return VK_FORMAT_R8G8B8_SRGB;
|
||||
case VK_FORMAT_B8G8R8_UNORM:
|
||||
return VK_FORMAT_B8G8R8_SRGB;
|
||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||
return VK_FORMAT_R8G8B8A8_SRGB;
|
||||
case VK_FORMAT_B8G8R8A8_UNORM:
|
||||
return VK_FORMAT_B8G8R8A8_SRGB;
|
||||
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
return VK_FORMAT_A8B8G8R8_SRGB_PACK32;
|
||||
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
|
||||
return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
|
||||
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
|
||||
return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
|
||||
case VK_FORMAT_BC2_UNORM_BLOCK:
|
||||
return VK_FORMAT_BC2_SRGB_BLOCK;
|
||||
case VK_FORMAT_BC3_UNORM_BLOCK:
|
||||
return VK_FORMAT_BC3_SRGB_BLOCK;
|
||||
case VK_FORMAT_BC7_UNORM_BLOCK:
|
||||
return VK_FORMAT_BC7_SRGB_BLOCK;
|
||||
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
|
||||
return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
|
||||
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
|
||||
return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
|
||||
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
|
||||
return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
|
||||
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
|
||||
return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
|
||||
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
|
||||
return VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG;
|
||||
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
|
||||
return VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG;
|
||||
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
|
||||
return VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG;
|
||||
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
|
||||
return VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG;
|
||||
default:
|
||||
return fmt;
|
||||
}
|
||||
}
|
||||
|
||||
Image::Image(const std::string &name, std::vector<uint8_t> &&d, std::vector<Mipmap> &&m) :
|
||||
Component{name},
|
||||
data{std::move(d)},
|
||||
format{VK_FORMAT_R8G8B8A8_UNORM},
|
||||
mipmaps{std::move(m)}
|
||||
{
|
||||
update_hash();
|
||||
}
|
||||
|
||||
std::type_index Image::get_type()
|
||||
{
|
||||
return typeid(Image);
|
||||
}
|
||||
|
||||
const std::vector<uint8_t> &Image::get_data() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
size_t Image::get_data_hash() const
|
||||
{
|
||||
return data_hash;
|
||||
}
|
||||
|
||||
void Image::clear_data()
|
||||
{
|
||||
data.clear();
|
||||
data.shrink_to_fit();
|
||||
}
|
||||
|
||||
VkFormat Image::get_format() const
|
||||
{
|
||||
return format;
|
||||
}
|
||||
|
||||
const VkExtent3D &Image::get_extent() const
|
||||
{
|
||||
assert(!mipmaps.empty());
|
||||
return mipmaps[0].extent;
|
||||
}
|
||||
|
||||
const uint32_t Image::get_layers() const
|
||||
{
|
||||
return layers;
|
||||
}
|
||||
|
||||
const std::vector<Mipmap> &Image::get_mipmaps() const
|
||||
{
|
||||
return mipmaps;
|
||||
}
|
||||
|
||||
const std::vector<std::vector<VkDeviceSize>> &Image::get_offsets() const
|
||||
{
|
||||
return offsets;
|
||||
}
|
||||
|
||||
void Image::create_vk_image(vkb::core::DeviceC &device, VkImageViewType image_view_type, VkImageCreateFlags flags)
|
||||
{
|
||||
assert(!vk_image && !vk_image_view && "Vulkan image already constructed");
|
||||
|
||||
vk_image = std::make_unique<core::Image>(device,
|
||||
get_extent(),
|
||||
format,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
VMA_MEMORY_USAGE_GPU_ONLY,
|
||||
VK_SAMPLE_COUNT_1_BIT,
|
||||
to_u32(mipmaps.size()),
|
||||
layers,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
flags);
|
||||
vk_image->set_debug_name(get_name());
|
||||
|
||||
vk_image_view = std::make_unique<core::ImageView>(*vk_image, image_view_type);
|
||||
vk_image_view->set_debug_name("View on " + get_name());
|
||||
}
|
||||
|
||||
const core::Image &Image::get_vk_image() const
|
||||
{
|
||||
assert(vk_image && "Vulkan image was not created");
|
||||
return *vk_image;
|
||||
}
|
||||
|
||||
const core::ImageView &Image::get_vk_image_view() const
|
||||
{
|
||||
assert(vk_image_view && "Vulkan image view was not created");
|
||||
return *vk_image_view;
|
||||
}
|
||||
|
||||
Mipmap &Image::get_mipmap(const size_t index)
|
||||
{
|
||||
assert(index < mipmaps.size());
|
||||
return mipmaps[index];
|
||||
}
|
||||
|
||||
// Note that this function returns the required size for ALL mip levels, *including* the base level.
|
||||
uint32_t get_required_mipmaps_size(const VkExtent3D &extent)
|
||||
{
|
||||
constexpr uint32_t channels = 4;
|
||||
auto width = std::max<uint32_t>(1, extent.width);
|
||||
auto height = std::max<uint32_t>(1, extent.height);
|
||||
auto size = width * height * channels;
|
||||
auto result = size;
|
||||
while (size != channels)
|
||||
{
|
||||
width = std::max<uint32_t>(1u, width >> 1);
|
||||
height = std::max<uint32_t>(1u, height >> 1);
|
||||
size = width * height * channels;
|
||||
result += size;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Image::generate_mipmaps()
|
||||
{
|
||||
assert(mipmaps.size() == 1 && "Mipmaps already generated");
|
||||
|
||||
if (mipmaps.size() > 1)
|
||||
{
|
||||
return; // Do not generate again
|
||||
}
|
||||
|
||||
auto extent = get_extent();
|
||||
auto next_width = std::max<uint32_t>(1u, extent.width / 2);
|
||||
auto next_height = std::max<uint32_t>(1u, extent.height / 2);
|
||||
auto channels = 4;
|
||||
auto next_size = next_width * next_height * channels;
|
||||
|
||||
// Allocate for all the mips at once. The function returns the total size needed for the
|
||||
// existing base mip as well as all the mips that will be generated.
|
||||
data.reserve(get_required_mipmaps_size(extent));
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Make space for next mipmap
|
||||
auto old_size = to_u32(data.size());
|
||||
data.resize(old_size + next_size);
|
||||
|
||||
auto &prev_mipmap = mipmaps.back();
|
||||
// Update mipmaps
|
||||
Mipmap next_mipmap{};
|
||||
next_mipmap.level = prev_mipmap.level + 1;
|
||||
next_mipmap.offset = old_size;
|
||||
next_mipmap.extent = {next_width, next_height, 1u};
|
||||
|
||||
// Fill next mipmap memory
|
||||
stbir_resize_uint8(data.data() + prev_mipmap.offset, prev_mipmap.extent.width, prev_mipmap.extent.height, 0,
|
||||
data.data() + next_mipmap.offset, next_mipmap.extent.width, next_mipmap.extent.height, 0, channels);
|
||||
|
||||
mipmaps.emplace_back(std::move(next_mipmap));
|
||||
|
||||
// Next mipmap values
|
||||
next_width = std::max<uint32_t>(1u, next_width / 2);
|
||||
next_height = std::max<uint32_t>(1u, next_height / 2);
|
||||
next_size = next_width * next_height * channels;
|
||||
|
||||
if (next_width == 1 && next_height == 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Mipmap> &Image::get_mut_mipmaps()
|
||||
{
|
||||
return mipmaps;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> &Image::get_mut_data()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
void Image::update_hash()
|
||||
{
|
||||
data_hash = vkb::calculate_hash(data);
|
||||
}
|
||||
|
||||
void Image::update_hash(size_t hash)
|
||||
{
|
||||
data_hash = hash;
|
||||
}
|
||||
|
||||
void Image::set_data(const uint8_t *raw_data, size_t size)
|
||||
{
|
||||
assert(data.empty() && "Image data already set");
|
||||
data = {raw_data, raw_data + size};
|
||||
update_hash();
|
||||
}
|
||||
|
||||
void Image::set_format(const VkFormat f)
|
||||
{
|
||||
format = f;
|
||||
}
|
||||
|
||||
void Image::set_width(const uint32_t width)
|
||||
{
|
||||
assert(!mipmaps.empty());
|
||||
mipmaps[0].extent.width = width;
|
||||
}
|
||||
|
||||
void Image::set_height(const uint32_t height)
|
||||
{
|
||||
assert(!mipmaps.empty());
|
||||
mipmaps[0].extent.height = height;
|
||||
}
|
||||
|
||||
void Image::set_depth(const uint32_t depth)
|
||||
{
|
||||
assert(!mipmaps.empty());
|
||||
mipmaps[0].extent.depth = depth;
|
||||
}
|
||||
|
||||
void Image::set_layers(uint32_t l)
|
||||
{
|
||||
layers = l;
|
||||
}
|
||||
|
||||
void Image::set_offsets(const std::vector<std::vector<VkDeviceSize>> &o)
|
||||
{
|
||||
offsets = o;
|
||||
}
|
||||
|
||||
void Image::coerce_format_to_srgb()
|
||||
{
|
||||
format = maybe_coerce_to_srgb(format);
|
||||
}
|
||||
|
||||
std::unique_ptr<Image> Image::load(const std::string &name, const std::string &uri,
|
||||
ContentType content_type)
|
||||
{
|
||||
std::unique_ptr<Image> image{nullptr};
|
||||
|
||||
auto data = fs::read_asset(uri);
|
||||
|
||||
// Get extension
|
||||
auto extension = get_extension(uri);
|
||||
|
||||
if (extension == "png" || extension == "jpg")
|
||||
{
|
||||
image = std::make_unique<Stb>(name, data, content_type);
|
||||
}
|
||||
else if (extension == "astc")
|
||||
{
|
||||
image = std::make_unique<Astc>(name, data);
|
||||
}
|
||||
else if (extension == "ktx")
|
||||
{
|
||||
image = std::make_unique<Ktx>(name, data, content_type);
|
||||
}
|
||||
else if (extension == "ktx2")
|
||||
{
|
||||
image = std::make_unique<Ktx>(name, data, content_type);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,152 @@
|
||||
/* Copyright (c) 2018-2025, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include <volk.h>
|
||||
|
||||
#include "core/image.h"
|
||||
#include "core/image_view.h"
|
||||
#include "scene_graph/component.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
/**
|
||||
* @param format Vulkan format
|
||||
* @return Whether the vulkan format is ASTC
|
||||
*/
|
||||
bool is_astc(VkFormat format);
|
||||
|
||||
/**
|
||||
* @brief Mipmap information
|
||||
*/
|
||||
struct Mipmap
|
||||
{
|
||||
/// Mipmap level
|
||||
uint32_t level = 0;
|
||||
|
||||
/// Byte offset used for uploading
|
||||
uint32_t offset = 0;
|
||||
|
||||
/// Width depth and height of the mipmap
|
||||
VkExtent3D extent = {0, 0, 0};
|
||||
};
|
||||
|
||||
class Image : public Component
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Type of content held in image.
|
||||
* This helps to steer the image loaders when deciding what the format should be.
|
||||
* Some image containers don't know whether the data they contain is sRGB or not.
|
||||
* Since most applications save color images in sRGB, knowing that an image
|
||||
* contains color data helps us to better guess its format when unknown.
|
||||
*/
|
||||
enum ContentType
|
||||
{
|
||||
Unknown,
|
||||
Color,
|
||||
Other
|
||||
};
|
||||
|
||||
Image(const std::string &name, std::vector<uint8_t> &&data = {}, std::vector<Mipmap> &&mipmaps = {{}});
|
||||
|
||||
static std::unique_ptr<Image> load(const std::string &name, const std::string &uri, ContentType content_type);
|
||||
|
||||
virtual ~Image() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
const std::vector<uint8_t> &get_data() const;
|
||||
|
||||
size_t get_data_hash() const;
|
||||
|
||||
void clear_data();
|
||||
|
||||
VkFormat get_format() const;
|
||||
|
||||
const VkExtent3D &get_extent() const;
|
||||
|
||||
const uint32_t get_layers() const;
|
||||
|
||||
const std::vector<Mipmap> &get_mipmaps() const;
|
||||
|
||||
const std::vector<std::vector<VkDeviceSize>> &get_offsets() const;
|
||||
|
||||
void generate_mipmaps();
|
||||
|
||||
void create_vk_image(vkb::core::DeviceC &device, VkImageViewType image_view_type = VK_IMAGE_VIEW_TYPE_2D, VkImageCreateFlags flags = 0);
|
||||
|
||||
const core::Image &get_vk_image() const;
|
||||
|
||||
const core::ImageView &get_vk_image_view() const;
|
||||
|
||||
void coerce_format_to_srgb();
|
||||
|
||||
protected:
|
||||
std::vector<uint8_t> &get_mut_data();
|
||||
|
||||
void set_data(const uint8_t *raw_data, size_t size);
|
||||
|
||||
void set_format(VkFormat format);
|
||||
|
||||
void set_width(uint32_t width);
|
||||
|
||||
void set_height(uint32_t height);
|
||||
|
||||
void set_depth(uint32_t depth);
|
||||
|
||||
void set_layers(uint32_t layers);
|
||||
|
||||
void set_offsets(const std::vector<std::vector<VkDeviceSize>> &offsets);
|
||||
|
||||
Mipmap &get_mipmap(size_t index);
|
||||
|
||||
std::vector<Mipmap> &get_mut_mipmaps();
|
||||
|
||||
void update_hash();
|
||||
|
||||
void update_hash(size_t data_hash);
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> data;
|
||||
|
||||
size_t data_hash{0};
|
||||
|
||||
VkFormat format{VK_FORMAT_UNDEFINED};
|
||||
|
||||
uint32_t layers{1};
|
||||
|
||||
std::vector<Mipmap> mipmaps{{}};
|
||||
|
||||
// Offsets stored like offsets[array_layer][mipmap_layer]
|
||||
std::vector<std::vector<VkDeviceSize>> offsets;
|
||||
|
||||
std::unique_ptr<core::Image> vk_image;
|
||||
|
||||
std::unique_ptr<core::ImageView> vk_image_view;
|
||||
};
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,381 @@
|
||||
/* Copyright (c) 2019-2025, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "scene_graph/components/image/astc.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <mutex>
|
||||
|
||||
#include "common/error.h"
|
||||
#include "core/util/profiling.hpp"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
// Windows.h defines IGNORE, so we must #undef it to avoid clashes with astc header
|
||||
# undef IGNORE
|
||||
#endif
|
||||
#include <astcenc.h>
|
||||
|
||||
#include <filesystem/filesystem.hpp>
|
||||
|
||||
#define MAGIC_FILE_CONSTANT 0x5CA1AB13
|
||||
#define ASTC_CACHE_DIRECTORY "cache/astc_to_bin"
|
||||
|
||||
constexpr uint32_t ASTC_CACHE_HEADER_SIZE = 64;
|
||||
constexpr uint32_t ASTC_CACHE_SEED = 1619;
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
|
||||
using Path = std::filesystem::path;
|
||||
|
||||
BlockDim to_blockdim(const VkFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
|
||||
return {4, 4, 1};
|
||||
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
|
||||
return {5, 4, 1};
|
||||
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
|
||||
return {5, 5, 1};
|
||||
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
|
||||
return {6, 5, 1};
|
||||
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
|
||||
return {6, 6, 1};
|
||||
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
|
||||
return {8, 5, 1};
|
||||
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
|
||||
return {8, 6, 1};
|
||||
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
|
||||
return {8, 8, 1};
|
||||
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
|
||||
return {10, 5, 1};
|
||||
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
|
||||
return {10, 6, 1};
|
||||
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
|
||||
return {10, 8, 1};
|
||||
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
|
||||
return {10, 10, 1};
|
||||
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
|
||||
return {12, 10, 1};
|
||||
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
|
||||
return {12, 12, 1};
|
||||
default:
|
||||
throw std::runtime_error{"Invalid astc format"};
|
||||
}
|
||||
}
|
||||
|
||||
inline astcenc_profile to_profile(const VkFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
|
||||
return ASTCENC_PRF_LDR;
|
||||
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
|
||||
return ASTCENC_PRF_LDR_SRGB;
|
||||
default:
|
||||
throw std::runtime_error{"Invalid astc format"};
|
||||
}
|
||||
}
|
||||
|
||||
struct AstcHeader
|
||||
{
|
||||
uint8_t magic[4];
|
||||
uint8_t blockdim_x;
|
||||
uint8_t blockdim_y;
|
||||
uint8_t blockdim_z;
|
||||
uint8_t xsize[3]; // x-size = xsize[0] + xsize[1] + xsize[2]
|
||||
uint8_t ysize[3]; // x-size, y-size and z-size are given in texels;
|
||||
uint8_t zsize[3]; // block count is inferred
|
||||
};
|
||||
|
||||
void Astc::init()
|
||||
{
|
||||
}
|
||||
|
||||
void Astc::decode(BlockDim blockdim, VkExtent3D extent, const uint8_t *compressed_data, uint32_t compressed_size)
|
||||
{
|
||||
PROFILE_SCOPE("Decode ASTC Image");
|
||||
|
||||
// Actual decoding
|
||||
astcenc_swizzle swizzle = {ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A};
|
||||
// Configure the compressor run
|
||||
astcenc_config astc_config;
|
||||
auto atscresult = astcenc_config_init(
|
||||
ASTCENC_PRF_LDR_SRGB,
|
||||
blockdim.x,
|
||||
blockdim.y,
|
||||
blockdim.z,
|
||||
ASTCENC_PRE_FAST,
|
||||
ASTCENC_FLG_DECOMPRESS_ONLY,
|
||||
&astc_config);
|
||||
|
||||
if (atscresult != ASTCENC_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error{"Error initializing astc"};
|
||||
}
|
||||
|
||||
if (extent.width == 0 || extent.height == 0 || extent.depth == 0)
|
||||
{
|
||||
throw std::runtime_error{"Error reading astc: invalid size"};
|
||||
}
|
||||
|
||||
// Allocate working state given config and thread_count
|
||||
astcenc_context *astc_context;
|
||||
astcenc_context_alloc(&astc_config, 1, &astc_context);
|
||||
|
||||
astcenc_image decoded{};
|
||||
decoded.dim_x = extent.width;
|
||||
decoded.dim_y = extent.height;
|
||||
decoded.dim_z = extent.depth;
|
||||
decoded.data_type = ASTCENC_TYPE_U8;
|
||||
|
||||
// allocate storage for the decoded image
|
||||
// The astcenc_decompress_image function will write directly to the image data vector
|
||||
auto uncompressed_size = decoded.dim_x * decoded.dim_y * decoded.dim_z * 4;
|
||||
auto &decoded_data = get_mut_data();
|
||||
decoded_data.resize(uncompressed_size);
|
||||
void *data_ptr = static_cast<void *>(decoded_data.data());
|
||||
decoded.data = &data_ptr;
|
||||
|
||||
atscresult = astcenc_decompress_image(astc_context, compressed_data, compressed_size, &decoded, &swizzle, 0);
|
||||
if (atscresult != ASTCENC_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error("Error decoding astc");
|
||||
}
|
||||
astcenc_context_free(astc_context);
|
||||
|
||||
set_format(VK_FORMAT_R8G8B8A8_SRGB);
|
||||
set_width(decoded.dim_x);
|
||||
set_height(decoded.dim_y);
|
||||
set_depth(decoded.dim_z);
|
||||
}
|
||||
|
||||
Astc::Astc(const Image &image) :
|
||||
Image{image.get_name()}
|
||||
{
|
||||
init();
|
||||
|
||||
auto fs = vkb::filesystem::get();
|
||||
|
||||
size_t key = ASTC_CACHE_SEED;
|
||||
glm::detail::hash_combine(key, image.get_data_hash());
|
||||
|
||||
constexpr bool use_cache = true;
|
||||
constexpr uint32_t bytes_per_pixel = 4;
|
||||
constexpr const char file_cache_header[ASTC_CACHE_HEADER_SIZE] = "ASTCConvertedDataV01";
|
||||
const auto profile = to_profile(image.get_format());
|
||||
|
||||
auto can_load_from_file = [this, profile, fs, file_cache_header, bytes_per_pixel, use_cache](const Path &path, std::vector<uint8_t> &dst_data, uint32_t width, uint32_t height, uint32_t depth) {
|
||||
if (!use_cache)
|
||||
{
|
||||
LOGD("Device does not support ASTC format and cache is disabled. ASTC image {} will be decoded.", get_name())
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (!fs->exists(path))
|
||||
{
|
||||
LOGW("Device does not support ASTC format and cache file {} does not exist. ASTC image {} will be decoded.", path.string(), get_name())
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGD("Loading ASTC image {} from cache file {}", get_name(), path.string())
|
||||
}
|
||||
size_t offset = 0;
|
||||
|
||||
auto copy_from_file = [fs, path](void *dst, size_t *offset, size_t content_size) {
|
||||
const auto bin_content = fs->read_chunk(path, *offset, content_size);
|
||||
std::memcpy(dst, &bin_content[0], content_size);
|
||||
*offset += content_size;
|
||||
};
|
||||
|
||||
char header[ASTC_CACHE_HEADER_SIZE];
|
||||
copy_from_file(&header, &offset, ASTC_CACHE_HEADER_SIZE);
|
||||
if (std::strcmp(header, file_cache_header) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t file_width, file_height, file_depth;
|
||||
copy_from_file(&file_width, &offset, sizeof(std::uint32_t));
|
||||
copy_from_file(&file_height, &offset, sizeof(std::uint32_t));
|
||||
copy_from_file(&file_depth, &offset, sizeof(std::uint32_t));
|
||||
|
||||
if (file_width != width || width == 0 ||
|
||||
file_height != height || height == 0 ||
|
||||
file_depth != depth || depth == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_width(width);
|
||||
set_height(height);
|
||||
set_depth(depth);
|
||||
set_format(profile == ASTCENC_PRF_LDR_SRGB ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM);
|
||||
}
|
||||
|
||||
auto image_size = width * height * depth * bytes_per_pixel;
|
||||
dst_data.resize(image_size);
|
||||
copy_from_file(dst_data.data(), &offset, image_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (const std::runtime_error &e)
|
||||
{
|
||||
LOGE("ERROR loading file {} from cache. Error: <{}>", path.string(), e.what())
|
||||
// file is truncated
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
auto save_to_file = [fs, file_cache_header, bytes_per_pixel, use_cache](const Path &path, uint8_t *dst_data, uint32_t width, uint32_t height, uint32_t depth) {
|
||||
if (!use_cache)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
LOGI("Saving ASTC cache data to file: {}", path.string());
|
||||
|
||||
auto image_size = width * height * depth * bytes_per_pixel;
|
||||
|
||||
std::vector<uint8_t> astc_file_content;
|
||||
astc_file_content.reserve(sizeof(file_cache_header) + (3 * sizeof(std::uint32_t)) + image_size);
|
||||
|
||||
auto append_to_file = [](std::vector<uint8_t> &dst_file, const std::uint8_t *content, size_t content_size) {
|
||||
dst_file.insert(dst_file.end(), content, content + content_size);
|
||||
};
|
||||
|
||||
append_to_file(astc_file_content, (uint8_t *) &file_cache_header, sizeof(file_cache_header));
|
||||
append_to_file(astc_file_content, (uint8_t *) &width, sizeof(uint32_t));
|
||||
append_to_file(astc_file_content, (uint8_t *) &height, sizeof(uint32_t));
|
||||
append_to_file(astc_file_content, (uint8_t *) &depth, sizeof(uint32_t));
|
||||
append_to_file(astc_file_content, (uint8_t *) dst_data, image_size);
|
||||
|
||||
fs->write_file(path, astc_file_content);
|
||||
}
|
||||
catch (const std::runtime_error &e)
|
||||
{
|
||||
LOGE("ERROR: saving to file: {}\nError<{}>", path.string(), e.what())
|
||||
}
|
||||
};
|
||||
|
||||
// Locate mip #0 in the KTX. This is the first one in the data array for KTX1s, but the last one in KTX2s!
|
||||
auto mip_it = std::ranges::find_if(image.get_mipmaps(),
|
||||
[](auto &mip) { return mip.level == 0; });
|
||||
assert(mip_it != image.get_mipmaps().end() && "Mip #0 not found");
|
||||
|
||||
const std::string path = fmt::format("{}/{}.bin", ASTC_CACHE_DIRECTORY, uint64_t(key));
|
||||
|
||||
if (!can_load_from_file(path, get_mut_data(), mip_it->extent.width, mip_it->extent.height, mip_it->extent.depth))
|
||||
{
|
||||
// When decoding ASTC on CPU (as it is the case in here), we don't decode all mips in the mip chain.
|
||||
// Instead, we just decode mip #0 and re-generate the other LODs later (via image->generate_mipmaps()).
|
||||
const auto blockdim = to_blockdim(image.get_format());
|
||||
const auto &extent = mip_it->extent;
|
||||
auto size = extent.width * extent.height * extent.depth * 4;
|
||||
const uint8_t *data_ptr = image.get_data().data() + mip_it->offset;
|
||||
|
||||
decode(blockdim, mip_it->extent, data_ptr, size);
|
||||
|
||||
save_to_file(path, get_mut_data().data(), mip_it->extent.width, mip_it->extent.height, mip_it->extent.depth);
|
||||
}
|
||||
|
||||
update_hash(image.get_data_hash());
|
||||
}
|
||||
|
||||
Astc::Astc(const std::string &name, const std::vector<uint8_t> &data) :
|
||||
Image{name}
|
||||
{
|
||||
init();
|
||||
|
||||
// Read header
|
||||
if (data.size() < sizeof(AstcHeader))
|
||||
{
|
||||
throw std::runtime_error{"Error reading astc: invalid memory"};
|
||||
}
|
||||
AstcHeader header{};
|
||||
std::memcpy(&header, data.data(), sizeof(AstcHeader));
|
||||
uint32_t magicval = header.magic[0] + 256 * static_cast<uint32_t>(header.magic[1]) + 65536 * static_cast<uint32_t>(header.magic[2]) + 16777216 * static_cast<uint32_t>(header.magic[3]);
|
||||
if (magicval != MAGIC_FILE_CONSTANT)
|
||||
{
|
||||
throw std::runtime_error{"Error reading astc: invalid magic"};
|
||||
}
|
||||
|
||||
BlockDim blockdim = {
|
||||
/* xdim = */ header.blockdim_x,
|
||||
/* ydim = */ header.blockdim_y,
|
||||
/* zdim = */ header.blockdim_z};
|
||||
|
||||
VkExtent3D extent = {
|
||||
/* width = */ static_cast<uint32_t>(header.xsize[0] + 256 * header.xsize[1] + 65536 * header.xsize[2]),
|
||||
/* height = */ static_cast<uint32_t>(header.ysize[0] + 256 * header.ysize[1] + 65536 * header.ysize[2]),
|
||||
/* depth = */ static_cast<uint32_t>(header.zsize[0] + 256 * header.zsize[1] + 65536 * header.zsize[2])};
|
||||
|
||||
decode(blockdim, extent, data.data() + sizeof(AstcHeader), to_u32(data.size() - sizeof(AstcHeader)));
|
||||
|
||||
update_hash(get_data_hash());
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,67 @@
|
||||
/* Copyright (c) 2019-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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 "scene_graph/components/image.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
struct BlockDim
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t z;
|
||||
};
|
||||
|
||||
class Astc : public Image
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Decodes an ASTC image
|
||||
* @param image Image to decode
|
||||
*/
|
||||
Astc(const Image &image);
|
||||
|
||||
/**
|
||||
* @brief Decodes ASTC data with an ASTC header
|
||||
* @param name Name of the component
|
||||
* @param data ASTC data with header
|
||||
*/
|
||||
Astc(const std::string &name, const std::vector<uint8_t> &data);
|
||||
|
||||
virtual ~Astc() = default;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Decodes ASTC data
|
||||
* @param blockdim Dimensions of the block
|
||||
* @param extent Extent of the image
|
||||
* @param data Pointer to ASTC image data
|
||||
*/
|
||||
void decode(BlockDim blockdim, VkExtent3D extent, const uint8_t *data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Initializes ASTC library
|
||||
*/
|
||||
void init();
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,184 @@
|
||||
/* Copyright (c) 2019-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.
|
||||
*/
|
||||
|
||||
#include "scene_graph/components/image/ktx.h"
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include <ktx.h>
|
||||
#include <ktxvulkan.h>
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
struct CallbackData final
|
||||
{
|
||||
ktxTexture *texture;
|
||||
std::vector<Mipmap> *mipmaps;
|
||||
};
|
||||
|
||||
/// Row padding is different between KTX (pad to 4) and Vulkan (none).
|
||||
/// Also region->bufferOffset, i.e. the start of each image, has
|
||||
/// to be a multiple of 4 and also a multiple of the element size.
|
||||
static ktx_error_code_e KTX_APIENTRY optimal_tiling_callback(int mip_level,
|
||||
int face,
|
||||
int width,
|
||||
int height,
|
||||
int depth,
|
||||
ktx_uint64_t face_lod_size,
|
||||
void *pixels,
|
||||
void *user_data)
|
||||
{
|
||||
auto *callback_data = reinterpret_cast<CallbackData *>(user_data);
|
||||
assert(static_cast<size_t>(mip_level) < callback_data->mipmaps->size() && "Not enough space in the mipmap vector");
|
||||
|
||||
ktx_size_t mipmap_offset = 0;
|
||||
auto result = ktxTexture_GetImageOffset(callback_data->texture, mip_level, 0, face, &mipmap_offset);
|
||||
if (result != KTX_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
auto &mipmap = callback_data->mipmaps->at(mip_level);
|
||||
mipmap.level = mip_level;
|
||||
mipmap.offset = to_u32(mipmap_offset);
|
||||
mipmap.extent.width = width;
|
||||
mipmap.extent.height = height;
|
||||
mipmap.extent.depth = depth;
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
Ktx::Ktx(const std::string &name, const std::vector<uint8_t> &data, ContentType content_type) :
|
||||
Image{name}
|
||||
{
|
||||
auto data_buffer = reinterpret_cast<const ktx_uint8_t *>(data.data());
|
||||
auto data_size = static_cast<ktx_size_t>(data.size());
|
||||
|
||||
ktxTexture *texture;
|
||||
auto load_ktx_result = ktxTexture_CreateFromMemory(data_buffer,
|
||||
data_size,
|
||||
KTX_TEXTURE_CREATE_NO_FLAGS,
|
||||
&texture);
|
||||
if (load_ktx_result != KTX_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error{"Error loading KTX texture: " + name};
|
||||
}
|
||||
|
||||
if (texture->pData)
|
||||
{
|
||||
// Already loaded
|
||||
set_data(texture->pData, texture->dataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load
|
||||
auto &mut_data = get_mut_data();
|
||||
auto size = texture->dataSize;
|
||||
mut_data.resize(size);
|
||||
auto load_data_result = ktxTexture_LoadImageData(texture, mut_data.data(), size);
|
||||
if (load_data_result != KTX_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error{"Error loading KTX image data: " + name};
|
||||
}
|
||||
}
|
||||
|
||||
set_width(texture->baseWidth);
|
||||
set_height(texture->baseHeight);
|
||||
set_depth(texture->baseDepth);
|
||||
set_layers(texture->numLayers);
|
||||
update_hash();
|
||||
|
||||
bool cubemap = false;
|
||||
|
||||
// Use the faces if there are 6 (for cubemap)
|
||||
if (texture->numLayers == 1 && texture->numFaces == 6)
|
||||
{
|
||||
cubemap = true;
|
||||
set_layers(texture->numFaces);
|
||||
}
|
||||
|
||||
auto updated_format = ktxTexture_GetVkFormat(texture);
|
||||
|
||||
set_format(updated_format);
|
||||
|
||||
if (texture->classId == ktxTexture1_c && content_type == Color)
|
||||
{
|
||||
// KTX-1 files don't contain color space information. Color data is normally
|
||||
// in sRGB, but the format we get back won't report that, so this will adjust it
|
||||
// if necessary.
|
||||
coerce_format_to_srgb();
|
||||
}
|
||||
|
||||
auto &mipmap_levels = get_mut_mipmaps();
|
||||
mipmap_levels.resize(texture->numLevels);
|
||||
|
||||
CallbackData callback_data{};
|
||||
callback_data.texture = texture;
|
||||
callback_data.mipmaps = &mipmap_levels;
|
||||
|
||||
auto result = ktxTexture_IterateLevels(texture, optimal_tiling_callback, &callback_data);
|
||||
if (result != KTX_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error("Error loading KTX texture");
|
||||
}
|
||||
|
||||
// If the texture contains more than one layer, then populate the offsets otherwise take the mipmap level offsets
|
||||
if (texture->numLayers > 1 || cubemap)
|
||||
{
|
||||
uint32_t layer_count = cubemap ? texture->numFaces : texture->numLayers;
|
||||
|
||||
std::vector<std::vector<VkDeviceSize>> offsets;
|
||||
for (uint32_t layer = 0; layer < layer_count; layer++)
|
||||
{
|
||||
std::vector<VkDeviceSize> layer_offsets{};
|
||||
for (uint32_t level = 0; level < texture->numLevels; level++)
|
||||
{
|
||||
ktx_size_t offset;
|
||||
KTX_error_code result;
|
||||
if (cubemap)
|
||||
{
|
||||
result = ktxTexture_GetImageOffset(texture, level, 0, layer, &offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ktxTexture_GetImageOffset(texture, level, layer, 0, &offset);
|
||||
}
|
||||
layer_offsets.push_back(static_cast<VkDeviceSize>(offset));
|
||||
}
|
||||
offsets.push_back(layer_offsets);
|
||||
}
|
||||
set_offsets(offsets);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<std::vector<VkDeviceSize>> offsets{};
|
||||
offsets.resize(1);
|
||||
for (size_t level = 0; level < mipmap_levels.size(); level++)
|
||||
{
|
||||
offsets[0].push_back(static_cast<VkDeviceSize>(mipmap_levels[level].offset));
|
||||
}
|
||||
set_offsets(offsets);
|
||||
}
|
||||
|
||||
ktxTexture_Destroy(texture);
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Copyright (c) 2019-2022, Arm Limited and Contributors
|
||||
*
|
||||
* 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 "scene_graph/components/image.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class Ktx : public Image
|
||||
{
|
||||
public:
|
||||
Ktx(const std::string &name, const std::vector<uint8_t> &data, ContentType content_type);
|
||||
|
||||
virtual ~Ktx() = default;
|
||||
};
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,55 @@
|
||||
/* Copyright (c) 2019-2022, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "scene_graph/components/image/stb.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
Stb::Stb(const std::string &name, const std::vector<uint8_t> &data, ContentType content_type) :
|
||||
Image{name}
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int comp;
|
||||
int req_comp = 4;
|
||||
|
||||
auto data_buffer = reinterpret_cast<const stbi_uc *>(data.data());
|
||||
auto data_size = static_cast<int>(data.size());
|
||||
|
||||
auto raw_data = stbi_load_from_memory(data_buffer, data_size, &width, &height, &comp, req_comp);
|
||||
|
||||
if (!raw_data)
|
||||
{
|
||||
throw std::runtime_error{"Failed to load " + name + ": " + stbi_failure_reason()};
|
||||
}
|
||||
|
||||
set_data(raw_data, width * height * req_comp);
|
||||
stbi_image_free(raw_data);
|
||||
|
||||
set_format(content_type == Color ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM);
|
||||
set_width(to_u32(width));
|
||||
set_height(to_u32(height));
|
||||
set_depth(1u);
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Copyright (c) 2019-2022, Arm Limited and Contributors
|
||||
*
|
||||
* 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 "scene_graph/components/image.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class Stb : public Image
|
||||
{
|
||||
public:
|
||||
Stb(const std::string &name, const std::vector<uint8_t> &data, ContentType content_type);
|
||||
|
||||
virtual ~Stb() = default;
|
||||
};
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,64 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "light.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
Light::Light(const std::string &name) :
|
||||
Component{name}
|
||||
{}
|
||||
|
||||
std::type_index Light::get_type()
|
||||
{
|
||||
return typeid(Light);
|
||||
}
|
||||
|
||||
void Light::set_node(Node &n)
|
||||
{
|
||||
node = &n;
|
||||
}
|
||||
|
||||
Node *Light::get_node()
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
void Light::set_light_type(const LightType &type)
|
||||
{
|
||||
this->light_type = type;
|
||||
}
|
||||
|
||||
const LightType &Light::get_light_type()
|
||||
{
|
||||
return light_type;
|
||||
}
|
||||
|
||||
void Light::set_properties(const LightProperties &properties)
|
||||
{
|
||||
this->properties = properties;
|
||||
}
|
||||
|
||||
const LightProperties &Light::get_properties()
|
||||
{
|
||||
return properties;
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,92 @@
|
||||
/* Copyright (c) 2018-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
|
||||
#include "core/shader_module.h"
|
||||
#include "scene_graph/component.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
enum LightType
|
||||
{
|
||||
Directional = 0,
|
||||
Point = 1,
|
||||
Spot = 2,
|
||||
// Insert new light type here
|
||||
Max
|
||||
};
|
||||
|
||||
struct LightProperties
|
||||
{
|
||||
glm::vec3 direction{0.0f, 0.0f, -1.0f};
|
||||
|
||||
glm::vec3 color{1.0f, 1.0f, 1.0f};
|
||||
|
||||
float intensity{1.0f};
|
||||
|
||||
float range{0.0f};
|
||||
|
||||
float inner_cone_angle{0.0f};
|
||||
|
||||
float outer_cone_angle{0.0f};
|
||||
};
|
||||
|
||||
class Light : public Component
|
||||
{
|
||||
public:
|
||||
Light(const std::string &name);
|
||||
|
||||
Light(Light &&other) = default;
|
||||
|
||||
virtual ~Light() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
void set_node(Node &node);
|
||||
|
||||
Node *get_node();
|
||||
|
||||
void set_light_type(const LightType &type);
|
||||
|
||||
const LightType &get_light_type();
|
||||
|
||||
void set_properties(const LightProperties &properties);
|
||||
|
||||
const LightProperties &get_properties();
|
||||
|
||||
private:
|
||||
Node *node{nullptr};
|
||||
|
||||
LightType light_type;
|
||||
|
||||
LightProperties properties;
|
||||
};
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "material.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
Material::Material(const std::string &name) :
|
||||
Component{name}
|
||||
{}
|
||||
|
||||
std::type_index Material::get_type()
|
||||
{
|
||||
return typeid(Material);
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,78 @@
|
||||
/* Copyright (c) 2018-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
|
||||
#include "scene_graph/component.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class Texture;
|
||||
|
||||
/**
|
||||
* @brief How the alpha value of the main factor and texture should be interpreted
|
||||
*/
|
||||
enum class AlphaMode
|
||||
{
|
||||
/// Alpha value is ignored
|
||||
Opaque,
|
||||
/// Either full opaque or fully transparent
|
||||
Mask,
|
||||
/// Output is combined with the background
|
||||
Blend
|
||||
};
|
||||
|
||||
class Material : public Component
|
||||
{
|
||||
public:
|
||||
Material(const std::string &name);
|
||||
|
||||
Material(Material &&other) = default;
|
||||
|
||||
virtual ~Material() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
std::unordered_map<std::string, Texture *> textures;
|
||||
|
||||
/// Emissive color of the material
|
||||
glm::vec3 emissive{0.0f, 0.0f, 0.0f};
|
||||
|
||||
/// Whether the material is double sided
|
||||
bool double_sided{false};
|
||||
|
||||
/// Cutoff threshold when in Mask mode
|
||||
float alpha_cutoff{0.5f};
|
||||
|
||||
/// Alpha rendering mode
|
||||
AlphaMode alpha_mode{AlphaMode::Opaque};
|
||||
};
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "mesh.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
Mesh::Mesh(const std::string &name) :
|
||||
Component{name}
|
||||
{}
|
||||
|
||||
void Mesh::update_bounds(const std::vector<glm::vec3> &vertex_data, const std::vector<uint16_t> &index_data)
|
||||
{
|
||||
bounds.update(vertex_data, index_data);
|
||||
}
|
||||
|
||||
std::type_index Mesh::get_type()
|
||||
{
|
||||
return typeid(Mesh);
|
||||
}
|
||||
|
||||
const AABB &Mesh::get_bounds() const
|
||||
{
|
||||
return bounds;
|
||||
}
|
||||
|
||||
void Mesh::add_submesh(SubMesh &submesh)
|
||||
{
|
||||
submeshes.push_back(&submesh);
|
||||
}
|
||||
|
||||
const std::vector<SubMesh *> &Mesh::get_submeshes() const
|
||||
{
|
||||
return submeshes;
|
||||
}
|
||||
|
||||
void Mesh::add_node(Node &node)
|
||||
{
|
||||
nodes.push_back(&node);
|
||||
}
|
||||
|
||||
const std::vector<Node *> &Mesh::get_nodes() const
|
||||
{
|
||||
return nodes;
|
||||
}
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "scene_graph/component.h"
|
||||
#include "scene_graph/components/aabb.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class SubMesh;
|
||||
|
||||
class Mesh : public Component
|
||||
{
|
||||
public:
|
||||
Mesh(const std::string &name);
|
||||
|
||||
virtual ~Mesh() = default;
|
||||
|
||||
void update_bounds(const std::vector<glm::vec3> &vertex_data, const std::vector<uint16_t> &index_data = {});
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
const AABB &get_bounds() const;
|
||||
|
||||
void add_submesh(SubMesh &submesh);
|
||||
|
||||
const std::vector<SubMesh *> &get_submeshes() const;
|
||||
|
||||
void add_node(Node &node);
|
||||
|
||||
const std::vector<Node *> &get_nodes() const;
|
||||
|
||||
private:
|
||||
AABB bounds;
|
||||
|
||||
std::vector<SubMesh *> submeshes;
|
||||
|
||||
std::vector<Node *> nodes;
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,107 @@
|
||||
/* Copyright (c) 2023-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "orthographic_camera.h"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
OrthographicCamera::OrthographicCamera(const std::string &name) :
|
||||
Camera{name}
|
||||
{}
|
||||
|
||||
OrthographicCamera::OrthographicCamera(const std::string &name, float left, float right, float bottom, float top, float near_plane, float far_plane) :
|
||||
Camera{name},
|
||||
left{left},
|
||||
right{right},
|
||||
top{top},
|
||||
bottom{bottom},
|
||||
near_plane{near_plane},
|
||||
far_plane{far_plane}
|
||||
{
|
||||
}
|
||||
|
||||
void OrthographicCamera::set_left(float new_left)
|
||||
{
|
||||
left = new_left;
|
||||
}
|
||||
|
||||
float OrthographicCamera::get_left() const
|
||||
{
|
||||
return left;
|
||||
}
|
||||
|
||||
void OrthographicCamera::set_right(float new_right)
|
||||
{
|
||||
right = new_right;
|
||||
}
|
||||
|
||||
float OrthographicCamera::get_right() const
|
||||
{
|
||||
return right;
|
||||
}
|
||||
|
||||
void OrthographicCamera::set_bottom(float new_bottom)
|
||||
{
|
||||
bottom = new_bottom;
|
||||
}
|
||||
|
||||
float OrthographicCamera::get_bottom() const
|
||||
{
|
||||
return bottom;
|
||||
}
|
||||
|
||||
void OrthographicCamera::set_top(float new_top)
|
||||
{
|
||||
top = new_top;
|
||||
}
|
||||
|
||||
float OrthographicCamera::get_top() const
|
||||
{
|
||||
return top;
|
||||
}
|
||||
|
||||
void OrthographicCamera::set_near_plane(float new_near_plane)
|
||||
{
|
||||
near_plane = new_near_plane;
|
||||
}
|
||||
|
||||
float OrthographicCamera::get_near_plane() const
|
||||
{
|
||||
return near_plane;
|
||||
}
|
||||
|
||||
void OrthographicCamera::set_far_plane(float new_far_plane)
|
||||
{
|
||||
far_plane = new_far_plane;
|
||||
}
|
||||
|
||||
float OrthographicCamera::get_far_plane() const
|
||||
{
|
||||
return far_plane;
|
||||
}
|
||||
|
||||
glm::mat4 OrthographicCamera::get_projection()
|
||||
{
|
||||
// Note: Using reversed depth-buffer for increased precision, so Znear and Zfar are flipped
|
||||
return glm::ortho(left, right, bottom, top, far_plane, near_plane);
|
||||
}
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,79 @@
|
||||
/* Copyright (c) 2020-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
|
||||
#include "scene_graph/components/camera.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class OrthographicCamera : public Camera
|
||||
{
|
||||
public:
|
||||
OrthographicCamera(const std::string &name);
|
||||
|
||||
OrthographicCamera(const std::string &name, float left, float right, float bottom, float top, float near_plane, float far_plane);
|
||||
|
||||
virtual ~OrthographicCamera() = default;
|
||||
|
||||
void set_left(float left);
|
||||
|
||||
float get_left() const;
|
||||
|
||||
void set_right(float right);
|
||||
|
||||
float get_right() const;
|
||||
|
||||
void set_bottom(float bottom);
|
||||
|
||||
float get_bottom() const;
|
||||
|
||||
void set_top(float top);
|
||||
|
||||
float get_top() const;
|
||||
|
||||
void set_near_plane(float near_plane);
|
||||
|
||||
float get_near_plane() const;
|
||||
|
||||
void set_far_plane(float far_plane);
|
||||
|
||||
float get_far_plane() const;
|
||||
|
||||
virtual glm::mat4 get_projection() override;
|
||||
|
||||
private:
|
||||
float left{-1.0f};
|
||||
|
||||
float right{1.0f};
|
||||
|
||||
float bottom{-1.0f};
|
||||
|
||||
float top{1.0f};
|
||||
|
||||
float near_plane{0.0f};
|
||||
|
||||
float far_plane{1.0f};
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,33 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "pbr_material.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
PBRMaterial::PBRMaterial(const std::string &name) :
|
||||
Material{name}
|
||||
{}
|
||||
|
||||
std::type_index PBRMaterial::get_type()
|
||||
{
|
||||
return typeid(PBRMaterial);
|
||||
}
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Copyright (c) 2018-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
|
||||
#include "scene_graph/components/material.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class PBRMaterial : public Material
|
||||
{
|
||||
public:
|
||||
PBRMaterial(const std::string &name);
|
||||
|
||||
virtual ~PBRMaterial() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
glm::vec4 base_color_factor{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
float metallic_factor{0.0f};
|
||||
|
||||
float roughness_factor{0.0f};
|
||||
};
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,76 @@
|
||||
/* Copyright (c) 2019-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "perspective_camera.h"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
PerspectiveCamera::PerspectiveCamera(const std::string &name) :
|
||||
Camera{name}
|
||||
{}
|
||||
|
||||
void PerspectiveCamera::set_field_of_view(float new_fov)
|
||||
{
|
||||
fov = new_fov;
|
||||
}
|
||||
|
||||
float PerspectiveCamera::get_far_plane() const
|
||||
{
|
||||
return far_plane;
|
||||
}
|
||||
|
||||
void PerspectiveCamera::set_far_plane(float zfar)
|
||||
{
|
||||
far_plane = zfar;
|
||||
}
|
||||
|
||||
float PerspectiveCamera::get_near_plane() const
|
||||
{
|
||||
return near_plane;
|
||||
}
|
||||
|
||||
void PerspectiveCamera::set_near_plane(float znear)
|
||||
{
|
||||
near_plane = znear;
|
||||
}
|
||||
|
||||
void PerspectiveCamera::set_aspect_ratio(float new_aspect_ratio)
|
||||
{
|
||||
aspect_ratio = new_aspect_ratio;
|
||||
}
|
||||
|
||||
float PerspectiveCamera::get_field_of_view()
|
||||
{
|
||||
return fov;
|
||||
}
|
||||
|
||||
float PerspectiveCamera::get_aspect_ratio()
|
||||
{
|
||||
return aspect_ratio;
|
||||
}
|
||||
|
||||
glm::mat4 PerspectiveCamera::get_projection()
|
||||
{
|
||||
// Note: Using reversed depth-buffer for increased precision, so Znear and Zfar are flipped
|
||||
return glm::perspective(fov, aspect_ratio, far_plane, near_plane);
|
||||
}
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,77 @@
|
||||
/* Copyright (c) 2019-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
|
||||
#include "scene_graph/components/camera.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class PerspectiveCamera : public Camera
|
||||
{
|
||||
public:
|
||||
PerspectiveCamera(const std::string &name);
|
||||
|
||||
virtual ~PerspectiveCamera() = default;
|
||||
|
||||
void set_aspect_ratio(float aspect_ratio);
|
||||
|
||||
void set_field_of_view(float fov);
|
||||
|
||||
float get_far_plane() const;
|
||||
|
||||
void set_far_plane(float zfar);
|
||||
|
||||
float get_near_plane() const;
|
||||
|
||||
void set_near_plane(float znear);
|
||||
|
||||
float get_aspect_ratio();
|
||||
|
||||
float get_field_of_view();
|
||||
|
||||
virtual glm::mat4 get_projection() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Screen size aspect ratio
|
||||
*/
|
||||
float aspect_ratio{1.0f};
|
||||
|
||||
/**
|
||||
* @brief Horizontal field of view in radians
|
||||
*/
|
||||
float fov{glm::radians(60.0f)};
|
||||
|
||||
float far_plane{100.0};
|
||||
|
||||
float near_plane{0.1f};
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "sampler.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
Sampler::Sampler(const std::string &name, core::Sampler &&vk_sampler) :
|
||||
Component{name},
|
||||
vk_sampler{std::move(vk_sampler)}
|
||||
{}
|
||||
|
||||
std::type_index Sampler::get_type()
|
||||
{
|
||||
return typeid(Sampler);
|
||||
}
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,46 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "core/sampler.h"
|
||||
#include "scene_graph/component.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class Sampler : public Component
|
||||
{
|
||||
public:
|
||||
Sampler(const std::string &name, core::Sampler &&vk_sampler);
|
||||
|
||||
Sampler(Sampler &&other) = default;
|
||||
|
||||
virtual ~Sampler() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
core::Sampler vk_sampler;
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,75 @@
|
||||
/* Copyright (c) 2018-2025, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "sub_mesh.h"
|
||||
|
||||
#include "material.h"
|
||||
#include "rendering/subpass.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
SubMesh::SubMesh(const std::string &name) :
|
||||
Component{name}
|
||||
{}
|
||||
|
||||
std::type_index SubMesh::get_type()
|
||||
{
|
||||
return typeid(SubMesh);
|
||||
}
|
||||
|
||||
void SubMesh::set_attribute(const std::string &attribute_name, const VertexAttribute &attribute)
|
||||
{
|
||||
vertex_attributes[attribute_name] = attribute;
|
||||
}
|
||||
|
||||
bool SubMesh::get_attribute(const std::string &attribute_name, VertexAttribute &attribute) const
|
||||
{
|
||||
auto attrib_it = vertex_attributes.find(attribute_name);
|
||||
|
||||
if (attrib_it == vertex_attributes.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
attribute = attrib_it->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SubMesh::set_material(const Material &new_material)
|
||||
{
|
||||
material = &new_material;
|
||||
}
|
||||
|
||||
const Material *SubMesh::get_material() const
|
||||
{
|
||||
return material;
|
||||
}
|
||||
|
||||
const ShaderVariant &SubMesh::get_shader_variant() const
|
||||
{
|
||||
return shader_variant;
|
||||
}
|
||||
|
||||
ShaderVariant &SubMesh::get_mut_shader_variant()
|
||||
{
|
||||
return shader_variant;
|
||||
}
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,87 @@
|
||||
/* Copyright (c) 2018-2025, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "common/vk_common.h"
|
||||
#include "core/buffer.h"
|
||||
#include "core/shader_module.h"
|
||||
#include "scene_graph/component.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class Material;
|
||||
|
||||
struct VertexAttribute
|
||||
{
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
|
||||
std::uint32_t stride = 0;
|
||||
|
||||
std::uint32_t offset = 0;
|
||||
};
|
||||
|
||||
class SubMesh : public Component
|
||||
{
|
||||
public:
|
||||
SubMesh(const std::string &name = {});
|
||||
|
||||
virtual ~SubMesh() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
VkIndexType index_type{};
|
||||
|
||||
std::uint32_t index_offset = 0;
|
||||
|
||||
std::uint32_t vertices_count = 0;
|
||||
|
||||
std::uint32_t vertex_indices = 0;
|
||||
|
||||
std::unordered_map<std::string, vkb::core::BufferC> vertex_buffers;
|
||||
|
||||
std::unique_ptr<vkb::core::BufferC> index_buffer;
|
||||
|
||||
void set_attribute(const std::string &name, const VertexAttribute &attribute);
|
||||
|
||||
bool get_attribute(const std::string &name, VertexAttribute &attribute) const;
|
||||
|
||||
void set_material(const Material &material);
|
||||
|
||||
const Material *get_material() const;
|
||||
|
||||
const ShaderVariant &get_shader_variant() const;
|
||||
|
||||
ShaderVariant &get_mut_shader_variant();
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, VertexAttribute> vertex_attributes;
|
||||
|
||||
const Material *material{nullptr};
|
||||
|
||||
ShaderVariant shader_variant;
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,57 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
#include "scene_graph/components/image.h"
|
||||
#include "scene_graph/components/sampler.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
Texture::Texture(const std::string &name) :
|
||||
Component{name}
|
||||
{}
|
||||
|
||||
std::type_index Texture::get_type()
|
||||
{
|
||||
return typeid(Texture);
|
||||
}
|
||||
|
||||
void Texture::set_image(Image &i)
|
||||
{
|
||||
image = &i;
|
||||
}
|
||||
|
||||
Image *Texture::get_image()
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
void Texture::set_sampler(Sampler &s)
|
||||
{
|
||||
sampler = &s;
|
||||
}
|
||||
|
||||
Sampler *Texture::get_sampler()
|
||||
{
|
||||
assert(sampler && "Texture has no sampler");
|
||||
return sampler;
|
||||
}
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Copyright (c) 2018-2019, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "scene_graph/component.h"
|
||||
#include "scene_graph/components/sampler.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class Image;
|
||||
class Sampler;
|
||||
|
||||
class Texture : public Component
|
||||
{
|
||||
public:
|
||||
Texture(const std::string &name);
|
||||
|
||||
Texture(Texture &&other) = default;
|
||||
|
||||
virtual ~Texture() = default;
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
void set_image(Image &image);
|
||||
|
||||
Image *get_image();
|
||||
|
||||
void set_sampler(Sampler &sampler);
|
||||
|
||||
Sampler *get_sampler();
|
||||
|
||||
private:
|
||||
Image *image{nullptr};
|
||||
|
||||
Sampler *sampler{nullptr};
|
||||
};
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,129 @@
|
||||
/* Copyright (c) 2018-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "transform.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
#include <glm/gtx/matrix_decompose.hpp>
|
||||
|
||||
#include "scene_graph/node.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
Transform::Transform(Node &n) :
|
||||
node{n}
|
||||
{
|
||||
}
|
||||
|
||||
Node &Transform::get_node()
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
std::type_index Transform::get_type()
|
||||
{
|
||||
return typeid(Transform);
|
||||
}
|
||||
|
||||
void Transform::set_translation(const glm::vec3 &new_translation)
|
||||
{
|
||||
translation = new_translation;
|
||||
|
||||
invalidate_world_matrix();
|
||||
}
|
||||
|
||||
void Transform::set_rotation(const glm::quat &new_rotation)
|
||||
{
|
||||
rotation = new_rotation;
|
||||
|
||||
invalidate_world_matrix();
|
||||
}
|
||||
|
||||
void Transform::set_scale(const glm::vec3 &new_scale)
|
||||
{
|
||||
scale = new_scale;
|
||||
|
||||
invalidate_world_matrix();
|
||||
}
|
||||
|
||||
const glm::vec3 &Transform::get_translation() const
|
||||
{
|
||||
return translation;
|
||||
}
|
||||
|
||||
const glm::quat &Transform::get_rotation() const
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
const glm::vec3 &Transform::get_scale() const
|
||||
{
|
||||
return scale;
|
||||
}
|
||||
|
||||
void Transform::set_matrix(const glm::mat4 &matrix)
|
||||
{
|
||||
glm::vec3 skew;
|
||||
glm::vec4 perspective;
|
||||
glm::decompose(matrix, scale, rotation, translation, skew, perspective);
|
||||
|
||||
invalidate_world_matrix();
|
||||
}
|
||||
|
||||
glm::mat4 Transform::get_matrix() const
|
||||
{
|
||||
return glm::translate(glm::mat4(1.0), translation) *
|
||||
glm::mat4_cast(rotation) *
|
||||
glm::scale(glm::mat4(1.0), scale);
|
||||
}
|
||||
|
||||
glm::mat4 Transform::get_world_matrix()
|
||||
{
|
||||
update_world_transform();
|
||||
|
||||
return world_matrix;
|
||||
}
|
||||
|
||||
void Transform::invalidate_world_matrix()
|
||||
{
|
||||
update_world_matrix = true;
|
||||
}
|
||||
|
||||
void Transform::update_world_transform()
|
||||
{
|
||||
if (!update_world_matrix)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
world_matrix = get_matrix();
|
||||
|
||||
auto parent = node.get_parent();
|
||||
|
||||
if (parent)
|
||||
{
|
||||
auto &transform = parent->get_component<Transform>();
|
||||
world_matrix = transform.get_world_matrix() * world_matrix;
|
||||
}
|
||||
|
||||
update_world_matrix = false;
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
@@ -0,0 +1,91 @@
|
||||
/* Copyright (c) 2018-2024, Arm Limited and Contributors
|
||||
*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include "scene_graph/component.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
class Node;
|
||||
|
||||
class Transform : public Component
|
||||
{
|
||||
public:
|
||||
Transform(Node &node);
|
||||
|
||||
virtual ~Transform() = default;
|
||||
|
||||
Node &get_node();
|
||||
|
||||
virtual std::type_index get_type() override;
|
||||
|
||||
void set_translation(const glm::vec3 &translation);
|
||||
|
||||
void set_rotation(const glm::quat &rotation);
|
||||
|
||||
void set_scale(const glm::vec3 &scale);
|
||||
|
||||
const glm::vec3 &get_translation() const;
|
||||
|
||||
const glm::quat &get_rotation() const;
|
||||
|
||||
const glm::vec3 &get_scale() const;
|
||||
|
||||
void set_matrix(const glm::mat4 &matrix);
|
||||
|
||||
glm::mat4 get_matrix() const;
|
||||
|
||||
glm::mat4 get_world_matrix();
|
||||
|
||||
/**
|
||||
* @brief Marks the world transform invalid if any of
|
||||
* the local transform are changed or the parent
|
||||
* world transform has changed.
|
||||
*/
|
||||
void invalidate_world_matrix();
|
||||
|
||||
private:
|
||||
Node &node;
|
||||
|
||||
glm::vec3 translation = glm::vec3(0.0, 0.0, 0.0);
|
||||
|
||||
glm::quat rotation = glm::quat(1.0, 0.0, 0.0, 0.0);
|
||||
|
||||
glm::vec3 scale = glm::vec3(1.0, 1.0, 1.0);
|
||||
|
||||
glm::mat4 world_matrix = glm::mat4(1.0);
|
||||
|
||||
bool update_world_matrix = false;
|
||||
|
||||
void update_world_transform();
|
||||
};
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
Reference in New Issue
Block a user