From 40ec5b75e57f760bc3d9a9ff660828b8cbb5ff37 Mon Sep 17 00:00:00 2001 From: Squareys Date: Mon, 22 Jul 2019 12:04:13 +0200 Subject: [PATCH] BasisImporter: Initial implementation and test Signed-off-by: Squareys --- CMakeLists.txt | 6 + doc/building-plugins.dox | 2 + doc/changelog-plugins.dox | 2 + doc/cmake-plugins.dox | 4 + doc/credits.dox | 1 + doc/snippets/CMakeLists.txt | 51 +++ doc/snippets/MagnumPluginsBasisImporter.cpp | 42 +++ doc/snippets/configure.h.cmake | 27 ++ modules/FindMagnumPlugins.cmake | 10 +- src/MagnumExternal/CMakeLists.txt | 2 +- .../BasisImporter/BasisImporter.conf | 17 + .../BasisImporter/BasisImporter.cpp | 260 +++++++++++++++ .../BasisImporter/BasisImporter.h | 221 ++++++++++++ .../BasisImporter/CMakeLists.txt | 69 ++++ .../BasisImporter/Test/BasisImporterTest.cpp | 315 ++++++++++++++++++ .../BasisImporter/Test/CMakeLists.txt | 72 ++++ .../BasisImporter/Test/README.md | 27 ++ .../BasisImporter/Test/configure.h.cmake | 28 ++ .../BasisImporter/Test/rgb.basis | Bin 0 -> 390 bytes .../BasisImporter/Test/rgb_27x63.png | Bin 0 -> 407 bytes .../BasisImporter/Test/rgb_2_images.basis | Bin 0 -> 547 bytes .../Test/rgb_2_images_pow2.basis | Bin 0 -> 521 bytes .../BasisImporter/Test/rgb_32x64.png | Bin 0 -> 731 bytes .../BasisImporter/Test/rgb_63x27.png | Bin 0 -> 528 bytes .../BasisImporter/Test/rgb_64x32.png | Bin 0 -> 691 bytes .../BasisImporter/Test/rgba_27x63.png | Bin 0 -> 111 bytes .../BasisImporter/Test/rgba_2_images.basis | Bin 0 -> 332 bytes .../Test/rgba_2_images_pow2.basis | Bin 0 -> 603 bytes .../BasisImporter/Test/rgba_63x27.png | Bin 0 -> 117 bytes .../BasisImporter/configure.h.cmake | 26 ++ .../BasisImporter/importStaticPlugin.cpp | 36 ++ src/MagnumPlugins/CMakeLists.txt | 4 + 32 files changed, 1220 insertions(+), 2 deletions(-) create mode 100644 doc/snippets/CMakeLists.txt create mode 100644 doc/snippets/MagnumPluginsBasisImporter.cpp create mode 100644 doc/snippets/configure.h.cmake create mode 100644 src/MagnumPlugins/BasisImporter/BasisImporter.conf create mode 100644 src/MagnumPlugins/BasisImporter/BasisImporter.cpp create mode 100644 src/MagnumPlugins/BasisImporter/BasisImporter.h create mode 100644 src/MagnumPlugins/BasisImporter/CMakeLists.txt create mode 100644 src/MagnumPlugins/BasisImporter/Test/BasisImporterTest.cpp create mode 100644 src/MagnumPlugins/BasisImporter/Test/CMakeLists.txt create mode 100644 src/MagnumPlugins/BasisImporter/Test/README.md create mode 100644 src/MagnumPlugins/BasisImporter/Test/configure.h.cmake create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgb.basis create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgb_27x63.png create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgb_2_images.basis create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgb_2_images_pow2.basis create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgb_32x64.png create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgb_63x27.png create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgb_64x32.png create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgba_27x63.png create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgba_2_images.basis create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgba_2_images_pow2.basis create mode 100644 src/MagnumPlugins/BasisImporter/Test/rgba_63x27.png create mode 100644 src/MagnumPlugins/BasisImporter/configure.h.cmake create mode 100644 src/MagnumPlugins/BasisImporter/importStaticPlugin.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b7a64e334..f7466cfa2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ include(CMakeDependentOption) # Plugins to build option(WITH_ASSIMPIMPORTER "Build AssimpImporter plugin" OFF) +option(WITH_BASISIMPORTER "Build BasisImporter plugin" OFF) option(WITH_DDSIMPORTER "Build DdsImporter plugin" OFF) option(WITH_DEVILIMAGEIMPORTER "Build DevIlImageImporter plugin" OFF) option(WITH_DRFLACAUDIOIMPORTER "Build DrFlacAudioImporter plugin" OFF) @@ -121,3 +122,8 @@ set(MAGNUM_LIBRARY_SOVERSION 2) add_subdirectory(modules) add_subdirectory(src) + +# Build snippets as part of testing +if(BUILD_TESTS) + add_subdirectory(doc/snippets) +endif() diff --git a/doc/building-plugins.dox b/doc/building-plugins.dox index c67ef94aa..7f86804c7 100644 --- a/doc/building-plugins.dox +++ b/doc/building-plugins.dox @@ -289,6 +289,8 @@ By default no plugins are built and you need to select them manually: - `WITH_ASSIMPIMPORTER` --- Build the @ref Trade::AssimpImporter "AssimpImporter" plugin. Depends on [Assimp](http://assimp.org/). +- `WITH_BASISIMPORTER` --- Build the @ref Trade::BasisImporter "BasisImporter" + plugin. - `WITH_DDSIMPORTER` --- Build the @ref Trade::DdsImporter "DdsImporter" plugin. - `WITH_DEVILIMAGEIMPORTER` --- Build the diff --git a/doc/changelog-plugins.dox b/doc/changelog-plugins.dox index 176e6fbfb..e8b737072 100644 --- a/doc/changelog-plugins.dox +++ b/doc/changelog-plugins.dox @@ -36,6 +36,8 @@ namespace Magnum { - New @ref Audio::DrMp3Importer "DrMp3AudioImporter" plugin for importing MP3 files (see [mosra/magnum-plugins#60](https://github.com/mosra/magnum-plugins/pull/60)) +- New @ref Trade::BasisImporter "BasisImporter" plugin for importing + Basis files (see [mosra/magnum-plugins#62](https://github.com/mosra/magnum-plugins/pull/62)) @subsection changelog-plugins-latest-changes Changes and improvements diff --git a/doc/cmake-plugins.dox b/doc/cmake-plugins.dox index 2d1b71349..6be3192fd 100644 --- a/doc/cmake-plugins.dox +++ b/doc/cmake-plugins.dox @@ -72,6 +72,7 @@ This command tries to find Magnum plugins and then defines: This command will not try to find any actual plugin. The plugins are: - `AssimpImporter` --- @ref Trade::AssimpImporter "AssimpImporter" plugin +- `BasisImporter` --- @ref Trade::BasisImporter "BasisImporter" plugin - `DdsImporter` --- @ref Trade::DdsImporter "DdsImporter" plugin - `DevIlImageImporter` --- @ref Trade::DevIlImageImporter "DevIlImageImporter" plugin @@ -143,6 +144,9 @@ usage documentation. - [FindAssimp.cmake](https://github.com/mosra/magnum-plugins/blob/master/modules/FindAssimp.cmake) --- CMake module for finding Assimp. Copy this to your module directory if you want to find and link to @ref Trade::AssimpImporter. +- [FindBasisUniversal.cmake](https://github.com/mosra/magnum-plugins/blob/master/modules/FindBasisUniversal.cmake) + --- CMake module for finding basis universal sources. Copy this to your module directory if + you want to find and link to @ref Trade::BasisImporter. - [FindDevIL.cmake](https://github.com/mosra/magnum-plugins/blob/master/modules/FindDevIL.cmake) --- CMake module for finding DevIL. This is a forked version of the upstream module that doesn't attempt to find the often not distributed ILUT library. diff --git a/doc/credits.dox b/doc/credits.dox index ed37ec0d9..528f2451e 100644 --- a/doc/credits.dox +++ b/doc/credits.dox @@ -47,6 +47,7 @@ namespace Magnum { fixes for @ref Trade::AssimpImporter "AssimpImporter" workarounds - **Jonathan Hale** ([\@Squareys](https://github.com/Squareys)) --- @ref Trade::AssimpImporter "AssimpImporter", + @ref Trade::BasisImporter "BasisImporter", @ref Trade::DdsImporter "DdsImporter" and @ref Audio::StbVorbisImporter "StbVorbisAudioImporter" plugins, improvements to @ref Trade::TinyGltfImporter "TinyGltfImporter" diff --git a/doc/snippets/CMakeLists.txt b/doc/snippets/CMakeLists.txt new file mode 100644 index 000000000..544aaab55 --- /dev/null +++ b/doc/snippets/CMakeLists.txt @@ -0,0 +1,51 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 +# Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +find_package(Corrade REQUIRED PluginManager) + +# On MSVC remove /W3, as we are replacing it with /W4 +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") + string(REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") +endif() + +set_directory_properties(PROPERTIES + CORRADE_CXX_STANDARD 11 + CORRADE_USE_PEDANTIC_FLAGS ON) + +# Emscripten needs special flag to use WebGL 2 +if(CORRADE_TARGET_EMSCRIPTEN AND NOT TARGET_GLES2) + # TODO: give me INTERFACE_LINK_OPTIONS or something, please + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_WEBGL2=1") +endif() + +if(WITH_BASISIMPORTER) + add_library(snippets-BasisImporter STATIC + MagnumPluginsBasisImporter.cpp) + if(BUILD_PLUGINS_STATIC) + target_link_libraries(snippets-BasisImporter PRIVATE BasisImporter) + endif() + target_link_libraries(snippets-BasisImporter PRIVATE Corrade::PluginManager) + set_target_properties(snippets-BasisImporter PROPERTIES FOLDER "Magnum/doc/snippets") +endif() diff --git a/doc/snippets/MagnumPluginsBasisImporter.cpp b/doc/snippets/MagnumPluginsBasisImporter.cpp new file mode 100644 index 000000000..6fe9e1b0f --- /dev/null +++ b/doc/snippets/MagnumPluginsBasisImporter.cpp @@ -0,0 +1,42 @@ +#include +#include + +#include + +#ifdef __has_include +#if __has_include() +/* No need to do this if you use CMake */ +#include +#endif +#endif + +using namespace Magnum; + +int main() { + +{ +PluginManager::Manager manager; +/* [basis-target-format-suffix] */ + /* Choose Etc2 target format */ + Containers::Pointer importerEtc2 = + manager.instantiate("BasisImporterEtc2"); + + /* Choose Bc5 target format */ + Containers::Pointer importerBc5 = + manager.instantiate("BasisImporterBc5"); +/* [basis-target-format-suffix] */ +} + +{ +PluginManager::Manager manager; +/* [basis-target-format-config] */ + /* Chooses default Etc2 target format */ + Containers::Pointer importer = + manager.instantiate("BasisImporter"); + + /* Change to Bc5 */ + importer->configuration().setValue("format", "Bc5"); +/* [basis-target-format-config] */ +} + +} diff --git a/doc/snippets/configure.h.cmake b/doc/snippets/configure.h.cmake new file mode 100644 index 000000000..9dd594138 --- /dev/null +++ b/doc/snippets/configure.h.cmake @@ -0,0 +1,27 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DIR}" +#define SNIPPETS_DIR "${SNIPPETS_DIR}" diff --git a/modules/FindMagnumPlugins.cmake b/modules/FindMagnumPlugins.cmake index 0211725ae..3f51d49a5 100644 --- a/modules/FindMagnumPlugins.cmake +++ b/modules/FindMagnumPlugins.cmake @@ -13,6 +13,7 @@ # This command will not try to find any actual plugin. The plugins are: # # AssimpImporter - Assimp importer +# BasisImporter - Basis importer # DdsImporter - DDS importer # DevIlImageImporter - Image importer using DevIL # DrFlacAudioImporter - FLAC audio importer using dr_flac @@ -69,6 +70,7 @@ # # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 # Vladimír Vondruš +# Copyright © 2019 Jonathan Hale # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -121,7 +123,7 @@ mark_as_advanced(MAGNUMPLUGINS_INCLUDE_DIR) # components from other repositories) set(_MAGNUMPLUGINS_LIBRARY_COMPONENT_LIST OpenDdl) set(_MAGNUMPLUGINS_PLUGIN_COMPONENT_LIST - AssimpImporter DdsImporter DevIlImageImporter + AssimpImporter BasisImporter DdsImporter DevIlImageImporter DrFlacAudioImporter DrMp3AudioImporter DrWavAudioImporter Faad2AudioImporter FreeTypeFont HarfBuzzFont JpegImageConverter JpegImporter MiniExrImageConverter OpenGexImporter PngImageConverter PngImporter @@ -271,6 +273,12 @@ foreach(_component ${MagnumPlugins_FIND_COMPONENTS}) set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY INTERFACE_LINK_LIBRARIES Assimp::Assimp) + # BasisImporter plugin dependencies + if(_component STREQUAL BasisImporter) + find_package(BasisUniversal) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES BasisUniversal::Transcoder) + # DdsImporter has no dependencies # DevIlImageImporter plugin dependencies diff --git a/src/MagnumExternal/CMakeLists.txt b/src/MagnumExternal/CMakeLists.txt index 3061fed79..136cb51da 100644 --- a/src/MagnumExternal/CMakeLists.txt +++ b/src/MagnumExternal/CMakeLists.txt @@ -1,4 +1,4 @@ -# +# # This file is part of Magnum. # # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 diff --git a/src/MagnumPlugins/BasisImporter/BasisImporter.conf b/src/MagnumPlugins/BasisImporter/BasisImporter.conf new file mode 100644 index 000000000..52af06830 --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/BasisImporter.conf @@ -0,0 +1,17 @@ +provides=BasisImporterEtc1 +provides=BasisImporterEtc2 +provides=BasisImporterBc1 +provides=BasisImporterBc3 +provides=BasisImporterBc4 +provides=BasisImporterBc5 +provides=BasisImporterBc7M6OpaqueOnly +provides=BasisImporterPvrtc1_4OpaqueOnly + +# [configuration] +[configuration] + +# No format is specified by default and you have to choose one either +# by changing this value or by loading the plugin under an alias. See +# class documentation for more information. +format= +# [configuration] diff --git a/src/MagnumPlugins/BasisImporter/BasisImporter.cpp b/src/MagnumPlugins/BasisImporter/BasisImporter.cpp new file mode 100644 index 000000000..9c19c6a8c --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/BasisImporter.cpp @@ -0,0 +1,260 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + Copyright © 2019 Jonathan Hale + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNETCION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "BasisImporter.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace Magnum { namespace Trade { namespace { + +/* Map BasisTranscodingType to Magnum::CompressedPixelFormat */ +CompressedPixelFormat textureFormat(BasisTranscodingType type, bool hasAlpha) { + switch(type) { + case BasisTranscodingType::Etc1: + case BasisTranscodingType::Etc2: + return (hasAlpha) ? CompressedPixelFormat::Etc2RGBA8Unorm + : CompressedPixelFormat::Etc2RGB8Unorm; + case BasisTranscodingType::Bc1: + return (hasAlpha) ? CompressedPixelFormat::Bc1RGBAUnorm + : CompressedPixelFormat::Bc1RGBUnorm; + case BasisTranscodingType::Bc3: + return CompressedPixelFormat::Bc3RGBAUnorm; + case BasisTranscodingType::Bc4: + return CompressedPixelFormat::Bc4RUnorm; + case BasisTranscodingType::Bc5: + return CompressedPixelFormat::Bc5RGUnorm; + case BasisTranscodingType::Bc7M6OpaqueOnly: + return CompressedPixelFormat::Bc7RGBAUnorm; + case BasisTranscodingType::Pvrtc1_4OpaqueOnly: + return CompressedPixelFormat::PvrtcRGB4bppUnorm; + default: + CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ + } +} + +const char* FormatNames[]{ + "Etc1", "Etc2", "Bc1", "Bc3", "Bc4", "Bc5", + "Bc7M6OpaqueOnly", "Pvrtc1_4OpaqueOnly" +}; + +constexpr basist::transcoder_texture_format TranscoderTextureFormat[] = { + basist::transcoder_texture_format::cTFETC1, + basist::transcoder_texture_format::cTFETC2, + basist::transcoder_texture_format::cTFBC1, + basist::transcoder_texture_format::cTFBC3, + basist::transcoder_texture_format::cTFBC4, + basist::transcoder_texture_format::cTFBC5, + basist::transcoder_texture_format::cTFBC7_M6_OPAQUE_ONLY, + basist::transcoder_texture_format::cTFPVRTC1_4_OPAQUE_ONLY +}; + +}}} + +namespace Corrade { namespace Utility { + +/* Configuration value implementation for BasisTranscodingType */ +template<> struct ConfigurationValue { + + static std::string toString( + const Magnum::Trade::BasisTranscodingType& value, + ConfigurationValueFlags) + { + #define _c(value) case Magnum::Trade::BasisTranscodingType::value: return #value; + switch(value) { + _c(Etc1) + _c(Etc2) + _c(Bc1) + _c(Bc3) + _c(Bc4) + _c(Bc5) + _c(Bc7M6OpaqueOnly) + _c(Pvrtc1_4OpaqueOnly) + } + #undef _c + + return ""; + } + + static Magnum::Trade::BasisTranscodingType fromString( + const std::string& value, ConfigurationValueFlags) + { + Magnum::Int i = 0; + for(const char* name: Magnum::Trade::FormatNames) { + if(value == name) return Magnum::Trade::BasisTranscodingType(i); + ++i; + } + + return Magnum::Trade::BasisTranscodingType(-1); + } +}; + +}} + +namespace Magnum { namespace Trade { + +struct BasisImporter::State { + /* There is only this type of codebook */ + basist::etc1_global_selector_codebook _codebook; + basist::basisu_transcoder _transcoder{&_codebook}; + + explicit State(): _codebook(basist::g_global_selector_cb_size, + basist::g_global_selector_cb) {} +}; + +void BasisImporter::initialize() { + basist::basisu_transcoder_init(); +} + +BasisImporter::BasisImporter() = default; + +BasisImporter::BasisImporter(PluginManager::AbstractManager& manager, const std::string& plugin): AbstractImporter{manager, plugin} { + /* Initializes codebook */ + _state.reset(new State); + + /* Set format configuration from plugin alias */ + if(Corrade::Utility::String::beginsWith(plugin, "BasisImporter")) { + + /* Has type prefix */ + if(plugin.length() > 13) { + /* We can assume the substring results in a valid value + as the plugin conf limits it to known suffixes */ + configuration().setValue("format", plugin.substr(13)); + } + } +} + +BasisImporter::~BasisImporter() = default; + +auto BasisImporter::doFeatures() const -> Features { return Feature::OpenData; } + +bool BasisImporter::doIsOpened() const { return _in; } + +void BasisImporter::doClose() { _in = nullptr; } + +void BasisImporter::doOpenData(const Containers::ArrayView data) { + /* Because here we're copying the data and using the _in to check if file + is opened, having them nullptr would mean openData() would fail without + any error message. It's not possible to do this check on the importer + side, because empty file is valid in some formats (OBJ or glTF). We also + can't do the full import here because then doImage2D() would need to + copy the imported data instead anyway (and the uncompressed size is much + larger). This way it'll also work nicely with a future openMemory(). */ + if(data.empty()) { + Error{} << "Trade::BasisImporter::openData(): the file is empty"; + return; + } + + if(!_state->_transcoder.validate_header(data.data(), data.size())) { + Error() << "Trade::BasisImporter::openData(): invalid header"; + return; + } + + if(!_state->_transcoder.start_transcoding(data.data(), data.size())) { + Error() << "Trade::BasisImporter::openData(): bad basis file"; + return; + } + + _in = Containers::Array(data.size()); + std::copy(data.begin(), data.end(), _in.begin()); +} + +UnsignedInt BasisImporter::doImage2DCount() const { + return _state->_transcoder.get_total_images(_in.data(), _in.size()); +} + +Containers::Optional BasisImporter::doImage2D(UnsignedInt index) { + const UnsignedInt level = 0; + + const std::string targetFormatStr = configuration().value("format"); + if(targetFormatStr.empty()) { + Error() << "Trade::BasisImporter::image2D(): no format to transcode " + "to was specified. Either load the plugin via one of its BasisImporterEtc1, ... " + "aliases, or set the format explicitly via plugin configuration."; + return Containers::NullOpt; + } + + const BasisTranscodingType targetFormat = + configuration().value("format"); + if(Int(targetFormat) == -1) { + Error() << "Trade::BasisImporter::image2D(): invalid transcoding target format" + << targetFormatStr.c_str() << Debug::nospace << ", expected to be one of:" + << "Etc1, Etc2, Bc1, Bc3, Bc4, Bc5, Bc7M6OpaqueOnly, Pvrtc1_4OpaqueOnly"; + return Containers::NullOpt; + } + const basist::transcoder_texture_format format = + TranscoderTextureFormat[Int(targetFormat)]; + const UnsignedInt bytes_per_block = basis_get_bytes_per_block(format); + + basist::basisu_image_info info; + if (!_state->_transcoder.get_image_info(_in.data(), _in.size(), info, index)) { + Error{} << "Trade::BasisImporter::image2D(): unable to get image info"; + return Containers::NullOpt; + } + const bool hasAlpha = info.m_alpha_flag; + + UnsignedInt origWidth, origHeight, totalBlocks; + if (!_state->_transcoder.get_image_level_desc(_in.data(), _in.size(), index, + level, origWidth, origHeight, totalBlocks)) + { + Error{} << "Trade::BasisImporter::image2D(): unable to retrieve mip level description"; + return Containers::NullOpt; + } + + const UnsignedInt requiredSize = totalBlocks*bytes_per_block; + Containers::Array dest{Containers::DefaultInit, requiredSize}; + const UnsignedInt status = _state->_transcoder.transcode_image_level( + _in.data(), _in.size(), index, level, dest.data(), dest.size()/bytes_per_block, + static_cast(format)); + if(!status) { + Error{} << "Trade::BasisImporter::image2D(): transcoding failed"; + return Containers::NullOpt; + } + + return Trade::ImageData2D(textureFormat(targetFormat, hasAlpha), + Vector2i{Int(origWidth), Int(origHeight)}, + std::move(dest)); +} + +void BasisImporter::setTargetFormat(BasisTranscodingType format) { + configuration().setValue("format", format); +} + +BasisTranscodingType BasisImporter::targetFormat() const { + return configuration().value("format"); +} + +}} + +CORRADE_PLUGIN_REGISTER(BasisImporter, Magnum::Trade::BasisImporter, + "cz.mosra.magnum.Trade.AbstractImporter/0.3") diff --git a/src/MagnumPlugins/BasisImporter/BasisImporter.h b/src/MagnumPlugins/BasisImporter/BasisImporter.h new file mode 100644 index 000000000..78a589630 --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/BasisImporter.h @@ -0,0 +1,221 @@ +#ifndef Magnum_Trade_BasisImporter_h +#define Magnum_Trade_BasisImporter_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + Copyright © 2019 Jonathan Hale + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNETCION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file +* @brief Class @ref Magnum::Trade::BasisImporter +*/ + +#include +#include + +#include "MagnumPlugins/BasisImporter/configure.h" + +#ifndef DOXYGEN_GENERATING_OUTPUT +#ifndef MAGNUM_BASISIMPORTER_BUILD_STATIC +#ifdef BasisImporter_EXPORTS + #define MAGNUM_BASISIMPORTER_EXPORT CORRADE_VISIBILITY_EXPORT +#else + #define MAGNUM_BASISIMPORTER_EXPORT CORRADE_VISIBILITY_IMPORT +#endif +#else +#define MAGNUM_BASISIMPORTER_EXPORT CORRADE_VISIBILITY_STATIC +#endif +#define MAGNUM_BASISIMPORTER_LOCAL CORRADE_VISIBILITY_LOCAL +#else +#define MAGNUM_BASISIMPORTER_EXPORT +#define MAGNUM_BASISIMPORTER_LOCAL +#endif + +namespace Magnum { namespace Trade { + +/** +@brief Type to transcode to +*/ +enum class BasisTranscodingType : Int { + /** + * ETC1 + * + * Loaded as @ref CompressedPixelFormat::Etc2RGB8Unorm or + * @ref CompressedPixelFormat::Etc2RGBA8Unorm if the image contains an + * alpha channel. + * + * This format is loaded like @ref Etc2, prefer it for potentially better quality. + */ + Etc1 = 0, + + /** + * ETC2 + * + * Loaded as @ref CompressedPixelFormat::Etc2RGB8Unorm or + * @ref CompressedPixelFormat::Etc2RGBA8Unorm if the image contains an + * alpha channel. + */ + Etc2 = 1, + + /** + * BC1 + * + * Loaded as @ref CompressedPixelFormat::Bc1RGBAUnorm or @ref CompressedPixelFormat::Bc1RGBUnorm + * if the image contains an alpha channel. + */ + Bc1 = 2, + + /** + * BC2 + * + * Loaded as @ref CompressedPixelFormat::Bc3RGBAUnorm. If the image does + * not contain an alpha channel, alpha will be set to opaque. + */ + Bc3 = 3, + + /** + * BC4 + * + * Loaded as @ref CompressedPixelFormat::Bc4RUnorm. + */ + Bc4 = 4, + + /** + * BC5 + * + * Loaded as @ref CompressedPixelFormat::Bc5RGUnorm. + */ + Bc5 = 5, + + /** + * BC7 mode 4 (opaque only) + * + * Loaded as @ref CompressedPixelFormat::Bc7RGBAUnorm, but with alpha + * values set to opaque. + */ + Bc7M6OpaqueOnly = 6, + + /** + * PVRTC1 4 bpp (opaque only) + * + * Loaded as @ref CompressedPixelFormat::PvrtcRGB4bppUnorm. If the image + * contains an alpha channel, it will be dropped. + */ + Pvrtc1_4OpaqueOnly = 7 +}; + +/** +@brief BASIS importer plugin + +@m_keywords{BasisImporterEct1 BasisImporterEtc2 BasisImporterBc1 BasisImporterBc3} +@m_keywords{BasisImporterBc4 BasisImporterBc5 BasisImporterBc7M6OpaqueOnly} +@m_keywords{BasisImporterPvrtc1_4OpaqueOnly} + +Supports Basis Universal (`*.basis`) compressed images by parsing and transcoding +files into an explicitly specified GPU format (see @ref Trade-BasisImporter-target-format). + +This plugin depends on the @ref Trade and [basis_universal](https://github.com/binomialLLC/basis_universal) +libraries and is built if `WITH_BASISIMPORTER` is enabled when building Magnum +Plugins. To use as a dynamic plugin, you need to load the @cpp "BasisImporter" @ce +plugin from `MAGNUM_PLUGINS_IMPORTER_DIR`. To use as a static plugin or as a +dependency of another plugin with CMake, you need to request the `BasisImporter` +component of the `MagnumPlugins` package and link to the `MagnumPlugins::BasisImporter` +target. See @ref building-plugins, @ref plugins for more information. + +This plugin provides `BasisImporter`, `BasisImporterEct1`, `BasisImporterEtc1`, +`BasisImporterEtc2`, `BasisImporterBc1`, `BasisImporterBc3`, `BasisImporterBc4`, +`BasisImporterBc5`, `BasisImporterBc7M6OpaqueOnly`, `BasisImporterPvrtc1_4OpaqueOnly`. + +@section Trade-BasisImporter-configuration Plugin-specific configuration + +Basis allows configuration of the format of loaded compressed data. +The full form of the configuration is shown below: + +@snippet MagnumPlugins/BasisImporter/BasisImporter.conf configuration + +@subsection Trade-BasisImporter-target-format Target format + +Basis is a compressed format that is *transcoded* into a compressed GPU format. With +BasisImporter, this format can be chosen in different ways: + +@snippet MagnumPluginsBasisImporter.cpp basis-target-format-suffix + +The list of valid suffixes is equivalent to enum value names in @ref BasisTranscodingType. + +If you want to be able to change the target format dynamically, you may want to +set the "format" configuration of the plugin: + +@snippet MagnumPluginsBasisImporter.cpp basis-target-format-config + +If you link to the plugin you may also use @ref BasisImporter::setTargetFormat(). + +@thirdparty This plugin makes use of the [Basis Universal GPU Texture Codec](https://github.com/BinomialLLC/basis_universal) + library, licensed under @m_class{m-label m-info} **Apache-2.0** + ([license text](https://opensource.org/licenses/Apache-2.0), + [choosealicense.com](https://choosealicense.com/licenses/apache-2.0/)). +*/ +class MAGNUM_BASISIMPORTER_EXPORT BasisImporter: public AbstractImporter { + public: + /** @brief Initialize basis transcoder */ + static void initialize(); + + /** @brief Default constructor */ + explicit BasisImporter(); + + /** @brief Plugin manager constructor */ + explicit BasisImporter(PluginManager::AbstractManager& manager, const std::string& plugin); + + /** + * @brief Set the importers target format + * @param format The format to transcode Basis files to + */ + void setTargetFormat(BasisTranscodingType format); + + /** + * @brief The importers target format + * @param format The format to transcode Basis files to + * + * See @ref basisimporter-target-format. + */ + BasisTranscodingType targetFormat() const; + + ~BasisImporter(); + + private: + struct State; + + MAGNUM_BASISIMPORTER_LOCAL Features doFeatures() const override; + MAGNUM_BASISIMPORTER_LOCAL bool doIsOpened() const override; + MAGNUM_BASISIMPORTER_LOCAL void doClose() override; + MAGNUM_BASISIMPORTER_LOCAL void doOpenData(Containers::ArrayView data) override; + + MAGNUM_BASISIMPORTER_LOCAL UnsignedInt doImage2DCount() const override; + MAGNUM_BASISIMPORTER_LOCAL Containers::Optional doImage2D(UnsignedInt id) override; + + Containers::Array _in; + Containers::Pointer _state; +}; + +}} + +#endif diff --git a/src/MagnumPlugins/BasisImporter/CMakeLists.txt b/src/MagnumPlugins/BasisImporter/CMakeLists.txt new file mode 100644 index 000000000..be7fcf139 --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/CMakeLists.txt @@ -0,0 +1,69 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 +# Vladimír Vondruš +# Copyright © 2019 Jonathan Hale +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +find_package(Magnum REQUIRED Trade) +find_package(BasisUniversal REQUIRED Transcoder) + +if(BUILD_PLUGINS_STATIC) + set(MAGNUM_BASISIMPORTER_BUILD_STATIC 1) +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) + +# BasisImporter plugin +add_plugin(BasisImporter + "${MAGNUM_PLUGINS_IMPORTER_DEBUG_BINARY_INSTALL_DIR};${MAGNUM_PLUGINS_IMPORTER_DEBUG_LIBRARY_INSTALL_DIR}" + "${MAGNUM_PLUGINS_IMPORTER_RELEASE_BINARY_INSTALL_DIR};${MAGNUM_PLUGINS_IMPORTER_RELEASE_LIBRARY_INSTALL_DIR}" + BasisImporter.conf + BasisImporter.cpp + BasisImporter.h) +if(BUILD_PLUGINS_STATIC AND BUILD_STATIC_PIC) + set_target_properties(BasisImporter PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() +target_include_directories(BasisImporter + PUBLIC + ${PROJECT_SOURCE_DIR}/src + ${PROJECT_BINARY_DIR}/src) +target_link_libraries(BasisImporter + PUBLIC Magnum::Trade + PRIVATE BasisUniversal::Transcoder) + +install(FILES BasisImporter.h ${CMAKE_CURRENT_BINARY_DIR}/configure.h + DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/BasisImporter) + +# Automatic static plugin import +if(BUILD_PLUGINS_STATIC) + install(FILES importStaticPlugin.cpp DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/BasisImporter) + target_sources(BasisImporter INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/importStaticPlugin.cpp) +endif() + +if(BUILD_TESTS) + add_subdirectory(Test) +endif() + +# MagnumPlugins BasisImporter target alias for superprojects +add_library(MagnumPlugins::BasisImporter ALIAS BasisImporter) diff --git a/src/MagnumPlugins/BasisImporter/Test/BasisImporterTest.cpp b/src/MagnumPlugins/BasisImporter/Test/BasisImporterTest.cpp new file mode 100644 index 000000000..3afb875b8 --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/Test/BasisImporterTest.cpp @@ -0,0 +1,315 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + Copyright © 2019 Jonathan Hale + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNETCION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "configure.h" + +namespace Magnum { namespace Trade { namespace Test { namespace { + +struct BasisImporterTest: TestSuite::Tester { + explicit BasisImporterTest(); + + void empty(); + void invalid(); + void unconfigured(); + void invalidConfiguredFormat(); + void fileTooShort(); + void transcodingFailure(); + + void openTwice(); + + void rgb(); + void rgba(); + void importMultipleFormats(); + + /* Explicitly forbid system-wide plugin dependencies */ + PluginManager::Manager _manager{"nonexistent"}; +}; + +constexpr struct { + const char* file; + const char* fileAlpha; + const char* suffix; + const CompressedPixelFormat expectedFormat; + const CompressedPixelFormat expectedFormatAlpha; + const Vector2i expectedSize; +} FormatData[] { + { + "rgb_2_images.basis", + "rgba_2_images.basis", + "Etc1", + CompressedPixelFormat::Etc2RGB8Unorm, + CompressedPixelFormat::Etc2RGBA8Unorm, + {63, 27} + }, { + "rgb_2_images.basis", + "rgba_2_images.basis", + "Etc2", + CompressedPixelFormat::Etc2RGB8Unorm, + CompressedPixelFormat::Etc2RGBA8Unorm, + {63, 27} + }, { + "rgb_2_images.basis", + "rgba_2_images.basis", + "Bc1", + CompressedPixelFormat::Bc1RGBUnorm, + CompressedPixelFormat::Bc1RGBAUnorm, + {63, 27} + }, { + "rgb_2_images.basis", + "rgba_2_images.basis", + "Bc3", + CompressedPixelFormat::Bc3RGBAUnorm, + CompressedPixelFormat::Bc3RGBAUnorm, + {63, 27} + }, { + "rgb_2_images.basis", + "rgba_2_images.basis", + "Bc4", + CompressedPixelFormat::Bc4RUnorm, + CompressedPixelFormat::Bc4RUnorm, + {63, 27} + }, { + "rgb_2_images.basis", + "rgba_2_images.basis", + "Bc5", + CompressedPixelFormat::Bc5RGUnorm, + CompressedPixelFormat::Bc5RGUnorm, + {63, 27} + }, { + "rgb_2_images.basis", + "rgba_2_images.basis", + "Bc7M6OpaqueOnly", + CompressedPixelFormat::Bc7RGBAUnorm, + CompressedPixelFormat::Bc7RGBAUnorm, + {63, 27} + }, { + "rgb_2_images_pow2.basis", + "rgba_2_images_pow2.basis", + "Pvrtc1_4OpaqueOnly", + CompressedPixelFormat::PvrtcRGB4bppUnorm, + CompressedPixelFormat::PvrtcRGB4bppUnorm, + {64, 32} + } +}; + +BasisImporterTest::BasisImporterTest() { + addTests({&BasisImporterTest::empty, + &BasisImporterTest::invalid, + &BasisImporterTest::unconfigured, + &BasisImporterTest::invalidConfiguredFormat, + &BasisImporterTest::fileTooShort, + &BasisImporterTest::transcodingFailure, + + &BasisImporterTest::openTwice, + &BasisImporterTest::importMultipleFormats}); + + addInstancedTests({&BasisImporterTest::rgb, + &BasisImporterTest::rgba}, + Containers::arraySize(FormatData)); + + /* Load the plugin directly from the build tree. Otherwise it's static and + already loaded. */ + #ifdef BASISIMPORTER_PLUGIN_FILENAME + CORRADE_INTERNAL_ASSERT(_manager.load(BASISIMPORTER_PLUGIN_FILENAME) & PluginManager::LoadState::Loaded); + #endif +} + +void BasisImporterTest::empty() { + Containers::Pointer importer = _manager.instantiate("BasisImporter"); + + std::ostringstream out; + Error redirectError{&out}; + char a{}; + /* Explicitly checking non-null but empty view */ + CORRADE_VERIFY(!importer->openData({&a, 0})); + CORRADE_COMPARE(out.str(), "Trade::BasisImporter::openData(): the file is empty\n"); +} + +void BasisImporterTest::invalid() { + Containers::Pointer importer = _manager.instantiate("BasisImporter"); + std::ostringstream out; + Error redirectError{&out}; + CORRADE_VERIFY(!importer->openData("NotABasisFile")); + + CORRADE_COMPARE(out.str(), "Trade::BasisImporter::openData(): invalid header\n"); +} + +void BasisImporterTest::unconfigured() { + Containers::Pointer importer = _manager.instantiate("BasisImporter"); + std::ostringstream out; + Error redirectError{&out}; + + CORRADE_VERIFY(importer->openFile( + Utility::Directory::join(BASISIMPORTER_TEST_DIR, "rgb.basis"))); + CORRADE_VERIFY(!importer->image2D(0)); + + CORRADE_COMPARE(out.str(), "Trade::BasisImporter::image2D(): no format to transcode " + "to was specified. Either load the plugin via one of its BasisImporterEtc1, ... " + "aliases, or set the format explicitly via plugin configuration.\n"); +} + +void BasisImporterTest::invalidConfiguredFormat() { + Containers::Pointer importer = _manager.instantiate("BasisImporter"); + CORRADE_VERIFY(importer->openFile( + Utility::Directory::join(BASISIMPORTER_TEST_DIR, "rgb.basis"))); + + std::ostringstream out; + Error redirectError{&out}; + importer->configuration().setValue("format", "Banana"); + CORRADE_VERIFY(!importer->image2D(0)); + + CORRADE_COMPARE(out.str(), "Trade::BasisImporter::image2D(): invalid transcoding target format Banana, expected to be one of: Etc1, Etc2, Bc1, Bc3, Bc4, Bc5, Bc7M6OpaqueOnly, Pvrtc1_4OpaqueOnly\n"); +} + +void BasisImporterTest::fileTooShort() { + Containers::Pointer importer = _manager.instantiate("BasisImporter"); + auto basisData = Utility::Directory::read( + Utility::Directory::join(BASISIMPORTER_TEST_DIR, "rgb.basis")); + + std::ostringstream out; + Error redirectError{&out}; + + CORRADE_VERIFY(!importer->openData(basisData.prefix(64))); + + /* Corrupt the header */ + basisData[100] = 100; + CORRADE_VERIFY(!importer->openData(basisData)); + + CORRADE_COMPARE(out.str(), "Trade::BasisImporter::openData(): invalid header\n" + "Trade::BasisImporter::openData(): bad basis file\n"); +} + + +void BasisImporterTest::openTwice() { + Containers::Pointer importer = _manager.instantiate("BasisImporter"); + CORRADE_VERIFY(importer->openFile( + Utility::Directory::join(BASISIMPORTER_TEST_DIR, "rgb.basis"))); + CORRADE_VERIFY(importer->openFile( + Utility::Directory::join(BASISIMPORTER_TEST_DIR, "rgb.basis"))); + + /* Shouldn't crash, leak or anything */ +} + +void BasisImporterTest::transcodingFailure() { + Containers::Pointer importer = _manager.instantiate("BasisImporter"); + CORRADE_VERIFY(importer->openFile(Utility::Directory::join(BASISIMPORTER_TEST_DIR, "rgb.basis"))); + + std::ostringstream out; + Error redirectError{&out}; + + /* PVRTC1 requires power of 2 image dimensions, but rgb.basis is 27x63, hence + basis will fail during transcoding. */ + importer->configuration().setValue("format", "Pvrtc1_4OpaqueOnly"); + Containers::Optional image = importer->image2D(0); + CORRADE_VERIFY(!image); + CORRADE_COMPARE(out.str(), "Trade::BasisImporter::image2D(): transcoding failed\n"); +} + +void BasisImporterTest::rgb() { + auto& formatData = FormatData[testCaseInstanceId()]; + const std::string pluginName = "BasisImporter" + std::string(formatData.suffix); + setTestCaseDescription(formatData.suffix); + + Containers::Pointer importer = _manager.instantiate(pluginName); + CORRADE_VERIFY(importer); + CORRADE_COMPARE(importer->configuration().value("format"), + formatData.suffix); + CORRADE_VERIFY(importer->openFile(Utility::Directory::join(BASISIMPORTER_TEST_DIR, + formatData.file))); + + /* Verify that everything is working the same way on second use */ + Containers::Optional image = importer->image2D(0); + CORRADE_VERIFY(image); + CORRADE_COMPARE(image->compressedFormat(), formatData.expectedFormat); + CORRADE_COMPARE(image->size(), formatData.expectedSize); + + /* Verify that the 90° rotated second image can be loaded also */ + image = importer->image2D(1); + CORRADE_VERIFY(image); + CORRADE_COMPARE(image->compressedFormat(), formatData.expectedFormat); + CORRADE_COMPARE(image->size(), formatData.expectedSize.flipped()); +} + +void BasisImporterTest::rgba() { + auto& formatData = FormatData[testCaseInstanceId()]; + const std::string pluginName = "BasisImporter" + std::string(formatData.suffix); + setTestCaseDescription(formatData.suffix); + + Containers::Pointer importer = _manager.instantiate(pluginName); + CORRADE_VERIFY(importer); + CORRADE_COMPARE(importer->configuration().value("format"), + formatData.suffix); + CORRADE_VERIFY(importer->openFile(Utility::Directory::join(BASISIMPORTER_TEST_DIR, + formatData.fileAlpha))); + + /* Verify that everything is working the same way on second use */ + Containers::Optional image = importer->image2D(0); + CORRADE_VERIFY(image); + CORRADE_COMPARE(image->compressedFormat(), formatData.expectedFormatAlpha); + CORRADE_COMPARE(image->size(), formatData.expectedSize); + + /* Verify that the 90° rotated second image can be loaded also */ + image = importer->image2D(1); + CORRADE_VERIFY(image); + CORRADE_COMPARE(image->compressedFormat(), formatData.expectedFormatAlpha); + CORRADE_COMPARE(image->size(), formatData.expectedSize.flipped()); +} + +void BasisImporterTest::importMultipleFormats() { + Containers::Pointer importer = _manager.instantiate("BasisImporter"); + CORRADE_VERIFY(importer->openFile(Utility::Directory::join(BASISIMPORTER_TEST_DIR, "rgb.basis"))); + + /* Verify that everything is working the same way on second use */ + { + importer->configuration().setValue("format", "Etc2"); + + Containers::Optional image = importer->image2D(0); + CORRADE_VERIFY(image); + CORRADE_COMPARE(image->compressedFormat(), CompressedPixelFormat::Etc2RGB8Unorm); + CORRADE_COMPARE(image->size(), (Vector2i{63, 27})); + } { + importer->configuration().setValue("format", "Bc1"); + + Containers::Optional image = importer->image2D(0); + CORRADE_VERIFY(image); + CORRADE_COMPARE(image->compressedFormat(), CompressedPixelFormat::Bc1RGBUnorm); + CORRADE_COMPARE(image->size(), (Vector2i{63, 27})); + } +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Trade::Test::BasisImporterTest) diff --git a/src/MagnumPlugins/BasisImporter/Test/CMakeLists.txt b/src/MagnumPlugins/BasisImporter/Test/CMakeLists.txt new file mode 100644 index 000000000..aa008aa77 --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/Test/CMakeLists.txt @@ -0,0 +1,72 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 +# Vladimír Vondruš +# Copyright © 2019 Jonathan Hale +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +# CMake before 3.8 has broken $ expressions for iOS (see +# https://gitlab.kitware.com/cmake/cmake/merge_requests/404) and since Corrade +# doesn't support dynamic plugins on iOS, this sorta works around that. Should +# be revisited when updating Travis to newer Xcode (current has CMake 3.6). + +if(CORRADE_TARGET_EMSCRIPTEN OR CORRADE_TARGET_ANDROID) + set(BASISIMPORTER_TEST_DIR ".") +else() + set(BASISIMPORTER_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +if(NOT BUILD_PLUGINS_STATIC) + set(BASISIMPORTER_PLUGIN_FILENAME $) + + # First replace ${} variables, then $<> generator expressions + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h.in) + file(GENERATE OUTPUT $/configure.h + INPUT ${CMAKE_CURRENT_BINARY_DIR}/configure.h.in) +else() + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) +endif() + +corrade_add_test(BasisImporterTest BasisImporterTest.cpp + LIBRARIES Magnum::Trade + FILES + rgb.basis + rgb_2_images.basis + rgb_2_images_pow2.basis + rgba_2_images.basis + rgba_2_images_pow2.basis) +if(NOT BUILD_PLUGINS_STATIC) + target_include_directories(BasisImporterTest PRIVATE + $ + # Need to include the importer's header for the + # ConfigurationValue specification. No need to link + # when plugin is dynamic + ${PROJECT_BINARY_DIR}/src + ${PROJECT_SOURCE_DIR}/src) +else() + target_include_directories(BasisImporterTest PRIVATE + ${CMAKE_CURRENT_BINARY_DIR}) + target_link_libraries(BasisImporterTest PRIVATE BasisImporter) +endif() +set_target_properties(BasisImporterTest PROPERTIES FOLDER "MagnumPlugins/BasisImporter/Test") diff --git a/src/MagnumPlugins/BasisImporter/Test/README.md b/src/MagnumPlugins/BasisImporter/Test/README.md new file mode 100644 index 000000000..bb2b7979c --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/Test/README.md @@ -0,0 +1,27 @@ +Creating input Basis files +========================== + +The images were converted from central cutouts from `ambient-texture.tga` and `alpha-mask1.0.tga` +from the [Magnum Shaders test files](https://github.com/mosra/magnum/tree/master/src/Magnum/Shaders/Test/TestFiles). + +- `rgb_63x27.png`, +- `rgba_64x27.png`, +- `rgb_27x63.png`, +- `rgba_27x64.png`, +- `rgb_32x64.png`, +- `rgb_64x32.png` + +using the official basis universal +[conversion tool](https://github.com/BinomialLLC/basis_universal/#command-line-compression-tool). + +To convert, run the following commands: +```sh +basisu rgb_63x27.png -output_file rgb.basis + +basisu rgb_63x27.png rgb_27x63.png -output_file rgb_2_images.basis +basisu rgba_63x27.png rgba_27x63.png -output_file rgba_2_images.basis -force_alpha + +# Required for PVRTC1 target, which requires pow2 dimensions +basisu rgb_64x32.png rgb_32x64.png -output_file rgb_2_images_pow2.basis +basisu rgba_64x32.png rgba_32x64.png -output_file rgba_2_images_pow2.basis -force_alpha +``` diff --git a/src/MagnumPlugins/BasisImporter/Test/configure.h.cmake b/src/MagnumPlugins/BasisImporter/Test/configure.h.cmake new file mode 100644 index 000000000..e50665894 --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/Test/configure.h.cmake @@ -0,0 +1,28 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + Copyright © 2019 Jonathan Hale + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#cmakedefine BASISIMPORTER_PLUGIN_FILENAME "${BASISIMPORTER_PLUGIN_FILENAME}" +#define BASISIMPORTER_TEST_DIR "${BASISIMPORTER_TEST_DIR}" diff --git a/src/MagnumPlugins/BasisImporter/Test/rgb.basis b/src/MagnumPlugins/BasisImporter/Test/rgb.basis new file mode 100644 index 0000000000000000000000000000000000000000..49f3cdbee5cd48edab8ef402e23b64c6164c4225 GIT binary patch literal 390 zcmXSR5@zsaaGzz#$iQ$0L;w*O11TgR#E=5yg)lIPFzf&_d>9y5fC@c3=%2d z8gDN2;AHGz07^2jEXw5AyFE`qvXb$7&!m#&|8I+YUKOETk#S~`vV8H>Pf83*znFzV zPGw;5X!;-V#9?*=BLj=z(aSb!7cJ$uJ{Z|~1vD611vD}}fAsx(_@n6$8pF1=Pu(Lu zegFOc{~csx5|+2PUoz}>l3-+t`0KC+=)RW57tG2rlT@@#H=aNd)FpMixz zqG{{jNf*{|b)*8gMfp1Smm|E6EtrM~gF%!J=@FYjcFEiycXYx&K4{i9pbru@{ D?74hj literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/Test/rgb_27x63.png b/src/MagnumPlugins/BasisImporter/Test/rgb_27x63.png new file mode 100644 index 0000000000000000000000000000000000000000..0a26117a20e3dfd279b5ef2afd77831009188fc2 GIT binary patch literal 407 zcmV;I0cie-P)dhZ zBIjPbU7sP5T_oA*habD_%rYacZq^KAM7AYI&KW)958*M7O(_=a?-c=PwFgwI+A1a+ z+ltbhu?~F$veU`aY{ph0fI9+Y6e-GOyQc!^3yG|6B-SB-Rg)rxaAL7SI-zy;C4@Wd zNEF;)eIa-?(hc@zBt^6vYynMIWZYmg7#b#V_dvFcn$SA)n8&6V6ZPBnSo7IIdOdQ^ zrgi+ZI7B(t~ zO6UgD4>64Oqm6?-Dw30)8!W%O$j{{`M%mvONJ0toA-ZROYaod=<|QFh$=b)_!!BVo z2L<~*IS6aB1nVX1(Ajy8AgI}g05&5(40>#8v0tw*UrYx{QAz*+002ovPDHLkV1hWl Bto8r^ literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/Test/rgb_2_images.basis b/src/MagnumPlugins/BasisImporter/Test/rgb_2_images.basis new file mode 100644 index 0000000000000000000000000000000000000000..fe1ce218c2cd65cd7a81742566dba07548cc593c GIT binary patch literal 547 zcmXSR5@zsaND02i$iPtYfr)_uh!}uuG$6`Q4HSuGU{GYZ0c4aiF!%x$g#wwrXet@( z8KfBm7}yyW0TtK*CBN+f8z&8vUtcdfq4;kOtbslE^1^b>W8S5+Jt?#Fcve zXl4VW6C+CpvjPKyfPl@-9yZtY?hHyGO)O2PZrpty=o^wNIJMF}gKgW}|4Ud_cf9^% zGsF1g>rIy2)_D!x2{#w8DlxGLGO+-4IBr?-f3=N*2j3oE2?hm)ip3gd53{K$$n!FH z_?1lC&`>i)sPhsLo-SyUAw8x+eyLEC-ivbP(Dg$M2x~l!@WsZ3ae(w#245g%VG_7mqGx zzm&fDD~|7iA*aYDi6BNBp#Kv%z8OA^(|6wf9?h-DtA2d&3!Z=p+05faNQt zTMKeHntLS_wKlTMdNp7E&ys@RKYiiSth}u^yOb)Xarvyi!5LjF?3xhemcR`F+?=>B literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/Test/rgb_2_images_pow2.basis b/src/MagnumPlugins/BasisImporter/Test/rgb_2_images_pow2.basis new file mode 100644 index 0000000000000000000000000000000000000000..c22b35805249b98447be11402276600dea8beb8d GIT binary patch literal 521 zcmXSR5@zsa_`GQkBLjnZEE59*5HSGRXh4vm8YmLVz#zwP0mvw0U~mH}@&__~(Nr=x zFeoqxFmNzT1uC!rO75EuHckO3!2y&w3*^}Vg*7KCIEVmkVrzVGr(jb~wCU}5cba|{o0VNg;4>f&hH<0SkyiD&ku>5~IyRIKwp*)?;8 zv(o)v>p9)#Ub%RaU+EvSAR|y4gM*CoTm9ne%!N!`3>+K_>O~H(XyXvGG~jr^snDhs zRZ-5Gw;!>&I#niiD&P7qzWWKob-)`|>QZ!+)}Eke8yf*C0ohDO`Ci!3Y@6_TAN$)=W5K|;Odfay*WCcw}^X|+Q)tVkj$ev e`y7h~SFXN*%dQ)ngEi#--)LjG)5Mc{A_V|utFi|G literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/Test/rgb_32x64.png b/src/MagnumPlugins/BasisImporter/Test/rgb_32x64.png new file mode 100644 index 0000000000000000000000000000000000000000..4ab7b9777f8c0017733348efd8f7e48e9df83576 GIT binary patch literal 731 zcmV<10wn#3P)tM-Ya~#(MhhE4Ar`oeQb1y3L5v;3pP;caYHVnX@zH6ctr0tn zS}2eB2u2HyHiTe6KwJUYo!yza7A$TsG&;;(6X#b>a`XGnx#!$_=8EyjLkb^?_Des@ z@wa*#6as_*AwWd|Jixeexq8#b{(&_b8@)h{=Y`}RF@7L1&YfQc;LW7T=vXvx^E_}B zi_~U4jszDrNZ+-q|yL{03kpK0Eo`F1HR7UA$P(TK*ci<0)zk|fW*-^ zl5HhpZD<-4#7^uavft8Tn$HV9eKZ)Kh+=^Y33Ne2?XR%(p}Tz(f=RgaH3Lz)xa}%2|?~`3V33 N002ovPDHLkV1j;zM&JMd literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/Test/rgb_63x27.png b/src/MagnumPlugins/BasisImporter/Test/rgb_63x27.png new file mode 100644 index 0000000000000000000000000000000000000000..76505c75f6bd920a3f9d4267faaf3bf6fab3432d GIT binary patch literal 528 zcmV+r0`L8aP)A#C_WtbMB|<`!3)?1`E|7qYT`EK1z&@?$C-4K<*oaLCB;*U^Go-OhKtT{O zpsm3(@lO)ZyLI<=#v&lWY_T(Y;gsE{o#mb1Gw>5qd4R|@cws7`Jz(F7nM@JsL0(n5661Rd6pcEZSF#MzLYO2rF>B- z<%>!_d2L`g)@wp8oE|gGaYVTL8G0I{00Z^=H}MvlBaW9&7z!WWSJ*$O5d;ZqYoSve zd-*{^f8z*$y^VLf0bDG`VB;hHqW~4uor2h~w^ygz^*H?|_`dt*wU!^g{YhoM@kbm$ zZq=xDW{6*Wr@r2H4wIEm=c3cEURHT`Saq&ry=?k?h)i9bPz65v#P0QU-24W+DukJv SQEq|&0000A#C=FYuyuNwGKC^wQsG28?#f@qbi#1h-PjiPn^13|0WNo2d0uG$8+XcH(D zL=gq)CQ~#u^Q-$c_s-iw2rU<#Iag1_eb&Q!e&;#wIcJ!W={IMUge-jVnVigW`_4|% z5~QztM$d1F@JMouYME|oOcU@-(p=DpQ7t2eM@}Er3b(*E$~v(l*FtDtOP7Cd31Hw zY)TmMO+A`9Sa<-m5wmKz39JNcZh9PRIl2z$B4$y1whx$O5n%<74mCT{5(|i9C=`UI z=EP^HF*%eWt?*ECtnG=uCBkC~8Pp0{%<`m?hAEYV-rg#PTh5xxTBeN}6OtuD@KIuc zA+2y;Bjb8va}Cx5(`#@qH6TU^3|Dj18ii|=kYeGz(4n{hdOqXQZOTnBJXLxAf5u4xEx9l$kq0%C=#)7J=V5`7TSl?tWF zudoxN9-xr9b{zjquFmlerc@GUKc$$SNt4gl7#=Pqu4OKuSfen$NI2Gs-=76`g%rmZ z2yf=`^5#D$OqrU>u)OTEu`Yz6T@xD%sJ{O}sxSL%@&IxoO?sq*=*4$3W1Uuk{)Ul} z-4%cRD&WJ%z^az9zIdyOwEj7$mk)_o&A-aJ##lhAFGuz5HX7|e{NklD{>j5{|9WFA zz&jO^8fcA8Mh5Pdq?|#NV*MhD`1VimeyWM_t Z!A}8@z?TC+GqnH!002ovPDHLkV1gDsI@$mL literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/Test/rgba_27x63.png b/src/MagnumPlugins/BasisImporter/Test/rgba_27x63.png new file mode 100644 index 0000000000000000000000000000000000000000..6cabc6b77b702b6c085c2f7cb1d0c8987aec7af2 GIT binary patch literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^(m-s_!3HD+Uv4f1Qf8hmjv*1PZ_gSEGB9wkEV%w} w?$*|3cGeXtla*^lPo@~n^ii9PM#-geXFXu7efmTAGSCDDPgg&ebxsLQ08W@9UjP6A literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/Test/rgba_2_images.basis b/src/MagnumPlugins/BasisImporter/Test/rgba_2_images.basis new file mode 100644 index 0000000000000000000000000000000000000000..cfd249402c1a9add9f288170e9c3d656c76f6d53 GIT binary patch literal 332 zcmXSR5@zsanE&NJ0|Ue19u@`$CLn_qh*1F(!%Col7D)OskRidq@ES;&0kJO-qX2sb zX$AoXb_PX81_mym%+*~WX-1f^Hc*%cDA3*qWH12L+5^=JFqi{*oIw87T_9mbn6Lv} zwZZ`xka`A&NlHvJIKV6iF%|}4FpHssApzuYAP{6w5@Ilhusu8&(jY7WPKE}?gDwnA z5*$qmH@Je|=Wj9SJje;t&f$FEHUrQqg-#wfbqiJj13|F1h9!(l=eO>hD82Jzy*Y#a jvYm+^&lD+}|9j7Ne(S~v9kK4CN&3qYd(%OTjS)Nmmo7G~ literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/Test/rgba_2_images_pow2.basis b/src/MagnumPlugins/BasisImporter/Test/rgba_2_images_pow2.basis new file mode 100644 index 0000000000000000000000000000000000000000..91e2195fa796623bf993f7b6c905c0d2872f0b08 GIT binary patch literal 603 zcmXSR5@zsaI3&f##K6F>%fi3_q#0O&7!?RJtON>#GBC(7`~xyd85oKg85qKWOkY%m z3=9qo3Jd}a91N#`3M_z<`=*0bFv5hHfEMrp1uSZS@(e(=4nVa63<5x5dmw+-36L-& zOxPbN%mWm#sF6D$&A`aekg(QPr2SC>BjY^>4h9C6DfwSSnt9ln_Am-CFmNmrsIK(j zX8OPY^an!+L;s(3_m?D2a{McMq9x(jG%I0iIi<%rylUSLFB4jLpGozouF^MVK_-x5 z1^bxoAuHJ*v4}7T2sr%LXba>O)G103I3Vo66T0QYJFYtgtC=!1R%tk{Vp3^&Um!Ro zPuYWAJIK>@X~>m;g{uopS(rJdu5+=q`1AMQznjh3|Ni~``)7abpJQp~o`3$?`ulzU zf%@aj9s2p_A2J@i(~u~@!K7fJTCsE69N}G@D(W64?mt}rvIw*%GB7wQNVGY%9NMq1 zu&GsngC$^!&Y@4?Q9?_<^Kd=N60~0s;);=0BIREoEQ|j*Oc4 z{O+wJF6EN$wA%g8H_s2>xmi#C`E%aHq#L=bEgjhT3JRROZ^pKA>Ry~*ZR}BdHN#`> zeO}{Iq3O2E8qVugr}V#J42~3 literal 0 HcmV?d00001 diff --git a/src/MagnumPlugins/BasisImporter/configure.h.cmake b/src/MagnumPlugins/BasisImporter/configure.h.cmake new file mode 100644 index 000000000..cfa3f2783 --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/configure.h.cmake @@ -0,0 +1,26 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#cmakedefine MAGNUM_BASISIMPORTER_BUILD_STATIC diff --git a/src/MagnumPlugins/BasisImporter/importStaticPlugin.cpp b/src/MagnumPlugins/BasisImporter/importStaticPlugin.cpp new file mode 100644 index 000000000..a8a6dd5eb --- /dev/null +++ b/src/MagnumPlugins/BasisImporter/importStaticPlugin.cpp @@ -0,0 +1,36 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + Copyright © 2019 Jonathan Hale + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "MagnumPlugins/BasisImporter/configure.h" + +#ifdef MAGNUM_BASISIMPORTER_BUILD_STATIC +#include + +static int magnumBasisImporterStaticImporter() { + CORRADE_PLUGIN_IMPORT(BasisImporter) + return 1; +} CORRADE_AUTOMATIC_INITIALIZER(magnumBasisImporterStaticImporter) +#endif diff --git a/src/MagnumPlugins/CMakeLists.txt b/src/MagnumPlugins/CMakeLists.txt index c3468d89a..c201ace42 100644 --- a/src/MagnumPlugins/CMakeLists.txt +++ b/src/MagnumPlugins/CMakeLists.txt @@ -38,6 +38,10 @@ if(WITH_ASSIMPIMPORTER) add_subdirectory(AssimpImporter) endif() +if(WITH_BASISIMPORTER) + add_subdirectory(BasisImporter) +endif() + if(WITH_DDSIMPORTER) add_subdirectory(DdsImporter) endif()