Using GL3 with Qt

it would work except that you need to change the GL context handle that Qt is using to the one you get back from wgl/glxCreateContextAttribARB, whose value (and type!)

I think, the purpose of using GL3 with Qt is not to make Qt using GL3 for its rendering, but instead to be able to render your own stuff with GL3 into a Qt widget.

This is possible, I did this in the same fashion with other GUI frameworks already.

Even though Qt is hiding the handles to its DC and RC, you can retrieve these via wglGetCurrentDC() and wglGetCurrentContext(), once Qt made its context current.

Then you do


 HDC qtDC=wglGetCurrentDC();

// you need to retrieve the function pointer before
  HGLRC myGL3RC= wglCreateContextAttribsARB( qtDC, NULL, *attribList);

and somewhere in your repaint() function, you do:


 // store original context
 HDC qtDC=wglGetCurrentDC();
 HGLRC qtRC=wglGetCurrentContext();

 //make your GL3 context current and let it render into the Qt window
  wglMakeCurrent(qtDC, myGL3RC);

 ...render your stuff...

  // restore original context
  wglMakeCurrent(qtDC, qtRC);
 

Disclaimer: I did not actually test this with Qt, but it should work.

There are a few issues that can bite you badly:

  1. Qt uses the GL context it makes; Qt handles swapping buffers for you and other Qt things; I have to be honest I have never written code where I have one window with two GL contexts set for display both tied to it (vs. just offscreen contexts) So I get really nervous of that… most likely, truly the best thing to do is the following:
  1. make a QWidget, not a QGLWidget
  2. make the GL context yourself and handle all the buffer swapping and making context current stuff yourself in paintEvent().
  3. if you must use a QPainter, you are probably hosed because QPainter wants a QPaintDevice; maybe you can paint to the QWidget just fine even though it now has a GL context, but that makes me scratch my head, huh? Qt won’t be able to use the GL context you make at all, and that implies one cannot use any of:
    i) QPainter with a GL backend directly to your widget
    ii) QGLFrameBufferObject either (this is because of the context handling that Qt will do behind the scenes)
    iii) QGLShader and QGLShaderProgram (small inconsequential loss IMO)
    iv) use a QPainter to paint to an FBO becuase it wants an FBO wrapped up inside of QGLFrameBufferObject

in honesty, the main use for a QGLFrameBufferObject is to have a QPainter paint to a texture using a GL backend, IMO.

Punchline:
if you do all the drawing yourself to the widget, there is no issue, but if you Qt to draw to the widget some for you, I think there will be very ugly things. Also scrolling in your Qt Widget will be wanked out too I imagine

Well, in my case i do all the rendering to the gl widget anyway. I do not use any of Qt’s wrappers for FBOs or such and i don’t scroll the window (just one big area with 3D content, it’s a level-editor).

So i assume that would be a possibility.

Well, you can do all the rendering in QWidget without QPainter/QPainterEngine. Just reimplement QWidget::paintEngine() to return 0:

QPaintEngine* QWidget::paintEngine() const
{
return 0;
}

and set Qt::WA_PaintOnScreen to true.

See documentation of this attribute. http://doc.trolltech.com/4.5/qt.html#WidgetAttribute-enum

This way you use even Direct3D context…

by setting

QPaintEngine* QWidget::paintEngine() const
{
return 0;
}

means that you cannot do QPainter p(this);
i.e. you cannot use Qt to paint to your widget, also the docs say this:

“…Note: This flag is only supported on X11 and it disables double buffering. …”

so you don’t get D3D out it or anything.

means that you cannot do QPainter p(this);
i.e. you cannot use Qt to paint to your widget,

Yes, you have to do all drawing by yourself.

Another solution is to reimplement QPaintEngine. That way Qt will use yours QPaintEngine.

so you don’t get D3D out it or anything.

Yes, you can. I have done it.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.