From b80febc045464009ecf0355a51bce048bc9b84a9 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 11 Oct 2019 09:33:49 +0200 Subject: Scene3D: only show SGNode once Qt3D has first rendered into it Avoids seeing garbage for the first frame (with planets-qml) Change-Id: I3445ce47f27bb921c15861e580a8cc6c7d8cc645 Reviewed-by: Mike Krus --- src/quick3d/imports/scene3d/scene3drenderer.cpp | 4 ++++ src/quick3d/imports/scene3d/scene3dsgmaterial.cpp | 1 + src/quick3d/imports/scene3d/scene3dsgmaterial_p.h | 4 ++++ src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp | 10 +++++++++- src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h | 1 + src/quick3d/imports/scene3d/scene3dsgnode.cpp | 6 ++++++ src/quick3d/imports/scene3d/scene3dsgnode_p.h | 2 ++ 7 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp index bc4dbd362..1e375ccbb 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer.cpp +++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp @@ -419,6 +419,10 @@ void Scene3DRenderer::render() // Restore QtQuick FBO QOpenGLFramebufferObject::bindDefault(); + + // Only show the node once Qt3D has rendered to it + // Avoids showing garbage on the first frame + m_node->show(); } // Reset the state used by the Qt Quick scenegraph to avoid any diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterial.cpp b/src/quick3d/imports/scene3d/scene3dsgmaterial.cpp index 1b8b08a4e..80a1c2c9c 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterial.cpp +++ b/src/quick3d/imports/scene3d/scene3dsgmaterial.cpp @@ -60,6 +60,7 @@ namespace Qt3DRender { Scene3DSGMaterial::Scene3DSGMaterial() : QSGMaterial() , m_texture(nullptr) + , m_visible(false) { } diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h b/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h index c096f2a74..59724782b 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h +++ b/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h @@ -75,8 +75,12 @@ public: QSGMaterialType *type() const final { return &Scene3DSGMaterialShader::type; } QSGMaterialShader *createShader() const final { return new Scene3DSGMaterialShader(); } + void show() { m_visible = true; } + bool visible() const { return m_visible; } + private: QSGTexture *m_texture; + bool m_visible; }; } // namespace Qt3DRender diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp index d25c6a7f7..55538ad1f 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp +++ b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp @@ -118,21 +118,25 @@ const char *Scene3DSGMaterialShader::fragmentShader() const if (ctx->format().version() >= qMakePair(3, 2) && ctx->format().profile() == QSurfaceFormat::CoreProfile) { return "" "#version 150 core \n" + "uniform bool visible; \n" "uniform sampler2D source; \n" "uniform float qt_Opacity; \n" "in vec2 qt_TexCoord; \n" "out vec4 fragColor; \n" "void main() { \n" - " vec4 p = texture(source, qt_TexCoord); \n" + " if (!visible) discard; \n" + " vec4 p = texture(source, qt_TexCoord); \n" " float a = qt_Opacity * p.a; \n" " fragColor = vec4(p.rgb * a, a); \n" "}"; } else { return "" + "uniform bool visible; \n" "uniform highp sampler2D source; \n" "uniform highp float qt_Opacity; \n" "varying highp vec2 qt_TexCoord; \n" "void main() { \n" + " if (!visible) discard; \n" " highp vec4 p = texture2D(source, qt_TexCoord); \n" " highp float a = qt_Opacity * p.a; \n" " gl_FragColor = vec4(p.rgb * a, a); \n" @@ -144,6 +148,7 @@ void Scene3DSGMaterialShader::initialize() { m_matrixId = program()->uniformLocation("qt_Matrix"); m_opacityId = program()->uniformLocation("qt_Opacity"); + m_visibleId = program()->uniformLocation("visible"); } void Scene3DSGMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) @@ -172,6 +177,9 @@ void Scene3DSGMaterialShader::updateState(const RenderState &state, QSGMaterial t->updateBindOptions(); } + if (oldTx == nullptr || oldTx->visible() != tx->visible()) + program()->setUniformValue(m_visibleId, tx->visible()); + if (state.isMatrixDirty()) program()->setUniformValue(m_matrixId, state.combinedMatrix()); diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h b/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h index c372a1170..60edf6d45 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h +++ b/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h @@ -74,6 +74,7 @@ protected: private: int m_matrixId; int m_opacityId; + int m_visibleId; }; } // namespace Qt3DRender diff --git a/src/quick3d/imports/scene3d/scene3dsgnode.cpp b/src/quick3d/imports/scene3d/scene3dsgnode.cpp index c38e9ffeb..630cf49a9 100644 --- a/src/quick3d/imports/scene3d/scene3dsgnode.cpp +++ b/src/quick3d/imports/scene3d/scene3dsgnode.cpp @@ -84,6 +84,12 @@ void Scene3DSGNode::setRect(const QRectF &rect, const QRectF textureRect) } } +void Scene3DSGNode::show() +{ + m_material.show(); + m_opaqueMaterial.show(); +} + } // namespace Qt3DRender QT_END_NAMESPACE diff --git a/src/quick3d/imports/scene3d/scene3dsgnode_p.h b/src/quick3d/imports/scene3d/scene3dsgnode_p.h index 388c8a605..a7873bdb8 100644 --- a/src/quick3d/imports/scene3d/scene3dsgnode_p.h +++ b/src/quick3d/imports/scene3d/scene3dsgnode_p.h @@ -78,6 +78,8 @@ public: void setRect(const QRectF &rect, const QRectF textureRect = QRectF(0.0f, 1.0f, 1.0f, -1.0f)); QRectF rect() const Q_DECL_NOTHROW { return m_rect; } + void show(); + private: Scene3DSGMaterial m_material; Scene3DSGMaterial m_opaqueMaterial; -- cgit v1.2.3