summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/opengl')
-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)