From eef1981b4348e21f1b4b224f7a8e354eed47ae8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 26 Sep 2019 18:37:14 +0200 Subject: [PATCH] GL: added hasTextureFormat() and textureFormat() helpers. --- doc/changelog.dox | 4 + src/Magnum/DebugTools/Screenshot.cpp | 4 +- src/Magnum/GL/CMakeLists.txt | 1 + .../GL/Implementation/pixelFormatMapping.hpp | 165 ++++++---- src/Magnum/GL/PixelFormat.cpp | 67 +++- src/Magnum/GL/PixelFormat.h | 5 +- src/Magnum/GL/Test/PixelFormatTest.cpp | 154 ++++++++- src/Magnum/GL/TextureFormat.cpp | 302 ++++++++++++++++++ src/Magnum/GL/TextureFormat.h | 95 +++++- 9 files changed, 714 insertions(+), 83 deletions(-) create mode 100644 src/Magnum/GL/TextureFormat.cpp diff --git a/doc/changelog.dox b/doc/changelog.dox index e540886ae..c684435c6 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -196,6 +196,10 @@ See also: texture classes now can read the pixels into @ref BasicMutableImageView "MutableImageView*D" and @ref BasicMutableCompressedImageView "MutableCompressedImageView*D" as well +- @ref GL::hasTextureFormat() and @ref GL::textureFormat() helpers for + converting @ref PixelFormat / @ref CompressedPixelFormat to + @ref GL::TextureFormat, similar to @ref GL::hasPixelFormat() / + @ref GL::pixelFormat() used for converting to @ref GL::PixelFormat @subsubsection changelog-latest-new-math Math library diff --git a/src/Magnum/DebugTools/Screenshot.cpp b/src/Magnum/DebugTools/Screenshot.cpp index fb252316a..46378274e 100644 --- a/src/Magnum/DebugTools/Screenshot.cpp +++ b/src/Magnum/DebugTools/Screenshot.cpp @@ -49,10 +49,12 @@ bool screenshot(PluginManager::Manager& manager, const GL::PixelType type = framebuffer.implementationColorReadType(); auto genericFormat = [](GL::PixelFormat format, GL::PixelType type) -> Containers::Optional { #ifndef DOXYGEN_GENERATING_OUTPUT /* It gets *really* confused */ - #define _c(generic, glFormat, glType) if(format == GL::PixelFormat::glFormat && type == GL::PixelType::glType) return PixelFormat::generic; + #define _c(generic, glFormat, glType, glTextureFormat) if(format == GL::PixelFormat::glFormat && type == GL::PixelType::glType) return PixelFormat::generic; + #define _n(generic, glFormat, glType) if(format == GL::PixelFormat::glFormat && type == GL::PixelType::glType) return PixelFormat::generic; #define _s(generic) return {}; #include "Magnum/GL/Implementation/pixelFormatMapping.hpp" #undef _c + #undef _n #undef _s #endif return {}; diff --git a/src/Magnum/GL/CMakeLists.txt b/src/Magnum/GL/CMakeLists.txt index 35c287de3..f36cbcc2f 100644 --- a/src/Magnum/GL/CMakeLists.txt +++ b/src/Magnum/GL/CMakeLists.txt @@ -36,6 +36,7 @@ set(MagnumGL_SRCS Renderer.cpp Shader.cpp Texture.cpp + TextureFormat.cpp Version.cpp Implementation/BufferState.cpp diff --git a/src/Magnum/GL/Implementation/pixelFormatMapping.hpp b/src/Magnum/GL/Implementation/pixelFormatMapping.hpp index 28163e76d..90bd738e6 100644 --- a/src/Magnum/GL/Implementation/pixelFormatMapping.hpp +++ b/src/Magnum/GL/Implementation/pixelFormatMapping.hpp @@ -25,22 +25,28 @@ /* See Magnum/GL/PixelFormat.cpp, Magnum/GL/Test/PixelFormatTest.cpp and DebugTools/Screenshot.cpp. _c() is a mapping, _s() denotes a skipped value - (so the enum numbering is preserved) */ + (so the enum numbering is preserved), _n() denotes a value where pixel + format mapping is defined, but texture format is not */ #ifdef _c #ifndef MAGNUM_TARGET_GLES2 -_c(R8Unorm, Red, UnsignedByte) -_c(RG8Unorm, RG, UnsignedByte) +_c(R8Unorm, Red, UnsignedByte, R8) +_c(RG8Unorm, RG, UnsignedByte, RG8) #else -_c(R8Unorm, Luminance, UnsignedByte) -_c(RG8Unorm, LuminanceAlpha, UnsignedByte) +_n(R8Unorm, Luminance, UnsignedByte) +_n(RG8Unorm, LuminanceAlpha, UnsignedByte) #endif -_c(RGB8Unorm, RGB, UnsignedByte) -_c(RGBA8Unorm, RGBA, UnsignedByte) #ifndef MAGNUM_TARGET_GLES2 -_c(R8Snorm, Red, Byte) -_c(RG8Snorm, RG, Byte) -_c(RGB8Snorm, RGB, Byte) -_c(RGBA8Snorm, RGBA, Byte) +_c(RGB8Unorm, RGB, UnsignedByte, RGB8) +_c(RGBA8Unorm, RGBA, UnsignedByte, RGBA8) +#else +_n(RGB8Unorm, RGB, UnsignedByte) +_n(RGBA8Unorm, RGBA, UnsignedByte) +#endif +#ifndef MAGNUM_TARGET_GLES2 +_c(R8Snorm, Red, Byte, R8Snorm) +_c(RG8Snorm, RG, Byte, R8Snorm) +_c(RGB8Snorm, RGB, Byte, R8Snorm) +_c(RGBA8Snorm, RGBA, Byte, R8Snorm) #else _s(R8Snorm) _s(RG8Snorm) @@ -48,25 +54,41 @@ _s(RGB8Snorm) _s(RGBA8Snorm) #endif /* Yes, GL's pixel format doesn't distinguish between linear and sRGB, so - mapping is the same as in case of the Unorm types. */ + mapping is the same as in case of the Unorm types. It's encoded in the + texture format tho. */ +#ifndef MAGNUM_TARGET_GLES2 +#ifndef MAGNUM_TARGET_WEBGL +_c(R8Srgb, Red, UnsignedByte, SR8) +#ifdef MAGNUM_TARGET_GLES +_c(RG8Srgb, RG, UnsignedByte, SRG8) +#else +_n(RG8Srgb, RG, UnsignedByte) +#endif +#else +_n(R8Srgb, Red, UnsignedByte) +_n(RG8Srgb, RG, UnsignedByte) +#endif +#else +/* SLUMINANCE / SLUMINANCE_ALPHA texture formats not exposed */ +_n(R8Srgb, Luminance, UnsignedByte) +_n(RG8Srgb, LuminanceAlpha, UnsignedByte) +#endif #ifndef MAGNUM_TARGET_GLES2 -_c(R8Srgb, Red, UnsignedByte) -_c(RG8Srgb, RG, UnsignedByte) +_c(RGB8Srgb, RGB, UnsignedByte, SRGB8) +_c(RGBA8Srgb, RGBA, UnsignedByte, SRGB8Alpha8) #else -_c(R8Srgb, Luminance, UnsignedByte) -_c(RG8Srgb, LuminanceAlpha, UnsignedByte) +_n(RGB8Srgb, RGB, UnsignedByte) +_n(RGBA8Srgb, RGBA, UnsignedByte) #endif -_c(RGB8Srgb, RGB, UnsignedByte) -_c(RGBA8Srgb, RGBA, UnsignedByte) #ifndef MAGNUM_TARGET_GLES2 -_c(R8UI, RedInteger, UnsignedByte) -_c(RG8UI, RGInteger, UnsignedByte) -_c(RGB8UI, RGBInteger, UnsignedByte) -_c(RGBA8UI, RGBAInteger, UnsignedByte) -_c(R8I, RedInteger, Byte) -_c(RG8I, RGInteger, Byte) -_c(RGB8I, RGBInteger, Byte) -_c(RGBA8I, RGBAInteger, Byte) +_c(R8UI, RedInteger, UnsignedByte, R8UI) +_c(RG8UI, RGInteger, UnsignedByte, RG8UI) +_c(RGB8UI, RGBInteger, UnsignedByte, RGB8UI) +_c(RGBA8UI, RGBAInteger, UnsignedByte, RGBA8UI) +_c(R8I, RedInteger, Byte, R8I) +_c(RG8I, RGInteger, Byte, RG8I) +_c(RGB8I, RGBInteger, Byte, RGB8I) +_c(RGBA8I, RGBAInteger, Byte, RGBA8I) #else _s(R8UI) _s(RG8UI) @@ -77,20 +99,27 @@ _s(RG8I) _s(RGB8I) _s(RGBA8I) #endif -#ifndef MAGNUM_TARGET_GLES2 -_c(R16Unorm, Red, UnsignedShort) -_c(RG16Unorm, RG, UnsignedShort) +#ifndef MAGNUM_TARGET_GLES +_c(R16Unorm, Red, UnsignedShort, R16) +_c(RG16Unorm, RG, UnsignedShort, RG16) +_c(RGB16Unorm, RGB, UnsignedShort, RGB16) +_c(RGBA16Unorm, RGBA, UnsignedShort, RGBA16) +#elif !defined(MAGNUM_TARGET_GLES2) +_n(R16Unorm, Red, UnsignedShort) +_n(RG16Unorm, RG, UnsignedShort) +_n(RGB16Unorm, RGB, UnsignedShort) +_n(RGBA16Unorm, RGBA, UnsignedShort) #else -_c(R16Unorm, Luminance, UnsignedShort) -_c(RG16Unorm, LuminanceAlpha, UnsignedShort) +_n(R16Unorm, Luminance, UnsignedShort) +_n(RG16Unorm, LuminanceAlpha, UnsignedShort) +_n(RGB16Unorm, RGB, UnsignedShort) +_n(RGBA16Unorm, RGBA, UnsignedShort) #endif -_c(RGB16Unorm, RGB, UnsignedShort) -_c(RGBA16Unorm, RGBA, UnsignedShort) -#ifndef MAGNUM_TARGET_GLES2 -_c(R16Snorm, Red, Short) -_c(RG16Snorm, RG, Short) -_c(RGB16Snorm, RGB, Short) -_c(RGBA16Snorm, RGBA, Short) +#ifndef MAGNUM_TARGET_GLES +_c(R16Snorm, Red, Short, R16Snorm) +_c(RG16Snorm, RG, Short, RG16Snorm) +_c(RGB16Snorm, RGB, Short, RGB16Snorm) +_c(RGBA16Snorm, RGBA, Short, RGBA16Snorm) #else _s(R16Snorm) _s(RG16Snorm) @@ -98,22 +127,22 @@ _s(RGB16Snorm) _s(RGBA16Snorm) #endif #ifndef MAGNUM_TARGET_GLES2 -_c(R16UI, RedInteger, UnsignedShort) -_c(RG16UI, RGInteger, UnsignedShort) -_c(RGB16UI, RGBInteger, UnsignedShort) -_c(RGBA16UI, RGBAInteger, UnsignedShort) -_c(R16I, RedInteger, Short) -_c(RG16I, RGInteger, Short) -_c(RGB16I, RGBInteger, Short) -_c(RGBA16I, RGBAInteger, Short) -_c(R32UI, RedInteger, UnsignedInt) -_c(RG32UI, RGInteger, UnsignedInt) -_c(RGB32UI, RGBInteger, UnsignedInt) -_c(RGBA32UI, RGBAInteger, UnsignedInt) -_c(R32I, RedInteger, Int) -_c(RG32I, RGInteger, Int) -_c(RGB32I, RGBInteger, Int) -_c(RGBA32I, RGBAInteger, Int) +_c(R16UI, RedInteger, UnsignedShort, R16UI) +_c(RG16UI, RGInteger, UnsignedShort, RG16UI) +_c(RGB16UI, RGBInteger, UnsignedShort, RGB16UI) +_c(RGBA16UI, RGBAInteger, UnsignedShort, RGBA16UI) +_c(R16I, RedInteger, Short, R16I) +_c(RG16I, RGInteger, Short, RG16I) +_c(RGB16I, RGBInteger, Short, RGB16I) +_c(RGBA16I, RGBAInteger, Short, RGBA16I) +_c(R32UI, RedInteger, UnsignedInt, R32UI) +_c(RG32UI, RGInteger, UnsignedInt, RG32UI) +_c(RGB32UI, RGBInteger, UnsignedInt, RGBA32UI) +_c(RGBA32UI, RGBAInteger, UnsignedInt, RGBA32UI) +_c(R32I, RedInteger, Int, R32I) +_c(RG32I, RGInteger, Int, RG32I) +_c(RGB32I, RGBInteger, Int, RGB32I) +_c(RGBA32I, RGBAInteger, Int, RGBA32I) #else _s(R16UI) _s(RG16UI) @@ -133,21 +162,25 @@ _s(RGB32I) _s(RGBA32I) #endif #ifndef MAGNUM_TARGET_GLES2 -_c(R16F, Red, HalfFloat) -_c(RG16F, RG, HalfFloat) +_c(R16F, Red, HalfFloat, R16F) +_c(RG16F, RG, HalfFloat, RG16F) +_c(RGB16F, RGB, HalfFloat, RGB16F) +_c(RGBA16F, RGBA, HalfFloat, RGBA16F) #else -_c(R16F, Luminance, HalfFloat) -_c(RG16F, LuminanceAlpha, HalfFloat) +_n(R16F, Luminance, HalfFloat) +_n(RG16F, LuminanceAlpha, HalfFloat) +_n(RGB16F, RGB, HalfFloat) +_n(RGBA16F, RGBA, HalfFloat) #endif -_c(RGB16F, RGB, HalfFloat) -_c(RGBA16F, RGBA, HalfFloat) #ifndef MAGNUM_TARGET_GLES2 -_c(R32F, Red, Float) -_c(RG32F, RG, Float) +_c(R32F, Red, Float, R32F) +_c(RG32F, RG, Float, RG32F) +_c(RGB32F, RGB, Float, RGB32F) +_c(RGBA32F, RGBA, Float, RGBA32F) #else -_c(R32F, Luminance, Float) -_c(RG32F, LuminanceAlpha, Float) +_n(R32F, Luminance, Float) +_n(RG32F, LuminanceAlpha, Float) +_n(RGB32F, RGB, Float) +_n(RGBA32F, RGBA, Float) #endif -_c(RGB32F, RGB, Float) -_c(RGBA32F, RGBA, Float) #endif diff --git a/src/Magnum/GL/PixelFormat.cpp b/src/Magnum/GL/PixelFormat.cpp index 175be42bd..c04377a8d 100644 --- a/src/Magnum/GL/PixelFormat.cpp +++ b/src/Magnum/GL/PixelFormat.cpp @@ -30,6 +30,7 @@ #include #include "Magnum/PixelFormat.h" +#include "Magnum/GL/TextureFormat.h" namespace Magnum { namespace GL { @@ -40,10 +41,22 @@ constexpr struct { PixelFormat format; PixelType type; } FormatMapping[] { - #define _c(input, format, type) {PixelFormat::format, PixelType::type}, - #define _s(input) {PixelFormat{}, PixelType{}}, + #define _c(input, format, type, textureFormat) {PixelFormat::format, PixelType::type}, + #define _n(input, format, type) {PixelFormat::format, PixelType::type}, + #define _s(input) {{}, {}}, #include "Magnum/GL/Implementation/pixelFormatMapping.hpp" #undef _s + #undef _n + #undef _c +}; + +constexpr TextureFormat TextureFormatMapping[] { + #define _c(input, format, type, textureFormat) TextureFormat::textureFormat, + #define _n(input, format, type) {}, + #define _s(input) {}, + #include "Magnum/GL/Implementation/pixelFormatMapping.hpp" + #undef _s + #undef _n #undef _c }; #endif @@ -59,6 +72,15 @@ bool hasPixelFormat(const Magnum::PixelFormat format) { return UnsignedInt(FormatMapping[UnsignedInt(format) - 1].format); } +bool hasTextureFormat(const Magnum::PixelFormat format) { + CORRADE_ASSERT(!isPixelFormatImplementationSpecific(format), + "GL::hasTextureFormat(): cannot map an implementation-specific pixel format to an OpenGL texture format", {}); + + CORRADE_ASSERT(UnsignedInt(format) - 1 < Containers::arraySize(TextureFormatMapping), + "GL::hasTextureFormat(): invalid format" << format, {}); + return UnsignedInt(TextureFormatMapping[UnsignedInt(format) - 1]); +} + PixelFormat pixelFormat(const Magnum::PixelFormat format) { if(isPixelFormatImplementationSpecific(format)) return pixelFormatUnwrap(format); @@ -86,6 +108,18 @@ PixelType pixelType(const Magnum::PixelFormat format, const UnsignedInt extra) { return out; } +TextureFormat textureFormat(const Magnum::PixelFormat format) { + CORRADE_ASSERT(!isPixelFormatImplementationSpecific(format), + "GL::textureFormat(): cannot map an implementation-specific pixel format to an OpenGL texture format", {}); + + CORRADE_ASSERT(UnsignedInt(format) - 1 < Containers::arraySize(FormatMapping), + "GL::textureFormat(): invalid format" << format, {}); + const TextureFormat out = TextureFormatMapping[UnsignedInt(format) - 1]; + CORRADE_ASSERT(UnsignedInt(out), + "GL::textureFormat(): format" << format << "is not supported on this target", {}); + return out; +} + UnsignedInt pixelSize(const PixelFormat format, const PixelType type) { std::size_t size = 0; #ifdef __GNUC__ @@ -358,9 +392,11 @@ Debug& operator<<(Debug& debug, const PixelType value) { namespace { #ifndef DOXYGEN_GENERATING_OUTPUT /* It gets *really* confused */ +/* Enum values are the same between CompressedPixelFormat and TextureFormat, so + having just a single table for both */ constexpr CompressedPixelFormat CompressedFormatMapping[] { - #define _c(input, format) GL::CompressedPixelFormat::format, - #define _s(input) GL::CompressedPixelFormat{}, + #define _c(input, format) CompressedPixelFormat::format, + #define _s(input) CompressedPixelFormat{}, #include "Magnum/GL/Implementation/compressedPixelFormatMapping.hpp" #undef _s #undef _c @@ -378,6 +414,15 @@ bool hasCompressedPixelFormat(const Magnum::CompressedPixelFormat format) { return UnsignedInt(CompressedFormatMapping[UnsignedInt(format) - 1]); } +bool hasTextureFormat(const Magnum::CompressedPixelFormat format) { + if(isCompressedPixelFormatImplementationSpecific(format)) + return true; + + CORRADE_ASSERT(UnsignedInt(format) - 1 < Containers::arraySize(CompressedFormatMapping), + "GL::hasTextureFormat(): invalid format" << format, {}); + return UnsignedInt(CompressedFormatMapping[UnsignedInt(format) - 1]); +} + CompressedPixelFormat compressedPixelFormat(const Magnum::CompressedPixelFormat format) { if(isCompressedPixelFormatImplementationSpecific(format)) return compressedPixelFormatUnwrap(format); @@ -390,6 +435,20 @@ CompressedPixelFormat compressedPixelFormat(const Magnum::CompressedPixelFormat return out; } +TextureFormat textureFormat(const Magnum::CompressedPixelFormat format) { + if(isCompressedPixelFormatImplementationSpecific(format)) + return compressedPixelFormatUnwrap(format); + + CORRADE_ASSERT(UnsignedInt(format) - 1 < Containers::arraySize(CompressedFormatMapping), + "GL::textureFormat(): invalid format" << format, {}); + /* Enum values are the same between CompressedPixelFormat and + TextureFormat, so having just a single table for both and casting */ + const auto out = TextureFormat(GLenum(CompressedFormatMapping[UnsignedInt(format) - 1])); + CORRADE_ASSERT(UnsignedInt(out), + "GL::textureFormat(): format" << format << "is not supported on this target", {}); + return out; +} + Debug& operator<<(Debug& debug, const CompressedPixelFormat value) { #ifdef __GNUC__ #pragma GCC diagnostic push diff --git a/src/Magnum/GL/PixelFormat.h b/src/Magnum/GL/PixelFormat.h index 6b269e782..384645ae8 100644 --- a/src/Magnum/GL/PixelFormat.h +++ b/src/Magnum/GL/PixelFormat.h @@ -1958,7 +1958,8 @@ expected to be valid. extension. Such check is outside of the scope of this function and you are expected to verify extension availability before using such format. -@see @ref compressedPixelFormat(), @ref pixelFormat(), @ref pixelType() +@see @ref compressedPixelFormat(), @ref hasPixelFormat(), + @ref hasTextureFormat() */ MAGNUM_GL_EXPORT bool hasCompressedPixelFormat(Magnum::CompressedPixelFormat format); @@ -1974,7 +1975,7 @@ returns @ref compressedPixelFormatUnwrap() cast to @ref GL::CompressedPixelForma Not all generic pixel formats may be available on all targets and this function expects that given format is available on the target. Use @ref hasCompressedPixelFormat() to query availability of given format. -@see @ref pixelFormat() +@see @ref pixelFormat(), @ref textureFormat() */ MAGNUM_GL_EXPORT CompressedPixelFormat compressedPixelFormat(Magnum::CompressedPixelFormat format); diff --git a/src/Magnum/GL/Test/PixelFormatTest.cpp b/src/Magnum/GL/Test/PixelFormatTest.cpp index 965c045d9..7bf017366 100644 --- a/src/Magnum/GL/Test/PixelFormatTest.cpp +++ b/src/Magnum/GL/Test/PixelFormatTest.cpp @@ -29,13 +29,17 @@ #include "Magnum/PixelFormat.h" #include "Magnum/GL/PixelFormat.h" +#include "Magnum/GL/TextureFormat.h" namespace Magnum { namespace GL { namespace Test { namespace { +/* Tests also TextureFormat-related utilities, since the mapping tables are + shared between these two */ + struct PixelFormatTest: TestSuite::Tester { explicit PixelFormatTest(); - void mapFormatType(); + void mapFormatTypeTextureFormat(); void mapFormatImplementationSpecific(); void mapFormatUnsupported(); void mapFormatInvalid(); @@ -43,23 +47,29 @@ struct PixelFormatTest: TestSuite::Tester { void mapTypeImplementationSpecificZero(); void mapTypeUnsupported(); void mapTypeInvalid(); + void mapTextureFormatImplementationSpecific(); + void mapTextureFormatUnsupported(); + void mapTextureFormatInvalid(); void size(); void sizeInvalid(); - void mapCompressedFormat(); + void mapCompressedFormatTextureFormat(); void mapCompressedFormatImplementationSpecific(); void mapCompressedFormatUnsupported(); void mapCompressedFormatInvalid(); + void mapCompressedTextureFormatImplementationSpecific(); + void mapCompressedTextureFormatUnsupported(); + void mapCompressedTextureFormatInvalid(); void debugPixelFormat(); void debugPixelType(); - void debugCompressedPixelFormat(); + void debugTextureFormat(); }; PixelFormatTest::PixelFormatTest() { - addTests({&PixelFormatTest::mapFormatType, + addTests({&PixelFormatTest::mapFormatTypeTextureFormat, &PixelFormatTest::mapFormatImplementationSpecific, &PixelFormatTest::mapFormatUnsupported, &PixelFormatTest::mapFormatInvalid, @@ -67,25 +77,38 @@ PixelFormatTest::PixelFormatTest() { &PixelFormatTest::mapTypeImplementationSpecificZero, &PixelFormatTest::mapTypeUnsupported, &PixelFormatTest::mapTypeInvalid, + &PixelFormatTest::mapTextureFormatImplementationSpecific, + &PixelFormatTest::mapTextureFormatUnsupported, + &PixelFormatTest::mapTextureFormatInvalid, &PixelFormatTest::size, &PixelFormatTest::sizeInvalid, - &PixelFormatTest::mapCompressedFormat, + &PixelFormatTest::mapCompressedFormatTextureFormat, &PixelFormatTest::mapCompressedFormatImplementationSpecific, &PixelFormatTest::mapCompressedFormatUnsupported, &PixelFormatTest::mapCompressedFormatInvalid, + &PixelFormatTest::mapCompressedTextureFormatImplementationSpecific, + &PixelFormatTest::mapCompressedTextureFormatUnsupported, + &PixelFormatTest::mapCompressedTextureFormatInvalid, &PixelFormatTest::debugPixelFormat, &PixelFormatTest::debugPixelType, - &PixelFormatTest::debugCompressedPixelFormat}); + &PixelFormatTest::debugCompressedPixelFormat, + &PixelFormatTest::debugTextureFormat}); } -void PixelFormatTest::mapFormatType() { +void PixelFormatTest::mapFormatTypeTextureFormat() { /* Touchstone verification */ CORRADE_VERIFY(hasPixelFormat(Magnum::PixelFormat::RGBA8Unorm)); CORRADE_COMPARE(pixelFormat(Magnum::PixelFormat::RGBA8Unorm), PixelFormat::RGBA); CORRADE_COMPARE(pixelType(Magnum::PixelFormat::RGBA8Unorm), PixelType::UnsignedByte); + #ifndef MAGNUM_TARGET_GLES2 + CORRADE_VERIFY(hasTextureFormat(Magnum::PixelFormat::RGBA8Unorm)); + CORRADE_COMPARE(textureFormat(Magnum::PixelFormat::RGBA8Unorm), TextureFormat::RGBA8); + #else + CORRADE_VERIFY(!hasTextureFormat(Magnum::PixelFormat::RGBA8Unorm)); + #endif /* This goes through the first 16 bits, which should be enough. Going through 32 bits takes 8 seconds, too much. */ @@ -104,13 +127,26 @@ void PixelFormatTest::mapFormatType() { #pragma GCC diagnostic error "-Wswitch" #endif switch(format) { - #define _c(format, expectedFormat, expectedType) \ + #define _c(format, expectedFormat, expectedType, expectedTextureFormat) \ case Magnum::PixelFormat::format: \ CORRADE_COMPARE(nextHandled, i); \ CORRADE_COMPARE(firstUnhandled, 0xffff); \ CORRADE_VERIFY(hasPixelFormat(Magnum::PixelFormat::format)); \ CORRADE_COMPARE(pixelFormat(Magnum::PixelFormat::format), Magnum::GL::PixelFormat::expectedFormat); \ CORRADE_COMPARE(pixelType(Magnum::PixelFormat::format), Magnum::GL::PixelType::expectedType); \ + CORRADE_VERIFY(hasTextureFormat(Magnum::PixelFormat::format)); \ + CORRADE_COMPARE(textureFormat(Magnum::PixelFormat::format), Magnum::GL::TextureFormat::expectedTextureFormat); \ + ++nextHandled; \ + continue; + #define _n(format, expectedFormat, expectedType) \ + case Magnum::PixelFormat::format: \ + CORRADE_COMPARE(nextHandled, i); \ + CORRADE_COMPARE(firstUnhandled, 0xffff); \ + CORRADE_VERIFY(hasPixelFormat(Magnum::PixelFormat::format)); \ + CORRADE_COMPARE(pixelFormat(Magnum::PixelFormat::format), Magnum::GL::PixelFormat::expectedFormat); \ + CORRADE_COMPARE(pixelType(Magnum::PixelFormat::format), Magnum::GL::PixelType::expectedType); \ + CORRADE_VERIFY(!hasTextureFormat(Magnum::PixelFormat::format)); \ + textureFormat(Magnum::PixelFormat::format); \ ++nextHandled; \ continue; #define _s(format) \ @@ -118,12 +154,15 @@ void PixelFormatTest::mapFormatType() { CORRADE_COMPARE(nextHandled, i); \ CORRADE_COMPARE(firstUnhandled, 0xffff); \ CORRADE_VERIFY(!hasPixelFormat(Magnum::PixelFormat::format)); \ + CORRADE_VERIFY(!hasTextureFormat(Magnum::PixelFormat::format)); \ pixelFormat(Magnum::PixelFormat::format); \ pixelType(Magnum::PixelFormat::format); \ + textureFormat(Magnum::PixelFormat::format); \ ++nextHandled; \ continue; #include "Magnum/GL/Implementation/pixelFormatMapping.hpp" #undef _s + #undef _n #undef _c } #ifdef __GNUC__ @@ -208,6 +247,49 @@ void PixelFormatTest::mapTypeInvalid() { "GL::pixelType(): invalid format PixelFormat(0x123)\n"); } +void PixelFormatTest::mapTextureFormatImplementationSpecific() { + std::ostringstream out; + Error redirectError{&out}; + hasTextureFormat(Magnum::pixelFormatWrap(PixelFormat::RGBA)); + textureFormat(Magnum::pixelFormatWrap(PixelFormat::RGBA)); + CORRADE_COMPARE(out.str(), + "GL::hasTextureFormat(): cannot map an implementation-specific pixel format to an OpenGL texture format\n" + "GL::textureFormat(): cannot map an implementation-specific pixel format to an OpenGL texture format\n"); +} + +void PixelFormatTest::mapTextureFormatUnsupported() { + #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2) + CORRADE_SKIP("All pixel formats are supported on ES3+."); + #elif defined(MAGNUM_TARGET_GLES2) + std::ostringstream out; + Error redirectError{&out}; + + textureFormat(Magnum::PixelFormat::RGB8Unorm); + CORRADE_COMPARE(out.str(), "GL::textureFormat(): format PixelFormat::RGB8Unorm is not supported on this target\n"); + #else + std::ostringstream out; + Error redirectError{&out}; + + textureFormat(Magnum::PixelFormat::RG8Srgb); + CORRADE_COMPARE(out.str(), "GL::textureFormat(): format PixelFormat::RG8Srgb is not supported on this target\n"); + #endif +} + +void PixelFormatTest::mapTextureFormatInvalid() { + std::ostringstream out; + Error redirectError{&out}; + + hasTextureFormat(Magnum::PixelFormat{}); + hasTextureFormat(Magnum::PixelFormat(0x123)); + textureFormat(Magnum::PixelFormat{}); + textureFormat(Magnum::PixelFormat(0x123)); + CORRADE_COMPARE(out.str(), + "GL::hasTextureFormat(): invalid format PixelFormat(0x0)\n" + "GL::hasTextureFormat(): invalid format PixelFormat(0x123)\n" + "GL::textureFormat(): invalid format PixelFormat(0x0)\n" + "GL::textureFormat(): invalid format PixelFormat(0x123)\n"); +} + void PixelFormatTest::size() { #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE(pixelSize(PixelFormat::RGB, PixelType::UnsignedByte332), 1); @@ -231,10 +313,12 @@ void PixelFormatTest::sizeInvalid() { CORRADE_COMPARE(out.str(), "GL::pixelSize(): invalid GL::PixelType::Float specified for GL::PixelFormat::DepthStencil\n"); } -void PixelFormatTest::mapCompressedFormat() { +void PixelFormatTest::mapCompressedFormatTextureFormat() { /* Touchstone verification */ CORRADE_VERIFY(hasCompressedPixelFormat(Magnum::CompressedPixelFormat::Bc1RGBAUnorm)); CORRADE_COMPARE(compressedPixelFormat(Magnum::CompressedPixelFormat::Bc1RGBAUnorm), CompressedPixelFormat::RGBAS3tcDxt1); + CORRADE_VERIFY(hasTextureFormat(Magnum::CompressedPixelFormat::Astc8x8RGBASrgb)); + CORRADE_COMPARE(textureFormat(Magnum::CompressedPixelFormat::Astc8x8RGBASrgb), TextureFormat::CompressedSRGB8Alpha8Astc8x8); /* This goes through the first 16 bits, which should be enough. Going through 32 bits takes 8 seconds, too much. */ @@ -258,7 +342,9 @@ void PixelFormatTest::mapCompressedFormat() { CORRADE_COMPARE(nextHandled, i); \ CORRADE_COMPARE(firstUnhandled, 0xffff); \ CORRADE_VERIFY(hasCompressedPixelFormat(Magnum::CompressedPixelFormat::format)); \ + CORRADE_VERIFY(hasTextureFormat(Magnum::CompressedPixelFormat::format)); \ CORRADE_COMPARE(compressedPixelFormat(Magnum::CompressedPixelFormat::format), Magnum::GL::CompressedPixelFormat::expectedFormat); \ + CORRADE_COMPARE(textureFormat(Magnum::CompressedPixelFormat::format), Magnum::GL::TextureFormat::Compressed ## expectedFormat); \ ++nextHandled; \ continue; #define _s(format) \ @@ -266,7 +352,9 @@ void PixelFormatTest::mapCompressedFormat() { CORRADE_COMPARE(nextHandled, i); \ CORRADE_COMPARE(firstUnhandled, 0xffff); \ CORRADE_VERIFY(!hasCompressedPixelFormat(Magnum::CompressedPixelFormat::format)); \ + CORRADE_VERIFY(!hasTextureFormat(Magnum::CompressedPixelFormat::format)); \ compressedPixelFormat(Magnum::CompressedPixelFormat::format); \ + textureFormat(Magnum::CompressedPixelFormat::format); \ ++nextHandled; \ continue; #include "Magnum/GL/Implementation/compressedPixelFormatMapping.hpp" @@ -327,6 +415,47 @@ void PixelFormatTest::mapCompressedFormatInvalid() { "GL::compressedPixelFormat(): invalid format CompressedPixelFormat(0x123)\n"); } +void PixelFormatTest::mapCompressedTextureFormatImplementationSpecific() { + CORRADE_VERIFY(hasTextureFormat(Magnum::compressedPixelFormatWrap(CompressedPixelFormat::RGBAS3tcDxt1))); + CORRADE_COMPARE(textureFormat(Magnum::compressedPixelFormatWrap(CompressedPixelFormat::RGBAS3tcDxt1)), + TextureFormat::CompressedRGBAS3tcDxt1); +} + +void PixelFormatTest::mapCompressedTextureFormatUnsupported() { + #ifdef MAGNUM_TARGET_GLES2 + CORRADE_VERIFY(!hasTextureFormat(Magnum::CompressedPixelFormat::Etc2RGB8Unorm)); + + std::ostringstream out; + Error redirectError{&out}; + textureFormat(Magnum::CompressedPixelFormat::Etc2RGB8Unorm); + CORRADE_COMPARE(out.str(), "GL::textureFormat(): format CompressedPixelFormat::Etc2RGB8Unorm is not supported on this target\n"); + #elif !defined(MAGNUM_TARGET_GLES) + CORRADE_VERIFY(!hasTextureFormat(Magnum::CompressedPixelFormat::PvrtcRGB2bppUnorm)); + + std::ostringstream out; + Error redirectError{&out}; + textureFormat(Magnum::CompressedPixelFormat::PvrtcRGB2bppUnorm); + CORRADE_COMPARE(out.str(), "GL::textureFormat(): format CompressedPixelFormat::PvrtcRGB2bppUnorm is not supported on this target\n"); + #else + CORRADE_SKIP("All compressed pixel formats are supported on ES3."); + #endif +} + +void PixelFormatTest::mapCompressedTextureFormatInvalid() { + std::ostringstream out; + Error redirectError{&out}; + + hasTextureFormat(Magnum::CompressedPixelFormat{}); + hasTextureFormat(Magnum::CompressedPixelFormat(0x123)); + textureFormat(Magnum::CompressedPixelFormat{}); + textureFormat(Magnum::CompressedPixelFormat(0x123)); + CORRADE_COMPARE(out.str(), + "GL::hasTextureFormat(): invalid format CompressedPixelFormat(0x0)\n" + "GL::hasTextureFormat(): invalid format CompressedPixelFormat(0x123)\n" + "GL::textureFormat(): invalid format CompressedPixelFormat(0x0)\n" + "GL::textureFormat(): invalid format CompressedPixelFormat(0x123)\n"); +} + void PixelFormatTest::debugPixelFormat() { std::ostringstream out; @@ -348,6 +477,13 @@ void PixelFormatTest::debugCompressedPixelFormat() { CORRADE_COMPARE(out.str(), "GL::CompressedPixelFormat::RGBS3tcDxt1 GL::CompressedPixelFormat(0xdead)\n"); } +void PixelFormatTest::debugTextureFormat() { + std::ostringstream out; + + Debug(&out) << TextureFormat::DepthComponent << TextureFormat(0xdead); + CORRADE_COMPARE(out.str(), "GL::TextureFormat::DepthComponent GL::TextureFormat(0xdead)\n"); +} + }}}} CORRADE_TEST_MAIN(Magnum::GL::Test::PixelFormatTest) diff --git a/src/Magnum/GL/TextureFormat.cpp b/src/Magnum/GL/TextureFormat.cpp new file mode 100644 index 000000000..06875b35f --- /dev/null +++ b/src/Magnum/GL/TextureFormat.cpp @@ -0,0 +1,302 @@ +/* + 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. +*/ + +#include "TextureFormat.h" + +#include +#include +#include + +#include "Magnum/PixelFormat.h" +#include "Magnum/GL/PixelFormat.h" + +namespace Magnum { namespace GL { + +/* the textureFormat() and hasTextureFormat() utilities share mapping tables + with pixelFormat() / hasPixelFormat() so are defined in PixelFormat.cpp + instead (and tested there too) */ + +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug& operator<<(Debug& debug, const TextureFormat value) { + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic error "-Wswitch" + #endif + switch(value) { + /* LCOV_EXCL_START */ + #define _c(value) case TextureFormat::value: return debug << "GL::TextureFormat::" #value; + #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) + _c(Red) + _c(R8) + _c(RG) + _c(RG8) + #endif + _c(RGB) + #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) + _c(RGB8) + #endif + _c(RGBA) + #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) + _c(RGBA8) + #endif + #ifndef MAGNUM_TARGET_WEBGL + _c(SR8) + #ifdef MAGNUM_TARGET_GLES + _c(SRG8) + #endif + #endif + #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2) + _c(SRGB) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(SRGB8) + #endif + #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2) + _c(SRGBAlpha) + #endif + #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) + _c(SRGB8Alpha8) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(R8Snorm) + _c(RG8Snorm) + _c(RGB8Snorm) + _c(RGBA8Snorm) + #endif + #ifndef MAGNUM_TARGET_GLES + _c(R16) + _c(RG16) + _c(RGB16) + _c(RGBA16) + _c(R16Snorm) + _c(RG16Snorm) + _c(RGB16Snorm) + _c(RGBA16Snorm) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(R8UI) + _c(RG8UI) + _c(RGB8UI) + _c(RGBA8UI) + _c(R8I) + _c(RG8I) + _c(RGB8I) + _c(RGBA8I) + _c(R16UI) + _c(RG16UI) + _c(RGB16UI) + _c(RGBA16UI) + _c(R16I) + _c(RG16I) + _c(RGB16I) + _c(RGBA16I) + _c(R32UI) + _c(RG32UI) + _c(RGB32UI) + _c(RGBA32UI) + _c(R32I) + _c(RG32I) + _c(RGB32I) + _c(RGBA32I) + _c(R16F) + _c(RG16F) + _c(RGB16F) + _c(RGBA16F) + _c(R32F) + _c(RG32F) + _c(RGB32F) + _c(RGBA32F) + #endif + #ifdef MAGNUM_TARGET_GLES2 + _c(Luminance) + _c(LuminanceAlpha) + #endif + #ifndef MAGNUM_TARGET_GLES + _c(R3G3B2) + _c(RGB4) + _c(RGB5) + #endif + _c(RGB565) + #if !defined(MAGNUM_TARGET_GLES) || (defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)) + _c(RGB10) + #endif + #ifndef MAGNUM_TARGET_GLES + _c(RGB12) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(R11FG11FB10F) + _c(RGB9E5) + #endif + #ifndef MAGNUM_TARGET_GLES + _c(RGBA2) + #endif + _c(RGBA4) + _c(RGB5A1) + #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) + _c(RGB10A2) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(RGB10A2UI) + #endif + #ifndef MAGNUM_TARGET_GLES + _c(RGBA12) + #endif + #ifndef MAGNUM_TARGET_GLES + _c(CompressedRed) + _c(CompressedRG) + _c(CompressedRGB) + _c(CompressedRGBA) + #endif + #if !defined(MAGNUM_TARGET_GLES2) || defined(MAGNUM_TARGET_WEBGL) + _c(CompressedRedRgtc1) + _c(CompressedRGRgtc2) + _c(CompressedSignedRedRgtc1) + _c(CompressedSignedRGRgtc2) + _c(CompressedRGBBptcUnsignedFloat) + _c(CompressedRGBBptcSignedFloat) + _c(CompressedRGBABptcUnorm) + _c(CompressedSRGBAlphaBptcUnorm) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(CompressedRGB8Etc2) + _c(CompressedSRGB8Etc2) + _c(CompressedRGB8PunchthroughAlpha1Etc2) + _c(CompressedSRGB8PunchthroughAlpha1Etc2) + _c(CompressedRGBA8Etc2Eac) + _c(CompressedSRGB8Alpha8Etc2Eac) + _c(CompressedR11Eac) + _c(CompressedSignedR11Eac) + _c(CompressedRG11Eac) + _c(CompressedSignedRG11Eac) + #endif + _c(CompressedRGBS3tcDxt1) + _c(CompressedSRGBS3tcDxt1) + _c(CompressedRGBAS3tcDxt1) + _c(CompressedSRGBAlphaS3tcDxt1) + _c(CompressedRGBAS3tcDxt3) + _c(CompressedSRGBAlphaS3tcDxt3) + _c(CompressedRGBAS3tcDxt5) + _c(CompressedSRGBAlphaS3tcDxt5) + _c(CompressedRGBAAstc4x4) + _c(CompressedSRGB8Alpha8Astc4x4) + _c(CompressedRGBAAstc5x4) + _c(CompressedSRGB8Alpha8Astc5x4) + _c(CompressedRGBAAstc5x5) + _c(CompressedSRGB8Alpha8Astc5x5) + _c(CompressedRGBAAstc6x5) + _c(CompressedSRGB8Alpha8Astc6x5) + _c(CompressedRGBAAstc6x6) + _c(CompressedSRGB8Alpha8Astc6x6) + _c(CompressedRGBAAstc8x5) + _c(CompressedSRGB8Alpha8Astc8x5) + _c(CompressedRGBAAstc8x6) + _c(CompressedSRGB8Alpha8Astc8x6) + _c(CompressedRGBAAstc8x8) + _c(CompressedSRGB8Alpha8Astc8x8) + _c(CompressedRGBAAstc10x5) + _c(CompressedSRGB8Alpha8Astc10x5) + _c(CompressedRGBAAstc10x6) + _c(CompressedSRGB8Alpha8Astc10x6) + _c(CompressedRGBAAstc10x8) + _c(CompressedSRGB8Alpha8Astc10x8) + _c(CompressedRGBAAstc10x10) + _c(CompressedSRGB8Alpha8Astc10x10) + _c(CompressedRGBAAstc12x10) + _c(CompressedSRGB8Alpha8Astc12x10) + _c(CompressedRGBAAstc12x12) + _c(CompressedSRGB8Alpha8Astc12x12) + #if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + _c(CompressedRGBAAstc3x3x3) + _c(CompressedSRGB8Alpha8Astc3x3x3) + _c(CompressedRGBAAstc4x3x3) + _c(CompressedSRGB8Alpha8Astc4x3x3) + _c(CompressedRGBAAstc4x4x3) + _c(CompressedSRGB8Alpha8Astc4x4x3) + _c(CompressedRGBAAstc4x4x4) + _c(CompressedSRGB8Alpha8Astc4x4x4) + _c(CompressedRGBAAstc5x4x4) + _c(CompressedSRGB8Alpha8Astc5x4x4) + _c(CompressedRGBAAstc5x5x4) + _c(CompressedSRGB8Alpha8Astc5x5x4) + _c(CompressedRGBAAstc5x5x5) + _c(CompressedSRGB8Alpha8Astc5x5x5) + _c(CompressedRGBAAstc6x5x5) + _c(CompressedSRGB8Alpha8Astc6x5x5) + _c(CompressedRGBAAstc6x6x5) + _c(CompressedSRGB8Alpha8Astc6x6x5) + _c(CompressedRGBAAstc6x6x6) + _c(CompressedSRGB8Alpha8Astc6x6x6) + #endif + #ifdef MAGNUM_TARGET_GLES + _c(CompressedRGBPvrtc2bppV1) + #ifndef MAGNUM_TARGET_WEBGL + _c(CompressedSRGBPvrtc2bppV1) + #endif + _c(CompressedRGBAPvrtc2bppV1) + #ifndef MAGNUM_TARGET_WEBGL + _c(CompressedSRGBAlphaPvrtc2bppV1) + #endif + _c(CompressedRGBPvrtc4bppV1) + #ifndef MAGNUM_TARGET_WEBGL + _c(CompressedSRGBPvrtc4bppV1) + #endif + _c(CompressedRGBAPvrtc4bppV1) + #ifndef MAGNUM_TARGET_WEBGL + _c(CompressedSRGBAlphaPvrtc4bppV1) + #endif + #endif + _c(DepthComponent) + #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) + _c(DepthComponent16) + _c(DepthComponent24) + #endif + #ifndef MAGNUM_TARGET_WEBGL + _c(DepthComponent32) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(DepthComponent32F) + #endif + #ifndef MAGNUM_TARGET_WEBGL + _c(StencilIndex8) + #endif + _c(DepthStencil) + #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) + _c(Depth24Stencil8) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(Depth32FStencil8) + #endif + #undef _c + /* LCOV_EXCL_STOP */ + } + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif + + return debug << "GL::TextureFormat(" << Debug::nospace << reinterpret_cast(GLenum(value)) << Debug::nospace << ")"; +} +#endif + +}} diff --git a/src/Magnum/GL/TextureFormat.h b/src/Magnum/GL/TextureFormat.h index 44108d552..6e47758a6 100644 --- a/src/Magnum/GL/TextureFormat.h +++ b/src/Magnum/GL/TextureFormat.h @@ -29,7 +29,9 @@ * @brief Enum @ref Magnum::GL::TextureFormat */ +#include "Magnum/Magnum.h" #include "Magnum/GL/OpenGL.h" +#include "Magnum/GL/visibility.h" #ifdef MAGNUM_BUILD_DEPRECATED #include @@ -47,7 +49,8 @@ color format is then @ref PixelFormat::Red, @ref PixelFormat::RGB or documentation of these values for possible limitations when using OpenGL ES 2.0 or WebGL. -@see @ref Texture, @ref CubeMapTexture, @ref CubeMapTextureArray +@see @ref textureFormat(), @ref hasTextureFormat(), @ref Texture, + @ref CubeMapTexture, @ref CubeMapTextureArray @m_enum_values_as_keywords */ enum class TextureFormat: GLenum { @@ -2420,6 +2423,96 @@ enum class TextureFormat: GLenum { #endif }; +/** +@brief Check availability of a sized generic texture format + +Some OpenGL targets don't support sized texture formats at all (OpenGL ES 2.0 +and WebGL 1.0), some targets miss some variants (for example OpenGL ES doesn't +have any 8-bit packed formats) Returns @cpp false @ce if current target can't +support such format, @cpp true @ce otherwise. Expects +@ref isPixelFormatImplementationSpecific() returns @cpp false @ce for given +@p format as OpenGL pixel format enum values usually can't be used to specify +internal texture format as well. + +For OpenGL ES 2.0 (and WebGL 1.0) targets in particular the mapping is very +complex and instead of using this function it's recommend to do the mapping +manually based on whether @ref Texture::setImage() or +@ref Texture::setStorage() is used and whether @gl_extension{EXT,texture_storage} +and other format-specific extensions are supported. + +@note Support of some formats depends on presence of a particular OpenGL + extension. Such check is outside of the scope of this function and you are + expected to verify extension availability before using such format. + +@see @ref textureFormat(), @ref hasPixelFormat(), + @ref hasCompressedPixelFormat() +*/ +MAGNUM_GL_EXPORT bool hasTextureFormat(Magnum::PixelFormat format); + +/** +@brief Convert a generic pixel format to sized OpenGL texture format + +Not all sized texture formats may be available on all targets and this function +expects that given format is available on the target. See @ref hasTextureFormat() +for more information about checking availability of given format. Expects +@ref isPixelFormatImplementationSpecific() returns @cpp false @ce for given +@p format as OpenGL pixel format enum values usually can't be used to specify +internal texture format as well. + +For OpenGL ES 2.0 (and WebGL 1.0) targets in particular the mapping is very +complex and instead of using this function it's recommend to do the mapping +manually based on whether @ref Texture::setImage() or +@ref Texture::setStorage() is used and whether @gl_extension{EXT,texture_storage} +and other format-specific extensions are supported. + +@see @ref pixelType(), @ref compressedPixelFormat() +*/ +MAGNUM_GL_EXPORT TextureFormat textureFormat(Magnum::PixelFormat format); + +/** +@brief Check availability of a generic compressed texture format + +Some OpenGL targets don't support all generic pixel formats (for example PVRTC +compression might not be available on desktop OpenGL). Returns @cpp false @ce +if current target can't support such format, @cpp true @ce otherwise. Moreover, +returns @cpp true @ce also for all formats that are +@ref isCompressedPixelFormatImplementationSpecific(). The @p format value is +expected to be valid. This is different from +@ref hasTextureFormat(Magnum::PixelFormat), where the mapping of an +implementation-specific pixel format to an OpenGL texture format can't be +performed. + +@note Support of some formats depends on presence of a particular OpenGL + extension. Such check is outside of the scope of this function and you are + expected to verify extension availability before using such format. + +@see @ref textureFormat(), @ref hasCompressedPixelFormat(), + @ref hasPixelFormat() +*/ +MAGNUM_GL_EXPORT bool hasTextureFormat(Magnum::CompressedPixelFormat format); + +/** +@brief Convert generic compressed pixel format to OpenGL texture format + +In case @ref isCompressedPixelFormatImplementationSpecific() returns +@cpp false @ce for @p format, maps it to a corresponding OpenGL pixel format. +In case @ref isCompressedPixelFormatImplementationSpecific() returns +@cpp true @ce, assumes @p format stores OpenGL-specific pixel format and +returns @ref compressedPixelFormatUnwrap() cast to @ref GL::TextureFormat. This +is different from @ref textureFormat(Magnum::PixelFormat), where the mapping of +an implementation-specific pixel format to an OpenGL texture format can't be +performed. + +Not all generic pixel formats may be available on all targets and this function +expects that given format is available on the target. Use @ref hasTextureFormat() +to query availability of given format. +@see @ref compressedPixelFormat(), @ref pixelFormat() +*/ +MAGNUM_GL_EXPORT TextureFormat textureFormat(Magnum::CompressedPixelFormat format); + +/** @debugoperatorenum{TextureFormat} */ +MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, TextureFormat value); + }} #endif