diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2018-04-03 14:42:15 +0200 |
---|---|---|
committer | Johan Helsing <johan.helsing@qt.io> | 2018-04-06 12:47:11 +0000 |
commit | fbb9c0461c14196ac7100c90088c15263d0cccbb (patch) | |
tree | 1b17e3eb66e1e95a3abd6799cd592bd9eb914f1b /src/gui/opengl | |
parent | d90fb72c201efde8f9fc10c4fb4a542b1a26b9e8 (diff) |
QOpenGLTexture: Set wrap mode if NPOT textures are not fully supported
The OpenGL wrap mode defaults to GL_REPEAT although it is not supported for
non-power-of-two textures on hardware that only has limited support.
I.e. the following would create a texture with an invalid wrap mode:
auto *t = new QOpenGLTexture(QOpenGLTexture::Target2D);
t.setSize(123, 456);
This patch adds a check in QOpenGLWindow::setSize to see if it's called with a
non-power-of-two size on hardware without full support, and if so sets wrapMode
to ClampToEdge (which should work on devices with limited support).
Task-number: QTBUG-67418
Change-Id: I56e9f4383dbf5430c2bc5e4e9e585712b3603c13
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/gui/opengl')
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index b825b56d45..cea4b51a5c 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2800,6 +2800,11 @@ QOpenGLTexture::TextureFormat QOpenGLTexture::format() const return d->format; } +static bool isNpot(int width, int height = 1, int depth = 1) +{ + return width & (width-1) || height & (height-1) || depth & (depth-1); +} + /*! Sets the dimensions of this texture object to \a width, \a height, and \a depth. The default for each dimension is 1. @@ -2807,6 +2812,10 @@ QOpenGLTexture::TextureFormat QOpenGLTexture::format() const implementation. Allocating storage for a texture less than the maximum size can still fail if your system is low on resources. + If a non-power-of-two \a width, \a height or \a depth is provided and your + OpenGL implementation doesn't have support for repeating non-power-of-two + textures, then the wrap mode is automatically set to ClampToEdge. + \sa width(), height(), depth() */ void QOpenGLTexture::setSize(int width, int height, int depth) @@ -2819,6 +2828,9 @@ void QOpenGLTexture::setSize(int width, int height, int depth) return; } + if (isNpot(width, height, depth) && !hasFeature(Feature::NPOTTextureRepeat) && d->target != Target::TargetRectangle) + d->setWrapMode(WrapMode::ClampToEdge); + switch (d->target) { case QOpenGLTexture::Target1D: case QOpenGLTexture::Target1DArray: |