Some slight cleanup for KTX image loader
This commit is contained in:
@@ -67,7 +67,10 @@ if (NOT ANDROID AND NOT IOS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense concurrentqueue units ktx dds_image)
|
||||
target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense concurrentqueue units dds_image)
|
||||
if (ENABLE_KTX)
|
||||
target_link_libraries(openVulkanoCpp PUBLIC ktx)
|
||||
endif ()
|
||||
LinkAssimp(openVulkanoCpp)
|
||||
LinkLibArchive(openVulkanoCpp)
|
||||
LinkLibJpegTurbo(openVulkanoCpp)
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
*/
|
||||
|
||||
#include "ImageLoaderKtx.hpp"
|
||||
#include "Base/Logger.hpp"
|
||||
|
||||
#if __has_include("ktx.h")
|
||||
#include <ktx.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -13,22 +15,72 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace
|
||||
{
|
||||
void KtxDestroy(ktxTexture* tex)
|
||||
{
|
||||
ktxTexture_Destroy(tex);
|
||||
}
|
||||
}
|
||||
|
||||
namespace OpenVulkano::Image
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct KTXTextureDeleter {
|
||||
void operator()(ktxTexture* texture) const {
|
||||
if (texture) {
|
||||
ktxTexture_Destroy(texture);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<Image> ExtractImage(ktxTexture* texture)
|
||||
{
|
||||
if (!texture->pData)
|
||||
{
|
||||
throw std::runtime_error("No image data found in KTX texture.");
|
||||
}
|
||||
|
||||
auto width = static_cast<int>(texture->baseWidth);
|
||||
auto height = static_cast<int>(texture->baseHeight);
|
||||
|
||||
auto image = std::make_unique<Image>();
|
||||
image->resolution.x = width;
|
||||
image->resolution.y = height;
|
||||
image->resolution.z = 1;
|
||||
|
||||
if (texture->classId == ktxTexture1_c)
|
||||
{
|
||||
ktxTexture1* tx = reinterpret_cast<ktxTexture1*>(texture);
|
||||
DataFormat format = DataFormat::Format::UNDEFINED;
|
||||
switch (tx->glInternalformat)
|
||||
{
|
||||
case 0x8051: /* GL_RGB8_EXT */ format = DataFormat::Format::R8G8B8_UNORM; break;
|
||||
case 0x8054: /* GL_RGB16_EXT */ format = DataFormat::Format::R16G16B16_UNORM; break;
|
||||
case 0x8057: /* GL_RGB5_A1_EXT */ format = DataFormat::Format::R5G5B5A1_UNORM_PACK16; break;
|
||||
case 0x8058: /* GL_RGBA8_EXT */ format = DataFormat::Format::R8G8B8A8_UNORM; break;
|
||||
case 0x8059: /* GL_RGB10_A2_EXT */ format = DataFormat::Format::A2R10G10B10_UNORM_PACK32; break;
|
||||
case 0x805B: /* GL_RGBA16_EXT */ format = DataFormat::Format::R16G16B16A16_UNORM; break;
|
||||
default: throw std::runtime_error("Unhandled texture1 format: " + tx->glInternalformat);
|
||||
}
|
||||
image->dataFormat = format;
|
||||
}
|
||||
else if (texture->classId == ktxTexture2_c)
|
||||
{
|
||||
ktxTexture2* tx = reinterpret_cast<ktxTexture2*>(texture);
|
||||
image->dataFormat = reinterpret_cast<DataFormat::Format&>(tx->vkFormat);
|
||||
}
|
||||
else [[unlikely]]
|
||||
{
|
||||
throw std::runtime_error("ktxTexture has unhandled classId!");
|
||||
}
|
||||
|
||||
image->data = Array<uint8_t>(texture->dataSize);
|
||||
memcpy(image->data.Data(), texture->pData, image->data.Size());
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Image> ImageLoaderKtx::loadFromFile(const std::string& filePath)
|
||||
{
|
||||
ktxTexture* tmp = nullptr;
|
||||
KTX_error_code error_code =
|
||||
ktxTexture_CreateFromNamedFile(filePath.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &tmp);
|
||||
std::unique_ptr<ktxTexture, decltype(&KtxDestroy)> texture(tmp, &KtxDestroy);
|
||||
std::unique_ptr<ktxTexture, KTXTextureDeleter> texture(tmp);
|
||||
|
||||
if (error_code != KTX_SUCCESS)
|
||||
{
|
||||
@@ -44,7 +96,7 @@ namespace OpenVulkano::Image
|
||||
ktxTexture* tmp = nullptr;
|
||||
KTX_error_code error_code =
|
||||
ktxTexture_CreateFromMemory(buffer.data(), buffer.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &tmp);
|
||||
std::unique_ptr<ktxTexture, decltype(&KtxDestroy)> texture(tmp, &KtxDestroy);
|
||||
std::unique_ptr<ktxTexture, KTXTextureDeleter> texture(tmp);
|
||||
|
||||
if (error_code != KTX_SUCCESS)
|
||||
{
|
||||
@@ -60,7 +112,7 @@ namespace OpenVulkano::Image
|
||||
ktxTexture* tmp = nullptr;
|
||||
KTX_error_code result =
|
||||
ktxTexture_CreateFromNamedFile(filename.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &tmp);
|
||||
std::unique_ptr<ktxTexture, decltype(&KtxDestroy)> texture(tmp, &KtxDestroy);
|
||||
std::unique_ptr<ktxTexture, KTXTextureDeleter> texture(tmp);
|
||||
|
||||
if (result != KTX_SUCCESS)
|
||||
{
|
||||
@@ -71,51 +123,26 @@ namespace OpenVulkano::Image
|
||||
Math::Vector2i dimensions(texture->baseWidth, texture->baseHeight);
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
std::unique_ptr<Image> ImageLoaderKtx::ExtractImage(ktxTexture* texture)
|
||||
}
|
||||
#else
|
||||
namespace OpenVulkano::Image
|
||||
{
|
||||
std::unique_ptr<Image> ImageLoaderKtx::loadFromFile(const std::string& filePath)
|
||||
{
|
||||
if (!texture->pData)
|
||||
{
|
||||
throw std::runtime_error("No image data found in KTX texture.");
|
||||
}
|
||||
|
||||
auto width = static_cast<int>(texture->baseWidth);
|
||||
auto height = static_cast<int>(texture->baseHeight);
|
||||
|
||||
auto image = std::make_unique<Image>();
|
||||
image->resolution.x = width;
|
||||
image->resolution.y = height;
|
||||
image->resolution.z = 1;
|
||||
|
||||
if (texture->classId == ktxTexture1_c)
|
||||
{
|
||||
ktxTexture1* tx = reinterpret_cast<ktxTexture1*>(texture);
|
||||
DataFormat format = DataFormat::Format::UNDEFINED;
|
||||
switch (tx->glInternalformat)
|
||||
{
|
||||
case 0x8051: /* GL_RGB8_EXT */ format = DataFormat::Format::R8G8B8_UNORM; break;
|
||||
case 0x8054: /* GL_RGB16_EXT */ format = DataFormat::Format::R16G16B16_UNORM; break;
|
||||
case 0x8057: /* GL_RGB5_A1_EXT */ format = DataFormat::Format::R5G5B5A1_UNORM_PACK16; break;
|
||||
case 0x8058: /* GL_RGBA8_EXT */ format = DataFormat::Format::R8G8B8A8_UNORM; break;
|
||||
case 0x8059: /* GL_RGB10_A2_EXT */ format = DataFormat::Format::A2R10G10B10_UNORM_PACK32; break;
|
||||
case 0x805B: /* GL_RGBA16_EXT */ format = DataFormat::Format::R16G16B16A16_UNORM; break;
|
||||
default: throw std::runtime_error("Unhandled texture1 format: " + tx->glInternalformat);
|
||||
}
|
||||
image->dataFormat = format;
|
||||
}
|
||||
else if (texture->classId == ktxTexture2_c)
|
||||
{
|
||||
ktxTexture2* tx = reinterpret_cast<ktxTexture2*>(texture);
|
||||
image->dataFormat = reinterpret_cast<DataFormat::Format&>(tx->vkFormat);
|
||||
}
|
||||
else [[unlikely]]
|
||||
{
|
||||
throw std::runtime_error("ktxTexture has unhandled classId!");
|
||||
}
|
||||
|
||||
image->data = Array<uint8_t>(texture->dataSize);
|
||||
memcpy(image->data.Data(), texture->pData, image->data.Size());
|
||||
|
||||
return image;
|
||||
Logger::DATA->error("KTX loading not available.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Image> ImageLoaderKtx::loadFromMemory(const std::vector<uint8_t>& buffer)
|
||||
{
|
||||
Logger::DATA->error("KTX loading not available.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Math::Vector2i ImageLoaderKtx::GetImageDimensions(const std::string& filename)
|
||||
{
|
||||
Logger::DATA->error("KTX loading not available.");
|
||||
return {0,0};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#include "ImageLoader.hpp"
|
||||
|
||||
struct ktxTexture;
|
||||
|
||||
namespace OpenVulkano::Image
|
||||
{
|
||||
class ImageLoaderKtx : public IImageLoader
|
||||
@@ -18,8 +16,5 @@ namespace OpenVulkano::Image
|
||||
std::unique_ptr<Image> loadFromFile(const std::string& filePath) override;
|
||||
std::unique_ptr<Image> loadFromMemory(const std::vector<uint8_t>& buffer) override;
|
||||
Math::Vector2i GetImageDimensions(const std::string& filename) override;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Image> ExtractImage(ktxTexture* texture);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user