summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCedric Chedaleux <cedric.chedaleux@orange.com>2014-02-03 12:53:26 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-04 21:34:58 +0100
commit96b7ac569c571a38826d5bfb2681889dbf81759d (patch)
treebe5370b25612a6307f29f676918948fc23ed43e6 /src
parentfdef360bad0f2f1059ff81f1bdd608332541abac (diff)
NPOT texture support in QOpenGLTextureCache
Enable non power of two texture support for non compatible NPOT GPU. If the context does not handle NPOTTexture feature, the image to bind is scaled to POT size. It works with OpenGL ES and Desktop version. It is actually almost the same code as the one in QGLContextPrivate::bindTexture. Change-Id: I6f0f511165c9e171a14f4ba6ba0b7a902e590cf6 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/gui/opengl/qopengltexturecache.cpp29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/gui/opengl/qopengltexturecache.cpp b/src/gui/opengl/qopengltexturecache.cpp
index 4238f63cd8..750264935b 100644
--- a/src/gui/opengl/qopengltexturecache.cpp
+++ b/src/gui/opengl/qopengltexturecache.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qopengltexturecache_p.h"
+#include <qopenglfunctions.h>
#include <private/qopenglcontext_p.h>
#include <private/qimagepixmapcleanuphooks_p.h>
#include <qpa/qplatformpixmap.h>
@@ -128,6 +129,20 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap &
return id;
}
+// returns the highest number closest to v, which is a power of 2
+// NB! assumes 32 bit ints
+static int qt_next_power_of_two(int v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ ++v;
+ return v;
+}
+
GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &image)
{
if (image.isNull())
@@ -144,7 +159,19 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i
}
}
- GLuint id = bindTexture(context, key, image);
+ QImage img = image;
+ if (!context->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)) {
+ // Scale the pixmap if needed. GL textures needs to have the
+ // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL
+ // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
+ int tx_w = qt_next_power_of_two(image.width());
+ int tx_h = qt_next_power_of_two(image.height());
+ if (tx_w != image.width() || tx_h != image.height()) {
+ img = img.scaled(tx_w, tx_h);
+ }
+ }
+
+ GLuint id = bindTexture(context, key, img);
if (id > 0)
QImagePixmapCleanupHooks::enableCleanupHooks(image);