summaryrefslogtreecommitdiffstats
path: root/src/render/io/texturedata.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-08-05 13:00:58 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-08-17 15:29:03 +0000
commit91d1980ff29736d230efcc49f424ea963e917c0e (patch)
tree387aa9a6957f4c22b218ce57b120ae8561feef52 /src/render/io/texturedata.cpp
parent2ec0946ce68d3dc884b90c2291780c4ee12fc91e (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/texturedata.cpp')
-rw-r--r--src/render/io/texturedata.cpp36
1 files changed, 36 insertions, 0 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