I want to draw a single item in QtQuick scene using raw OpenGL calls. I have decided to take approach suggested in this question.
I have created a Qt Quick item deriving from QQuickFramebufferObject
and exposed it to QML as Renderer
: (code is based on Qt example: Scene Graph - Rendering FBOs)
class FboInSGRenderer : public QQuickFramebufferObject {
Q_OBJECT
public:
Renderer *createRenderer() const;
};
source file:
class LogoInFboRenderer : public QQuickFramebufferObject::Renderer {
public:
LogoInFboRenderer() { }
void render() {
int width = 1, height = 1;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.0, 1.0, 0.0, 0.8);
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(width, 0);
glVertex2f(width, height);
glVertex2f(0, height);
glEnd();
glLineWidth(2.5);
glColor4f(0.0, 0.0, 0.0, 1.0);
glBegin(GL_LINES);
glVertex2f(0, 0);
glVertex2f(width, height);
glVertex2f(width, 0);
glVertex2f(0, height);
glEnd();
update();
}
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) {
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(4);
return new QOpenGLFramebufferObject(size, format);
}
};
QQuickFramebufferObject::Renderer *FboInSGRenderer::createRenderer() const {
return new LogoInFboRenderer();
}
In Qml I use it as follows:
import QtQuick 2.4
import SceneGraphRendering 1.0
Rectangle {
width: 400
height: 400
color: "purple"
Renderer {
id: renderer
anchors.fill: parent
}
}
I was expecting to see that rendered "X" will fill entire scene, but instead I get the result presented below:
Other experiments seem to confirm that drew shape has always it's size (width/height) divided by 2.
I also checked that size
parameter in createFramebufferObject
has correct value.
Looking into docs led me to property textureFollowsItemSize
in QQuickFramebufferObject
class but it is by default set to true
.
Am I doing something wrong or should I consider this behavior as Qt bug?
The drawn rectangle is half the sizes you expect because the default coordinate range is [-1, 1], not [0, 1] as your code assumes. If you want to use [0, 1] scale, then you should appropriately set the projection matrix:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With