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>
This commit is contained in:
parent
4273c14e57
commit
3232682d3b
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user