summaryrefslogtreecommitdiffstats
path: root/src/quick3d/imports/scene3d/scene3drenderer.cpp
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-08-06 12:51:05 +0200
committerPaul Lemire <paul.lemire@kdab.com>2019-08-27 12:10:09 +0200
commit1fcbcf06da29a1fadd64f1fd53f6cac27f417fe1 (patch)
tree5344980743a7c8ddf084e0b7491793bda993800c /src/quick3d/imports/scene3d/scene3drenderer.cpp
parent5344d87197c83feb7d00931a6756eea870be953c (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.cpp76
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.