I'm trying to get VBOs shared across multiple QGLWidgets. I'm using JOGL and jruby and noticed when I switched to VBOs from immediate mode, I no longer have any meshes drawing in the secondary windows. I'm sharing the VBOs in a global variable. I understood that I just had to create a pbuffer and share the contexts between multiple GLWidgets. That doesn't seem to be the case, however. Maybe I'm not setting up my VBO correctly or there's another step to setup the context? Or an explicit sharing function?

Looking at your code around line 750, I don't think you're sharing the contexts correctly. You need to share contexts when you create a pbuffer or QGLWidget. When creating a GLCanvas or pbuffer, the last argument to the constructor or factory method is a GLContext. This is the context that is shared. Every created window or pbuffer that is sharing with that context shares with each other.

It seems like QGLWidget does things a little differently. They have a constructor that takes a QGLWidget to share with. If you want sharing to work with Qt, you should create one QGLWidget as your primary widget and make sure that doesn't change. Then any other window you need will be created with the primary widget as the shareWith argument. It doesn't look like you can use JOGL pbuffers to specify a context because they don't expose enough.

I've seen the sharewith property before, but I'm not sure how to properly use it. When I create the first one, do I still need to create pbuffer object or do I need to do something else? I've spent hours looking for context-sharing in QGLWidgets, but the only posts I've found are just similar ones I've created earlier. I might remember some site long ago saying I had to create my first widget and update it because it wouldn't have a context to share later until I drew it. Is that really required, because that seems like a massive headache, and documentation is very old for JOGL.

I just want a simple example to create multiple QGLWidgets that share the same GL3 context.

Unless I missed something, I can't see how to share an actual GLContext with QGLWidgets when you create them. The only constructor they give you has the QGLWidget as the sharewith.

Although this will suck, you will have to do it this way:1. Create your first QGLWidget without any sharewith parameter.2. Draw once with the widget to make sure it is displayed (this is an unfortunate consequence of how JOGL works I think)3. Create your other QGLWidgets and always pass in the QGLWidget from #1 as the sharewith argument.

I changed the code around so it's only making one QGLWidget at startup, which seems to work fine. However, when creating a new QGLWidget after launching, I still don't see anything drawn in that widget. I guess I could call "isSharing" on the secondary widgets to see if they really are sharing. I'm using jruby so I'm wondering if when I call the super constructor, it's really sending @@firstPanel to the correct function or sending it to the wrong constructor and just not displaying any errors and not sharing. I might do this part in java or scala just to make sure.

I still don't know why you are creating a pbuffer, though. Why can't you use the context from the QGLWidget, i.e. the context() method? Maybe you need to use GLDrawableFactory.getFactory().createExternalContext() but I've never done that (I'm a little out of my element with this Qt stuff, sorry).

I'm a little out of my element, too. I've been using a pBuffer because that's the only way I've ever been able to create a GL3-profiled context. And from what I understand the QGLContext and GLContext are two different things, where GLContext is from JOGL and can provide a valid "GL" object for running commands. Maybe I can try going without GL3 for a bit and doing everything through Qt. Then I can try GLContext.getCurrent() to see if JOGL can figure out the context can give me a JOGL context to get the GL object from.

Reading the docs for GLDrawableFactory.createExternalContext(), I think you can still use a GL3 context. It will be a little bit of a headache because you aren't supposed to use the makeCurrent() and release() methods on the GLContext, but would need to use the similarly named methods on QGLWidget.context().

In your initialize() method (I think), try doing something like:

1 2 3

widget.context.makeCurrent() // This is the QGLWidget heregl_context = GLDrawableFactory.getFactory(GLProfile.get(GLProfile::GL3)).createExternalContext() // The qgl context must be current for this to workgl = gl_context.getGL.getGL3

You would still use the shareWith as I described above with the QGLWidgets. Every time you need to use the GLContext, make the widget.context current instead and then everything should get connected behind the scenes correctly. You might want to ask for a new GL every time you need to render in case the instance changes.

I have the following, which seems to almost work. I just create a vanilla QGLWidget with no parameters to the constructor and the following code. The problem is getting the GL3 object. The strange thing is in resizeGL I can call getGL3 without problems. But in paintGL calling it returns a javax.media.opengl.GLException: Not a GL3 implementation (NativeException) error. Not sure why. I've tried calling makeCurrent on the Qt context, but then resizeGL gives the same error. I've confirmed that GLProfile.get(...) returns a GL3 profile, but the createExternalGLContext function returns a GL2 implementation.

If the QGLContext is creating GL2-only contexts, you might be out of luck as far as rendering directly into the widget. They don't give you enough options to configure, so they probably don't have support for OpenGL version profiles.

An option you could try is rendering directly to a pbuffer. Instead of creating a 1x1 and trying to use its context for the QGLWidget, you would just use the GLEventListener interface and render with JOGL directly. Then you'd have to figure out a way of copying the pbuffer data to a texture in a QGLContext so that you could render the pbuffer to the screen. Depending on how fast you need things to be, you can just read it into memory and then push it to the widget (might not even need a QGLWidget then).

Alternatively, you could try setting up a shared context again, but render using the pbuffer as above, then use glCopyTexImage to a texture object that has been shared with an external context wrapping a QGLContext (as you got working in the last post), then both contexts should see the rendered-to texture. I don't know if contexts from different opengl versions can share properly, though. All of this is getting pretty complicated, so I would recommend doing the pbuffer-to-memory copy if its fast enough or living with OpenGL 2.0

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org