-
Suggestion
-
Resolution: Invalid
-
Not Evaluated
-
None
-
None
-
None
When i use a QSGRenderNode to custom render content, no matter where any area of the scene graph needs to be repaint, the QSGRenderNode::paint will always be called, But I need to judge whether certain operations should be performed based on the dirty area, what should I do? I have an example here, I need to do this in RenderNode::render, please check the following code:
// dquickblitframebuffer.h #include <QQuickItem> class Q_DECL_EXPORT DQuickBlitFramebuffer : public QQuickItem { public: explicit DQuickBlitFramebuffer(QQuickItem *parent = nullptr); private: QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override; }; // dquickblitframebuffer.cpp #include "dquickblitframebuffer.h" #include <QSGRenderNode> #include <QDebug> #include <QOpenGLContext> #include <QOpenGLExtraFunctions> #include <private/qquickitem_p.h> #include <private/qquickwindow_p.h> class Q_DECL_HIDDEN RenderNode : public QSGRenderNode { public: RenderNode(QQuickItem *item) : m_item(item) {} StateFlags changedStates() const override { return 0; } void render(const RenderState *state) override { ... // get dirty areas QQuickWindowPrivate windowD = QQuickWindowPrivate::get(m_item->window()); // This is not a correct waym, the geometry of the dirty item is not equivalent to the dirty area in the scene graph. // const QRegion dirtyArea = QRect(windowD.dirtyItemList->position(), windowD.dirtyItemList->size()); QQuickItemPrivate *itemD = QQuickItemPrivate::get(m_item); // I need the dirty area of the scene graph when I draw this time const QRegion dirtyArea = itemD->sceneGraphRenderContext()->dirtyArea(); // Convert coordinates const QRect rect = state->projectionMatrix()->mapRect(m_rect); if (dirtyArea.contains(rect)) { ... GLint old = 0; QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_DRAW_FRAMEBUFFER, &old); QOpenGLContext::currentContext()->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo.handle()); // Copy the content below yourself to a texture QOpenGLContext::currentContext()->extraFunctions()->glBlitFramebuffer(rect.x(), rect.y(), rect.width(), rect.height(), ...); // Reset QOpenGLContext::currentContext()->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old); // Only when the overlap areas with is dirty, we need to continue the next processing ... I can do Gaussian blur for the m_fbo.texture() } Draw the m_fbo.texture() ... } void releaseResources() override { } RenderingFlags flags() const override { return OpaqueRendering; } QRectF rect() const override { return m_rect; } private: QRectF m_rect; QQuickItem *m_item; QOpenGLFramebufferObject m_fbo; }; DQuickBlitFramebuffer::DQuickBlitFramebuffer(QQuickItem *parent) : QQuickItem(parent) { setFlag(ItemHasContents); } QSGNode *DQuickBlitFramebuffer::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *oldData) { qDebug() << Q_FUNC_INFO; if (!oldNode) { return new RenderNode(this); } return oldNode; }