summaryrefslogtreecommitdiffstats
path: root/src/render/io
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
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')
-rw-r--r--src/render/io/texturedata.cpp36
-rw-r--r--src/render/io/texturedata.h3
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; }