summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Albamont <jim.albamont@kdab.com>2020-12-10 17:19:14 -0800
committerPaul Lemire <paul.lemire@kdab.com>2020-12-11 06:56:46 +0000
commit94ab90f93dc5338338f30e6d78854b55353d3cb8 (patch)
treec01f22be8fdc22ea4c4027c506b08c7edb37ac8b
parente09188f773ab287dd8c4569a1996d89113bfd5d7 (diff)
Fix binding of CubeMapArray textures
To bind to a specific face: use glFramebufferTextureLayer and calculate the layer as 6 * layer + face. To bind to a specific cubemap: There is no way in OpenGL to directly bind to an entire cubemap within the array. Instead bind to the entire texture as for a CubeMap with AllFaces. It is up to the drawing code to select the right cubemap and face, 6 * layer + face Change-Id: Ib9e1a598503eeba1fa729677944aba6d799f90b2 Pick-to: 5.15 6.0 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp4
-rw-r--r--src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp4
-rw-r--r--src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp4
-rw-r--r--tests/auto/render/opengl/graphicshelpergl4/tst_graphicshelpergl4.cpp107
4 files changed, 113 insertions, 6 deletions
diff --git a/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp b/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp
index 5f9d2b9db..0eb0a9818 100644
--- a/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp
+++ b/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp
@@ -496,8 +496,8 @@ void GraphicsHelperGL3_2::bindFrameBufferAttachment(QOpenGLTexture *texture, con
if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray ||
target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D)
m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
- else if (target == QOpenGLTexture::TargetCubeMapArray)
- m_funcs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
+ else if (target == QOpenGLTexture::TargetCubeMapArray && attachment.m_face != QAbstractTexture::AllFaces)
+ m_funcs->glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer * 6 + (attachment.m_face - QAbstractTexture::CubeMapPositiveX));
else if (target == QOpenGLTexture::TargetCubeMap)
m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
else
diff --git a/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp b/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp
index ff82ae587..370533197 100644
--- a/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp
+++ b/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp
@@ -477,8 +477,8 @@ void GraphicsHelperGL3_3::bindFrameBufferAttachment(QOpenGLTexture *texture, con
if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray ||
target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D)
m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
- else if (target == QOpenGLTexture::TargetCubeMapArray)
- m_funcs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
+ else if (target == QOpenGLTexture::TargetCubeMapArray && attachment.m_face != QAbstractTexture::AllFaces)
+ m_funcs->glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer * 6 + (attachment.m_face - QAbstractTexture::CubeMapPositiveX));
else if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face != QAbstractTexture::AllFaces)
m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
else
diff --git a/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp b/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp
index 94510ff41..435ac7a03 100644
--- a/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp
+++ b/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp
@@ -843,8 +843,8 @@ void GraphicsHelperGL4::bindFrameBufferAttachment(QOpenGLTexture *texture, const
if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray ||
target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D)
m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
- else if (target == QOpenGLTexture::TargetCubeMapArray)
- m_funcs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
+ else if (target == QOpenGLTexture::TargetCubeMapArray && attachment.m_face != QAbstractTexture::AllFaces)
+ m_funcs->glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer * 6 + (attachment.m_face - QAbstractTexture::CubeMapPositiveX));
else if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face != QAbstractTexture::AllFaces)
m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
else
diff --git a/tests/auto/render/opengl/graphicshelpergl4/tst_graphicshelpergl4.cpp b/tests/auto/render/opengl/graphicshelpergl4/tst_graphicshelpergl4.cpp
index 595c50f08..fe87f21b7 100644
--- a/tests/auto/render/opengl/graphicshelpergl4/tst_graphicshelpergl4.cpp
+++ b/tests/auto/render/opengl/graphicshelpergl4/tst_graphicshelpergl4.cpp
@@ -470,6 +470,113 @@ private Q_SLOTS:
m_func->glDeleteFramebuffers(1, &fboId);
}
}
+
+ // TargetCubeMapArray
+ {
+ // GIVEN
+ QOpenGLTexture texture(QOpenGLTexture::TargetCubeMapArray);
+ texture.setSize(512, 512);
+ texture.setFormat(QOpenGLTexture::RGBA32F);
+ texture.setMinificationFilter(QOpenGLTexture::Linear);
+ texture.setMagnificationFilter(QOpenGLTexture::Linear);
+ texture.setWrapMode(QOpenGLTexture::ClampToEdge);
+ texture.setLayers(4);
+ if (!texture.create())
+ qWarning() << "Texture creation failed";
+ texture.allocateStorage();
+ QVERIFY(texture.isStorageAllocated());
+ GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ { // Check All Faces
+
+ // GIVEN
+ GLuint fboId;
+ m_func->glGenFramebuffers(1, &fboId);
+
+ // THEN
+ QVERIFY(fboId != 0);
+
+ // WHEN
+ m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
+
+ Attachment attachment;
+ attachment.m_point = QRenderTargetOutput::Color0;
+ attachment.m_face = Qt3DRender::QAbstractTexture::AllFaces;
+
+ m_glHelper.bindFrameBufferAttachment(&texture, attachment);
+
+ // THEN
+ GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+ QVERIFY(status == GL_FRAMEBUFFER_COMPLETE);
+
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // Texture should be layered and attached to layer 0 since CubeMapArray textures
+ // are bound to entire texture, not a specific layer
+ GLint textureIsLayered = 0;
+ m_func->glGetFramebufferAttachmentParameteriv(
+ GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_LAYERED, &textureIsLayered);
+ QCOMPARE(textureIsLayered, GL_TRUE);
+
+ GLint textureLayer = 0;
+ m_func->glGetFramebufferAttachmentParameteriv(
+ GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, &textureLayer);
+ QCOMPARE(textureLayer, 0);
+
+ // Restore state
+ m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ m_func->glDeleteFramebuffers(1, &fboId);
+ }
+ { // Check Specific Faces
+
+ // GIVEN
+ GLuint fboId;
+ m_func->glGenFramebuffers(1, &fboId);
+
+ // THEN
+ QVERIFY(fboId != 0);
+
+ // WHEN
+ m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
+
+ Attachment attachment;
+ attachment.m_point = QRenderTargetOutput::Color0;
+ attachment.m_face = Qt3DRender::QAbstractTexture::CubeMapNegativeZ;
+ attachment.m_layer = 1;
+
+ m_glHelper.bindFrameBufferAttachment(&texture, attachment);
+
+ // THEN
+ GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+ QVERIFY(status == GL_FRAMEBUFFER_COMPLETE);
+
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ GLint textureIsLayered = 0;
+ m_func->glGetFramebufferAttachmentParameteriv(
+ GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_LAYERED, &textureIsLayered);
+ QCOMPARE(textureIsLayered, GL_FALSE);
+
+ GLint textureLayer = 0;
+ m_func->glGetFramebufferAttachmentParameteriv(
+ GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, &textureLayer);
+ // actual layer should be 6 * layer + face
+ const auto faceNo =
+ attachment.m_face - Qt3DRender::QAbstractTexture::CubeMapPositiveX;
+ QCOMPARE(textureLayer, 6 * attachment.m_layer + faceNo);
+
+ // Restore state
+ m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ m_func->glDeleteFramebuffers(1, &fboId);
+ }
+ }
}
void bindFrameBufferObject()