diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-08-06 12:51:05 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-08-27 12:10:09 +0200 |
commit | 1fcbcf06da29a1fadd64f1fd53f6cac27f417fe1 (patch) | |
tree | 5344980743a7c8ddf084e0b7491793bda993800c /src/quick3d/imports/scene3d/scene3drenderer.cpp | |
parent | 5344d87197c83feb7d00931a6756eea870be953c (diff) |
Scene3D: introduce compositingMode (FBO or Underlay)
The default compositing mode is FBO.
One of the problematic aspects of Scene3D is its round trip
through a FBO, which is moderately expensive on low-end hardware,
although it makes it a fully fledged Qt Quick 2 item. If one
wants MSAA then things are even worse, as an intermediate MS'ed
FBO is needed, then resolving into the final one, whose color
texture is then sampled.
However, there's a significant use case for which these FBOs
can be avoided, and that's the case of a 3D scene "below" other
QQ2 content. In this setup, Qt3D can simply render to the
screen, driven by QQ2; then QQ2 can draw on top.
(It's the typical "underlay" scenario.) This can be enabled by setting
the compositing mode to Underlay
[ChangeLog] Scene3D add compositingMode property. Allows underlay rendering.
Task-number: QTBUG-74977
Change-Id: I1ec5f5d60eab45835dbdb2596a7bf1b2ac3624e0
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/quick3d/imports/scene3d/scene3drenderer.cpp')
-rw-r--r-- | src/quick3d/imports/scene3d/scene3drenderer.cpp | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp index 596ad0b84..da63c32d8 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer.cpp +++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp @@ -311,6 +311,11 @@ void Scene3DRenderer::allowRender() m_allowRendering.release(1); } +void Scene3DRenderer::setCompositingMode(Scene3DItem::CompositingMode mode) +{ + m_compositingMode = mode; +} + void Scene3DRenderer::setSGNode(Scene3DSGNode *node) { m_node = node; @@ -331,51 +336,58 @@ void Scene3DRenderer::render() // it here to give Qt3D the clean state it expects m_window->resetOpenGLState(); - // Rebuild FBO and textures if never created or a resize has occurred - if ((m_multisampledFBO.isNull() || m_forceRecreate) && m_multisample) { - m_multisampledFBO.reset(createMultisampledFramebufferObject(m_lastSize)); - if (m_multisampledFBO->format().samples() == 0 || !QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) { - m_multisample = false; - m_multisampledFBO.reset(nullptr); + // Create and bind FBO if using the FBO compositing mode + const bool usesFBO = m_compositingMode == Scene3DItem::FBO; + if (usesFBO) { + // Rebuild FBO and textures if never created or a resize has occurred + if ((m_multisampledFBO.isNull() || m_forceRecreate) && m_multisample) { + m_multisampledFBO.reset(createMultisampledFramebufferObject(m_lastSize)); + if (m_multisampledFBO->format().samples() == 0 || !QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) { + m_multisample = false; + m_multisampledFBO.reset(nullptr); + } } - } - if (m_finalFBO.isNull() || m_forceRecreate) { - m_finalFBO.reset(createFramebufferObject(m_lastSize)); - m_texture.reset(m_window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel)); - m_node->setTexture(m_texture.data()); - } + if (m_finalFBO.isNull() || m_forceRecreate) { + m_finalFBO.reset(createFramebufferObject(m_lastSize)); + m_texture.reset(m_window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel)); + m_node->setTexture(m_texture.data()); + } - m_forceRecreate = false; - // Bind FBO - if (m_multisample) //Only try to use MSAA when available - m_multisampledFBO->bind(); - else - m_finalFBO->bind(); + m_forceRecreate = false; + + // Bind FBO + if (m_multisample) //Only try to use MSAA when available + m_multisampledFBO->bind(); + else + m_finalFBO->bind(); + } // Render Qt3D Scene - static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderSynchronous(); + static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderSynchronous(usesFBO); // We may have called doneCurrent() so restore the context if the rendering surface was changed // Note: keep in mind that the ContextSave also restores the surface when destroyed if (saver.context()->surface() != saver.surface()) saver.context()->makeCurrent(saver.surface()); - if (m_multisample) { - // Blit multisampled FBO with non multisampled FBO with texture attachment - const QRect dstRect(QPoint(0, 0), m_finalFBO->size()); - const QRect srcRect(QPoint(0, 0), m_multisampledFBO->size()); - QOpenGLFramebufferObject::blitFramebuffer(m_finalFBO.data(), dstRect, - m_multisampledFBO.data(), srcRect, - GL_COLOR_BUFFER_BIT, - GL_NEAREST, - 0, 0, - QOpenGLFramebufferObject::DontRestoreFramebufferBinding); - } + if (usesFBO) { + if (m_multisample) { + // Blit multisampled FBO with non multisampled FBO with texture attachment + const QRect dstRect(QPoint(0, 0), m_finalFBO->size()); + const QRect srcRect(QPoint(0, 0), m_multisampledFBO->size()); + QOpenGLFramebufferObject::blitFramebuffer(m_finalFBO.data(), dstRect, + m_multisampledFBO.data(), srcRect, + GL_COLOR_BUFFER_BIT, + GL_NEAREST, + 0, 0, + QOpenGLFramebufferObject::DontRestoreFramebufferBinding); + } - // Restore QtQuick FBO - QOpenGLFramebufferObject::bindDefault(); + // Restore QtQuick FBO + QOpenGLFramebufferObject::bindDefault(); + } // Reset the state used by the Qt Quick scenegraph to avoid any // interference when rendering the rest of the UI. |