diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-08-05 13:00:58 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-08-17 15:29:03 +0000 |
commit | 91d1980ff29736d230efcc49f424ea963e917c0e (patch) | |
tree | 387aa9a6957f4c22b218ce57b120ae8561feef52 /src/render/io | |
parent | 2ec0946ce68d3dc884b90c2291780c4ee12fc91e (diff) |
Add support for ETC1 compressed textures in PKM containers
The PKM format is easy to generate via f.ex. Android's etc1tool and
most GLES2 drivers come with support for GL_OES_compressed_ETC1_RGB8_texture,
making ETC1 ideal when targeting embedded/mobile.
Tested with Mesa (Intel, GL ES 3.0) and etc1tool.
It is important to keep in mind that mipmap generation may not be supported for
compressed textures, depending on the driver.
Change-Id: I8b0ff7b44a6684be714507f6c3e201493b60e57c
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/io')
-rw-r--r-- | src/render/io/texturedata.cpp | 36 | ||||
-rw-r--r-- | src/render/io/texturedata.h | 3 |
2 files changed, 38 insertions, 1 deletions
diff --git a/src/render/io/texturedata.cpp b/src/render/io/texturedata.cpp index 893862731..df224ab35 100644 --- a/src/render/io/texturedata.cpp +++ b/src/render/io/texturedata.cpp @@ -38,6 +38,9 @@ #include <QDebug> #include <QOpenGLTexture> +#include <QFileInfo> +#include <QFile> +#include <qendian.h> QT_BEGIN_NAMESPACE @@ -85,6 +88,39 @@ void TexImageData::setData(const QByteArray &data, QOpenGLTexture::PixelFormat f m_pixelType = ptype; } +bool TexImageData::setCompressedFile(const QString &source) +{ + const bool isPkm = QFileInfo(source).suffix() == QStringLiteral("pkm"); + if (!isPkm) + return false; + + QFile f(source); + if (!f.open(QIODevice::ReadOnly)) { + qWarning() << "Failed to open" << source; + return false; + } + + // ETC1 in PKM, as generated by f.ex. Android's etc1tool + static const char pkmMagic[] = { 'P', 'K', 'M', ' ', '1', '0' }; + const int pkmHeaderSize = 6 + 2 + 4 * 2; + QByteArray header = f.read(pkmHeaderSize); + if (header.size() >= pkmHeaderSize && !qstrncmp(header.constData(), pkmMagic, 6)) { + m_format = QOpenGLTexture::RGB8_ETC1; // may get changed to RGB8_ETC2 later on + // get the extended (multiple of 4) width and height + m_width = qFromBigEndian(*(reinterpret_cast<const quint16 *>(header.constData() + 6 + 2))); + m_height = qFromBigEndian(*(reinterpret_cast<const quint16 *>(header.constData() + 6 + 2 + 2))); + m_depth = 1; + QByteArray data = f.readAll(); + if (data.size() < (m_width / 4) * (m_height / 4) * 8) + qWarning() << "Unexpected end of ETC1 data in" << source; + setData(data, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8); + m_isCompressed = true; + return true; + } + + return false; +} + } // namespace Qt3D QT_END_NAMESPACE diff --git a/src/render/io/texturedata.h b/src/render/io/texturedata.h index a403b0e8c..427453d6e 100644 --- a/src/render/io/texturedata.h +++ b/src/render/io/texturedata.h @@ -67,7 +67,8 @@ public: void setData(const QByteArray &data, QOpenGLTexture::PixelFormat fmt, QOpenGLTexture::PixelType ptype); - void setCompressedData(QByteArray data, QOpenGLTexture::PixelFormat fmt); + + bool setCompressedFile(const QString &source); QByteArray data() const { return m_data; } |