diff options
Diffstat (limited to 'src/gui/opengl')
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 24 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexturehelper.cpp | 56 |
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) |