I'd like to add a second render target to the default framebuffer of a QOpenGLWidget.
The reason is that I'd like to implement object picking and check whether the user hit an object by rendering a segmentation mask into gl_FragData[1]
. Unfortunately, you can only retrieve the GLuint
handle from the widget and there is no constructor of QOpenGLFramebufferObject
that takes in the handle and there is no other option to retrieve the framebuffer.
Is there any possibility to attach another texture to the default frame buffer of the widget without workarounds?
The only two options I can think of are:
1.
Attaching a texture using native OpenGL calls (I'd rather stick to pure Qt) like so in the initialization (of course I'll store segmentationTexture
to be able to delete it later):
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
QOpenGLTexture *segmentationTexture = new QOpenGLTexture(QOpenGLTexture::BindingTargetBuffer);
// set texture parameters
segmentationTexture.create();
segmentationTexture.bind();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, segmentationTexture.textureId(), 0);
segmentationTexture.release();
and then in paintGL()
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);
before the OpenGL draw calls and use glReadBuffer(GL_COLOR_ATTACHMENT1);
to retrieve the content from gl_FragData[1]
. Or maybe, if this doesn't work, using only native OpenGL code to generate the texture.
2.
Create a second framebuffer object, bind it in paintGL()
and then swap the content with the default framebuffer using glBlitFramebuffer
(to account for multisampling) to display the rendering, but use the second framebuffer to read from gl_FragData[1]
. But this feels a bit "nasty".