Strategy for sharing OpenGL resources
Asked Answered
N

1

6

I'm creating a CAD-like app (Qt-based), it will be a multiple document interface and each document will contain about 5 viewports (derived from QGLWidget). As such I need my flat shader to be shared across the entire application, and then the 3D assets (models stored as VBOs) to be shared across each document i.e. the 5 viewports.

I thought as long as I shared around the shader program and VBO GLuint addresses all will automagickly work - it doesn't. I think because each viewport/context has it's own address space on the graphics card, if anyone knows better please inform!

I would like to have the shader compiled on application start, but this is proving difficult as I need a valid QGLWidget to get OpenGL into a valid state beforehand. But as I need to share the QGLWidgets (through their constructor) to have them share resources, one needs to be created and shown before the others can be instantiated. But this is highly impractical as multiple views to be shown at once to the user.

This must be easier than I'm making out because it's hardly groundbreaking stuff, but I am really struggling - can anyone point me in the right direction?

Thanks, Cam

Nuptial answered 5/12, 2010 at 19:20 Comment(0)
G
12

Here's what usual CAD/MDI applications are doing:

  • they create a shared context that serves for well, sharing resources.

  • they use wglShareLists when creating a new OpenGL rendering context for giving access to the resource ids of the shared context.

wglShareLists can be used for sharing VBOs, textures, shaders, etc, not only display lists (sharing DLs is the legacy usage, hence the function name).

I don't remember if you need to create resources with the shared context or if you can create them on any contexts.

If you're not on windows, see glXCreateContext. That should put you on track.

Edit:

I've looked at Qt, it looks like it's abstracted with member QGLContext::create.

Ghazi answered 5/12, 2010 at 19:45 Comment(2)
Excellent! QGLContext is a bit of a dud in isolation, the create method can only be run once a display device is created, which in my case is inside a QGLWidget. So I'll create an invisible QGLWidget as my shader compilation context, then pass that as the const QGLWidget* shareWidget arg in the constructor of the document's hidden QGLWidget which holds the VBO data, and that widget is then passed onto the visible viewport QGLWidgets. Essentially creating a QGLWidget tree hierarchy. Making invisible GUI components is hardly classy, but it'll save a lot of typing when it comes to porting.Nuptial
@Nuptial Actually, it is class, sort of: blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8Pfeffer

© 2022 - 2024 — McMap. All rights reserved.