QQuickFramebufferObject is flipped on Y axis in QML
-
Hello,
This is my first post on qt-project. I have created a new QML project, and I use a custom QML item to integrate raw OpenGL.
If I take a screenshot using @framebufferObject()->toImage().save("a.png");@ in the QQuickFramebufferObject::Renderer then the surface is correctly renderer, but the QML surface is flipped on Y-axis.
To fix that, I need to scale my matrix by -1 on Y-axis, but now my screenshot is flipped. I think that the flip come from QML vs OpenGL coordinates. Can someone give me a the QML to render properly instead of scaling my matrix ?
Thank you in advance !!
Victor -
We should allow flipping the y coordinate more easily in the QQuickFramebufferObject class, see https://bugreports.qt-project.org/browse/QTBUG-41073
A QML way to do the same would be to set a transform: Scale { xScale: 1; yScale: -1; origin.x: width / 2; origin.y: height / 2; }. Basically flip the way it is rendered to screen. Be aware of that this will also flip input events though, so if you have a MouseArea or similar you will have to place it besides the FBO or take the inversion into account.
-
Hmm i use QQuickFramebufferObject to create a dynamic texture and render this texture with QSGSimpleTextureNode. To correct the output of the backbuffer i do this:
@
setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
@
Take a look at "this":http://qt-project.org/doc/qt-5/qsgsimpletexturenode.html#setTextureCoordinatesTransform -
[quote author="dasRicardo" date="1412586609"]Hmm i use QQuickFramebufferObject to create a dynamic texture and render this texture with QSGSimpleTextureNode. To correct the output of the backbuffer i do this: [...]
[/quote]Sounds good, but I don't know yet how to access the raw scene graph, and this is why I think we need an easy way :)
-
Hmmm take a look at "this":http://qt-project.org/doc/qt-5/qtquick-scenegraph-customgeometry-example.html. But use QSGSimpleTextureNode instead of QSGGeometryNode. A simple rendering can look like this.
@
QSGNode *YourClass::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) {
QSGNode *node = oldNode;
if (!node) {
node = new QSGNode();
}
if (this->_fbo == NULL) {
this->_fbo = new QGLFramebufferObject(QSize(this->boundingRect().width(), this->boundingRect().height()));
QSGTexture *m_texture = this->window()->createTextureFromId(this->_fbo->texture(),QSize(this->boundingRect().width(), this->boundingRect().height()), QQuickWindow::TextureHasAlphaChannel);
QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode();
textureNode->setTexture(m_texture);
textureNode->setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
textureNode->setRect(this->boundingRect());
textureNode->setFiltering(QSGTexture::Linear);
node->appendChildNode(textureNode);
}return node;
}
@
Is an example but should show how to render a backbuffer with scenegraph