PDA

View Full Version : OpenGL render to texture



Nicuvëo
25th March 2011, 19:47
Hi all! I have a quick question.

I'm trying to render a bunch of stuff (mainly QPainterPaths) to an OpenGL texture in order to cache it for future usage. My naïve approach was to paint in a QImage then use QGLWidget::bindTexture to send it to OpenGL.

However, this approach has a double drawback: rendering in a QImage isn't done with OpenGL (which is way slower) and then data has to copied from the RAM to the VRAM in order to create that texture. I'm no expert, but it's my understanding that render to texture is merely a copy inside the VRAM.

So, if I could render those painter paths with OpenGL directly in a texture, I'd gain time on both actions (if I'm not mistaken).

The big question is of course how does one do that? I have an OpenGL context in a QGraphicsView, but render to texture involves some off-screen rendering that I'm not sure how to do. I've seen there is a QGLFrameBufferObject class, but I'm not sure about the way I'm supposed to use it...

Any pointers on that topic? Thanks in advance!

lauwe
25th March 2011, 22:35
The documentation for QGLFrameBufferObject includes an example: http://doc.trolltech.com/latest/opengl-framebufferobject-glwidget-cpp.html
It doesn't seem too difficult:
- First Create a QGLFrameBufferObject specifying the size of the texture.
- Then when you are ready to draw/paint create a QPainter(QGLFrameBufferObject*)
- Now QGLFrameBufferObject->texture() returns the texture-id of the texture containing whatever you painted to the framebufferobject

Nicuvëo
26th March 2011, 13:07
Oh, thanks, I hadn't noticed! ^^"
Well, it seems to work, except for one thing: I can't find a way to erase the buffer before drawing on it. Therefore when I update a texture everything is drawn on the previous one. I'd like to fill it with a transparent background before drawing; is there a way do to that with QPainter or QGLFrameBufferObject or do I have to make a native glClear call? Thanks in advance!

EDIT: a native OpenGL call to glClear works:

buffer.bind();
glClear(GL_COLOR_BUFFER_BIT);
buffer.release();
However that might be a bit heavy. Is this the "right way" of cleaning the buffer?