diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 4b2156ec79..44e35aa387 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -124,7 +124,6 @@ uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = { 1, 1, 1, 6 }; using Storage = Texture::Storage; using PixelsPointer = Texture::PixelsPointer; using MemoryStorage = Texture::MemoryStorage; -using KtxStorage = Texture::KtxStorage; void Storage::assignTexture(Texture* texture) { _texture = texture; @@ -199,13 +198,6 @@ void Texture::MemoryStorage::assignMipFaceData(uint16 level, uint8 face, const s } } -KtxStorage::KtxStorage(ktx::KTXUniquePointer& ktxData) : _ktxData(ktxData.release()) { -} - -PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const { - return _ktxData->getMipFaceTexelsData(level, face); -} - Texture* Texture::createExternal(const ExternalRecycler& recycler, const Sampler& sampler) { Texture* tex = new Texture(TextureUsageType::EXTERNAL); tex->_type = TEX_2D; @@ -980,7 +972,3 @@ void Texture::setStorage(std::unique_ptr& newStorage) { _storage.swap(newStorage); } -void Texture::setKtxBacking(ktx::KTXUniquePointer& ktxBacking) { - auto newBacking = std::unique_ptr(new KtxStorage(ktxBacking)); - setStorage(newBacking); -} \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 637b098504..b0054472fe 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -25,6 +25,7 @@ namespace ktx { class KTX; using KTXUniquePointer = std::unique_ptr; + struct Header; } namespace gpu { @@ -509,8 +510,11 @@ public: ExternalUpdates getUpdates() const; + // Textures can be serialized directly to ktx data file, here is how static ktx::KTXUniquePointer serialize(const Texture& texture); static Texture* unserialize(Usage usage, TextureUsageType usageType, const ktx::KTXUniquePointer& srcData, const Sampler& sampler = Sampler()); + static bool evalKTXFormat(const Element& mipFormat, const Element& texelFormat, ktx::Header& header); + static bool evalTextureFormat(const ktx::Header& header, Element& mipFormat, Element& texelFormat); protected: const TextureUsageType _usageType; diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index d18440bbc6..3b56b1e8c5 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -15,6 +15,36 @@ #include using namespace gpu; +using PixelsPointer = Texture::PixelsPointer; +using KtxStorage = Texture::KtxStorage; + +KtxStorage::KtxStorage(ktx::KTXUniquePointer& ktxData) { + + // if the source ktx is valid let's config this KtxStorage correctly + if (ktxData && ktxData->getHeader()) { + + // now that we know the ktx, let's get the header info to configure this Texture::Storage: + Format mipFormat = Format::COLOR_BGRA_32; + Format texelFormat = Format::COLOR_SRGBA_32; + if (Texture::evalTextureFormat(*ktxData->getHeader(), mipFormat, texelFormat)) { + _format = mipFormat; + } + + + } + + _ktxData.reset(ktxData.release()); +} + +PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const { + return _ktxData->getMipFaceTexelsData(level, face); +} + +void Texture::setKtxBacking(ktx::KTXUniquePointer& ktxBacking) { + auto newBacking = std::unique_ptr(new KtxStorage(ktxBacking)); + setStorage(newBacking); +} + ktx::KTXUniquePointer Texture::serialize(const Texture& texture) { ktx::Header header; @@ -22,17 +52,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) { auto texelFormat = texture.getTexelFormat(); auto mipFormat = texture.getStoredMipFormat(); - if (texelFormat == Format::COLOR_RGBA_32 && mipFormat == Format::COLOR_BGRA_32) { - header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 4, ktx::GLFormat::BGRA, ktx::GLInternalFormat_Uncompressed::RGBA8, ktx::GLBaseInternalFormat::RGBA); - } else if (texelFormat == Format::COLOR_RGBA_32 && mipFormat == Format::COLOR_RGBA_32) { - header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 4, ktx::GLFormat::RGBA, ktx::GLInternalFormat_Uncompressed::RGBA8, ktx::GLBaseInternalFormat::RGBA); - } else if (texelFormat == Format::COLOR_SRGBA_32 && mipFormat == Format::COLOR_SBGRA_32) { - header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 4, ktx::GLFormat::BGRA, ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8, ktx::GLBaseInternalFormat::RGBA); - } else if (texelFormat == Format::COLOR_SRGBA_32 && mipFormat == Format::COLOR_SRGBA_32) { - header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 4, ktx::GLFormat::RGBA, ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8, ktx::GLBaseInternalFormat::RGBA); - } else if (texelFormat == Format::COLOR_R_8 && mipFormat == Format::COLOR_R_8) { - header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RED, ktx::GLInternalFormat_Uncompressed::R8, ktx::GLBaseInternalFormat::RED); - } else { + if (!Texture::evalKTXFormat(mipFormat, texelFormat, header)) { return nullptr; } @@ -130,33 +150,8 @@ Texture* Texture::unserialize(Usage usage, TextureUsageType usageType, const ktx Format mipFormat = Format::COLOR_BGRA_32; Format texelFormat = Format::COLOR_SRGBA_32; - if (header.getGLFormat() == ktx::GLFormat::BGRA && header.getGLType() == ktx::GLType::UNSIGNED_BYTE && header.getTypeSize() == 4) { - if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::RGBA8) { - mipFormat = Format::COLOR_BGRA_32; - texelFormat = Format::COLOR_RGBA_32; - } else if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8) { - mipFormat = Format::COLOR_SBGRA_32; - texelFormat = Format::COLOR_SRGBA_32; - } else { - return nullptr; - } - } else if (header.getGLFormat() == ktx::GLFormat::RGBA && header.getGLType() == ktx::GLType::UNSIGNED_BYTE && header.getTypeSize() == 4) { - if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::RGBA8) { - mipFormat = Format::COLOR_RGBA_32; - texelFormat = Format::COLOR_RGBA_32; - } else if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8) { - mipFormat = Format::COLOR_SRGBA_32; - texelFormat = Format::COLOR_SRGBA_32; - } else { - return nullptr; - } - } else if (header.getGLFormat() == ktx::GLFormat::RED && header.getGLType() == ktx::GLType::UNSIGNED_BYTE && header.getTypeSize() == 1) { - mipFormat = Format::COLOR_R_8; - if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::R8) { - texelFormat = Format::COLOR_R_8; - } else { - return nullptr; - } + if (!Texture::evalTextureFormat(header, mipFormat, texelFormat)) { + return nullptr; } // Find Texture Type based on dimensions @@ -198,4 +193,56 @@ Texture* Texture::unserialize(Usage usage, TextureUsageType usageType, const ktx } return tex; -} \ No newline at end of file +} + +bool Texture::evalKTXFormat(const Element& mipFormat, const Element& texelFormat, ktx::Header& header) { + if (texelFormat == Format::COLOR_RGBA_32 && mipFormat == Format::COLOR_BGRA_32) { + header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::BGRA, ktx::GLInternalFormat_Uncompressed::RGBA8, ktx::GLBaseInternalFormat::RGBA); + } else if (texelFormat == Format::COLOR_RGBA_32 && mipFormat == Format::COLOR_RGBA_32) { + header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RGBA, ktx::GLInternalFormat_Uncompressed::RGBA8, ktx::GLBaseInternalFormat::RGBA); + } else if (texelFormat == Format::COLOR_SRGBA_32 && mipFormat == Format::COLOR_SBGRA_32) { + header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::BGRA, ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8, ktx::GLBaseInternalFormat::RGBA); + } else if (texelFormat == Format::COLOR_SRGBA_32 && mipFormat == Format::COLOR_SRGBA_32) { + header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RGBA, ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8, ktx::GLBaseInternalFormat::RGBA); + } else if (texelFormat == Format::COLOR_R_8 && mipFormat == Format::COLOR_R_8) { + header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RED, ktx::GLInternalFormat_Uncompressed::R8, ktx::GLBaseInternalFormat::RED); + } else { + return false; + } + + return true; +} + +bool Texture::evalTextureFormat(const ktx::Header& header, Element& mipFormat, Element& texelFormat) { + if (header.getGLFormat() == ktx::GLFormat::BGRA && header.getGLType() == ktx::GLType::UNSIGNED_BYTE && header.getTypeSize() == 1) { + if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::RGBA8) { + mipFormat = Format::COLOR_BGRA_32; + texelFormat = Format::COLOR_RGBA_32; + } else if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8) { + mipFormat = Format::COLOR_SBGRA_32; + texelFormat = Format::COLOR_SRGBA_32; + } else { + return false; + } + } else if (header.getGLFormat() == ktx::GLFormat::RGBA && header.getGLType() == ktx::GLType::UNSIGNED_BYTE && header.getTypeSize() == 1) { + if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::RGBA8) { + mipFormat = Format::COLOR_RGBA_32; + texelFormat = Format::COLOR_RGBA_32; + } else if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8) { + mipFormat = Format::COLOR_SRGBA_32; + texelFormat = Format::COLOR_SRGBA_32; + } else { + return false; + } + } else if (header.getGLFormat() == ktx::GLFormat::RED && header.getGLType() == ktx::GLType::UNSIGNED_BYTE && header.getTypeSize() == 1) { + mipFormat = Format::COLOR_R_8; + if (header.getGLInternaFormat_Uncompressed() == ktx::GLInternalFormat_Uncompressed::R8) { + texelFormat = Format::COLOR_R_8; + } else { + return false; + } + } else { + return false; + } + return true; +}