PDA

View Full Version : Using QGLWidget paint engine to draw regular widgtes?



high_flyer
27th September 2006, 14:27
Hi,

I am interested to be able to draw the regular Qt widgets (like QPushButton) in an OpenGL context.
Note, I am NOT interested in having a QPushButton on top of a QGLWidget (where the glwidget is the parent of the button) but rather, to pass an openGL initialized QPainter to the QPushButton and let it draw it self as usual, but since the QPainter is an openGL context painter, the button should then draw it self in the openGL context.
In principal, this is very much like this example: http://doc.trolltech.com/4.1/opengl-2dpainting.html
Only, in this example, the drawing is a custom drawing, so the widget draws it self with the openGL initialized QPainter.
The problem is, I couldn't yet find a way to pass an externally initialized painter to a QWidget...
I thought as well about implementing a QPaintEngine.
However, there are server disadvantages to this approach:
1. I want to use openGL rendering, and the trolls already implemented a paint engine for openGL - accessible through QGLWidget. - so no need to reimplement such an engine.
2. A new paint engine means a new kind of widget to have all the other widgets drive from (i.e a new QWidget) (because the PaintDevice is a new implementation) - which is why there is a QGLWdiget...
This is a problem since it means I will have to derive each Qt widget that I want to draw in openGL from that class...

So is there a way to pass an openGL initialized painter to a QWidget?

Or do you have other comments that could help me in this regard?

Thanks.

wysota
27th September 2006, 16:37
Doesn't passing QGLWidget as parent take care of that? I haven't tried that, but since QGLWidget is derived from QWidget and you can paint on QGLWidget using regular QPainter, maybe it'll work?

high_flyer
28th September 2006, 11:05
It works in the sense that the QGLWidget is the parent widget, and the child widget will be place on top of it, and the painting will be the "regular" painting, not in openGL context, that was the first thing I tried...
As I said, one can draw in an openGL context by using a openGL initialized QPainter (as in the examples from TT).
But how can I pass that QPainter to "regular" widget so it will use it is what I looking for.
It looks to me that Qt API just doesn't allow it.
The solution hides either in multiple inheritance (i.e QGLPushPutton where it derives both QGLWidget and QPushButton - and then reimplementing the drawing stuff) or a creating a new PaintEngine...

But these solutions mean that I can't use regular widgets in openGL context, which is what I was looking for...

If anyone has any information about this, it would be very welcome.

Thanks.

wysota
28th September 2006, 11:15
You can't have multiple inheritance from QObject, so that won't do. You could have a subclass of QPushButton where you would pass a painter pointer through a constructor. But it could be dangerous and error prone.

high_flyer
28th September 2006, 16:09
You can't have multiple inheritance from QObject
That's true, I was talking in principal, is QObject's case that would probably mean containmant (i.e QGLPushButton derives from QGLWidget and has a QPushButton).

You could have a subclass of QPushButton where you would pass a painter pointer through a constructor.
Could you explain a bit more on how you would do such a thing?
I mean, how would the QPainter be delivered to the QPushButton paintEvent?

wysota
28th September 2006, 16:28
Could you explain a bit more on how you would do such a thing?
I mean, how would the QPainter be delivered to the QPushButton paintEvent?

Hmm... let's think about it... Maybe through some external object holding a pointer to the painter which would be updated every time the GLPainter is created. It's just a loose concept, but if there was a pointer to the painter available, one could read it through that object and use it. Of course after clipping and transforming coordinates. The problem I see is that the painter object is only created (at least I think so) when the top level widget is updated (correct me if I'm wrong), so updating a child widget would require creating such a painter first. As I said, just a loose concept and a bit unclear one, I don't have a slightest idea if this is achievable at all.

high_flyer
28th September 2006, 18:20
but if there was a pointer to the painter available, one could read it through that object and use it.
That is the point I don't get.
Lets say I have a pointer to the openGL QPainter, in a helper object or some other place.
How can I give it to a regular QWidget subclass (not a user subclass,but like QPushButton) in order that it will use it for drawing it self...

That is the main problem I am trying to solve (if it can be solved).

Thanks for helping out with the brainstorming! :)

wysota
28th September 2006, 21:41
You can't. That's why I said you have to subclass :)

high_flyer
29th September 2006, 11:06
Hehe... ok, I thought you were suggesting to give the QPainter pointer to the Qt widgets...
I know it not possible with the Qt API (at least I could not find how), that is why I posted the question...

Hmm... I am not yet sure in which direction to go...
I mean, this will have to do with reimplementing the PaintEngine, which is created by the PaintDevice, which is the base for QWidget...

I have to read some more...

Thanks.

wysota
29th September 2006, 23:47
Reading one of the other threads in this forum I came up with an idea - maybe redirecting QPainter (QPainter::setRedirected) could help? You could redirect painting child widgets to the parent (GL based) widget's painter. It is probable that you should do some transforming/clipping of the GL painter to make it work (or maybe using the "offset" param will be enough).

high_flyer
2nd October 2006, 12:18
That looks interesting!
I'll have a look at it - thanks.

high_flyer
9th October 2006, 13:06
Hi again,

I just wanted to add that I tried QPainter::setRedirected, and it works in the sence that you can use it to draw the controls in a GL context.
I do it by first redirecting the draw event of the widget I want on to a QPixmap, and then I use a GL initiated QPainter to draw this pixmap in GL context.
The problem is, that this only DRAWS the controls in GL, so these are not real object anymore under GL...
It looks like having 'responding objects' under GL will force me to do sume subclassing after all...