summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2014-02-13 16:39:30 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-14 14:36:10 +0100
commit3232682d3b04ff16806fd8c5ad36271876a7b419 (patch)
tree2d36117b6f8f20b1cffd23a873a9370a20aa6bbb
parent4273c14e57d26cf2dde90ed9db1f463a25b327bd (diff)
OpenGL: Fix QOpenGLTexture for cubemaps with mutable storage
The code was not creating all of the storage necessary for cubemaps as well as attempting to bind to the cubemap face targets which is invalid when using mutable storage - typically on OS X where EXT_direct_state_access is not available and immutable storage is only available at all if using an OpenGL 4.1 context. Change-Id: I4cf84f1b88c90e8359366392b3ccda65669ebfa7 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Pasi Keränen <pasi.keranen@digia.com>
-rw-r--r--src/gui/opengl/qopengltexture.cpp24
-rw-r--r--src/gui/opengl/qopengltexturehelper.cpp56
2 files changed, 71 insertions, 9 deletions
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 43acd0a0c3..8bdbdba6f7 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -347,7 +347,6 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
break;
case QOpenGLTexture::Target2D:
- case QOpenGLTexture::TargetCubeMap:
case QOpenGLTexture::TargetRectangle:
for (int level = 0; level < mipLevels; ++level)
texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format,
@@ -357,6 +356,29 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
break;
+ case QOpenGLTexture::TargetCubeMap: {
+ // Cubemaps are the odd one out. We have to allocate storage for each
+ // face and miplevel using the special cubemap face targets rather than
+ // GL_TARGET_CUBEMAP.
+ const QOpenGLTexture::CubeMapFace faceTargets[] = {
+ QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::CubeMapNegativeX,
+ QOpenGLTexture::CubeMapPositiveY, QOpenGLTexture::CubeMapNegativeY,
+ QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::CubeMapNegativeZ
+ };
+
+ for (int faceTarget = 0; faceTarget < 6; ++faceTarget) {
+ for (int level = 0; level < mipLevels; ++level) {
+ texFuncs->glTextureImage2D(textureId, faceTargets[faceTarget], bindingTarget,
+ level, format,
+ mipLevelSize(level, dimensions[0]),
+ mipLevelSize(level, dimensions[1]),
+ 0,
+ QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
+ }
+ }
+ break;
+ }
+
case QOpenGLTexture::Target2DArray:
if (features.testFlag(QOpenGLTexture::TextureArrays)) {
for (int level = 0; level < mipLevels; ++level)
diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp
index 69ad498aa7..1f44a81276 100644
--- a/src/gui/opengl/qopengltexturehelper.cpp
+++ b/src/gui/opengl/qopengltexturehelper.cpp
@@ -478,11 +478,31 @@ void QOpenGLTextureHelper::qt_TextureImage3D(GLuint texture, GLenum target, GLen
void QOpenGLTextureHelper::qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
+ // For cubemaps we can't use the standard DSA emulation as it is illegal to
+ // try to bind a texture to one of the cubemap face targets. So we force the
+ // target and binding target to the cubemap values in this case.
GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
- glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
- glBindTexture(target, oldTexture);
+
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
+ glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
+ break;
+
+ default:
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
+ glBindTexture(target, oldTexture);
+ break;
+ }
}
void QOpenGLTextureHelper::qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
@@ -505,11 +525,31 @@ void QOpenGLTextureHelper::qt_TextureSubImage3D(GLuint texture, GLenum target, G
void QOpenGLTextureHelper::qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
{
+ // For cubemaps we can't use the standard DSA emulation as it is illegal to
+ // try to bind a texture to one of the cubemap face targets. So we force the
+ // target and binding target to the cubemap values in this case.
GLint oldTexture;
- glGetIntegerv(bindingTarget, &oldTexture);
- glBindTexture(target, texture);
- glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
- glBindTexture(target, oldTexture);
+
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
+ break;
+
+ default:
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ glBindTexture(target, oldTexture);
+ break;
+ }
}
void QOpenGLTextureHelper::qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)