The short form of the question: How can I draw in my QGLWidget using my FBO as a texture, without just getting a blank white image?
And, some background and details... I am using Qt 5.1 for an app that does some image processing on the GPU. have a “compositor” class which uses a QOffscreenSurface, with a QOpenGLContext, and a QOpenGLFramebufferObject. It renders some things to the FBO. If the app is running in a render only mode, the result will get written to a file. Run interactively, it gets shown on my subclass of QGLWidget the “viewer.”
If I make a QImage from the FBO and draw that to the viewer, it works. However, this requires round-tripping from GPU-> QImage-> Back to the GPU as a texture. In theory, I should be able to use the FBO as a texture directly, which is what I want.
I am trying to share between my QOpenGLContext and the QGLWidget’s QGLContext like so:
viewer = new tl::ui::glViewer(this); compositor = new tl::playback::glCompositor(1280, 720, this); viewer->context()->contextHandle()->setShareContext(compositor->context);
Is it possible to share between the two types of contexts? Is this the way to do it? Do I need to do something else to draw in the viewer using the FBO in the compositor? I’m just getting solid white when I draw the FBO directly instead of the QImage, so I’m clearly doing something wrong.
So I have figured out my problem. I was misinterpreting the documentation for setShareContext() which notes that it "Won't take effect until create() is called" which I mistakenly thought meant you had to share the context after it was created. Instead, sharing has to be established right before:
viewer = new tl::ui::glViewer(this);
compositor = new tl::playback::glCompositor(512, 512, viewer->context()->contextHandle(), this);
and the new constructor for my glCompositor:
offscreenSurface = new QOffscreenSurface();
QSurfaceFormat format;
format.setMajorVersion(4);
format.setMinorVersion(0);
format.setProfile(QSurfaceFormat::CompatibilityProfile);
format.setSamples(0);
offscreenSurface->setFormat(format);
offscreenSurface->create();
context = new QOpenGLContext();
context->setShareContext(srcCtx);
context->setFormat(format);
context->create();
context->makeCurrent(offscreenSurface);
QOpenGLFramebufferObjectFormat f;
f.setSamples(0);
f.setInternalTextureFormat(GL_RGBA32F);
frameBuffer = new QOpenGLFramebufferObject(w, h, f);
Will create a new FBO in a new context which is sharing with the viewer's context. When it comes time to draw, I just bind glBindTexture(GL_TEXTURE_2D, frameBuffer->texture());
I am marking the answer I got correct, even though it didn't directly solve my problem. It was very informative.