1
votes

I am trying to capture a qml drawing buffer using the method given in this question : Capture QML drawing buffer, without displaying

The idea was to change the rendering target before rendering using the following slot connected to the beforeRendering() QQuickWindow signal :

void GrabWindow::beforeRendering()
{
  if (!fbo_)
  {
        fbo_.reset(new QOpenGLFramebufferObject( size(), QOpenGLFramebufferObject::NoAttachment) );
        setRenderTarget(fbo_.data());
  }
}

The rendering is done into a frame buffer object and this object is used to acquire the image

Problem

While running this solution, I sometimes have different rendering between my original QQuickView and my QOpenGLFramebufferObject.

For instance, I have the following main.qml :

import QtQuick 2.12

Item {
    id:root
    visible: true
    width: 640
    height: 480

    Rectangle {
        width: parent.width
        height: parent.height
        color: "gray"
    }

    Text {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        text: "Test Text"
        font.underline: true
        font.pixelSize: 24
    }

    Rectangle {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter

        width: 200
        height: 200
        border.width: 5
        color: "transparent"
        border.color: "black"
    }
}

When I render this qml main directly into a QQuickView, I have got the following and expected result :


When I render this qml main into a custom QOpenGLFramebufferObject, I have got the following result :
The black rectangle disappears and the text is not underlined anymore.

If I set the root Rectangle color to transparent, the problem seems to be solved. It looks like the root rectangle hide some of the objects.

Is there any difference between the two way of rendering that could explain this problem ?

1

1 Answers

1
votes

The solution is to add a depth buffer attached to the frame buffer object used to render :

void GrabWindow::beforeRendering()
{
  if (!fbo_)
  {
        fbo_.reset(new QOpenGLFramebufferObject( size(), QOpenGLFramebufferObject::Depth) );
        setRenderTarget(fbo_.data());
  }
}

Some of my objects were hidden by others due to a bad depth management.