General questions about using Qt for 2D game development
-
I want to try to use Qt as GUI for my pet-projects, which are usually based on Allegro library. But I simply can't see where to start. All examples of using Qt with OpenGL applications seem to create OpenGL window, render a triangle in it and call it a day. But... How do I even render Qt controls inside OpenGL window? Is it even possible, with Qt widgets or QtQuick? The answers seems to be 'yes' (as docs boast that Qt is now OpenGL-accelerated), but the way is not clear.
From what I've seen in Ogre/Qt integration, I could easily create QAllegroWidget which would setup an Allegro OpenGL or DirectX window and display it inside Qt layout. But that's not what I want: if I add any Qt controls to that widget, they still would rendered... Actually, I'm not sure how, but probably not the way I want them to.
An ideal solution would be to write my own graphics driver, but from docs, this seems to only be an option for Embedded Linux Qt (why?!). For example, I've tried Rocket GUI library, and after a day of coding, I could render their controls through Allegro with ease. If only library itself was less buggy and/or still in active development... Well, anyway, this approach does not seem to be possible with Qt, unless I want to dive deep into sources. Or am I wrong?
Well, anyway, I would be thankful for any pointers (of non-C kind [insert-xkcd-reference-here] ;) ) or even a plain "No, it is not possible", so as to avoid wasting any more time on digging through docs and sites.
-
Hi, and welcome to the Qt Dev Net!
I'm guessing that by "render Qt controls inside OpenGL window", you mean "render a Qt button (for example) on top of a custom OpenGL background", is this correct?
All "Qt Quick":http://qt-project.org/doc/qt-5/qtquick-index.html elements are rendered using OpenGL, without the need for low-level OpenGL programming. However, it does provide a way to create custom OpenGL components through the Scene Graph technology. See:
- http://qt-project.org/doc/qt-5/qtquick-visualcanvas-scenegraph.html
- http://qt-project.org/doc/qt-5/qtquick-visualcanvas-scenegraph-renderer.html
- http://qt-project.org/doc/qt-5/qtquick-scenegraph-openglunderqml-example.html
The last link shows an example on how to render Qt-provided elements (Qt Quick items) on top of a custom OpenGL background.
-
OK, thank you, this answers my main question. Now, a bit more specific one. It seems that I cannot share an OpenGL context between Allegro and Qt, since they both create it themselves and hide it deep inside their own structures. The obvious solution would be to let each one to create its own context and make it current during its paint step. The code will go something like that:
@
void OnBeforeRendering()
{
allegro_make_current();
allegro_render_before(); // Game draws its stuff
qt_make_current();
}... Qt paints QtQuick controls in scene graph ...
void OnAfterRendering:()
{
// If I want an overlay drawn by Allegro, I probably need ANOTHER context, but since it's probably just fade-to-black I'm sure I can handle it with Qt.
}
@Will this work? I'm not entirely sure how two context would overlay each other.
-
I'm afraid that level of detail is beyond my knowledge, as I have no experience in OpenGL programming. Hopefully someone with the answer will see this post.
If you still don't get anything after a few days, you can subscribe to the "Interest mailing list":http://lists.qt-project.org/mailman/listinfo/interest and ask there -- there are more people there who understand Qt's internals.
Good luck!
-
Now I think the pseudo-code above is wrong. Since to have an OpenGL context I need to have a window, doing things that way will result in Allegro and Qt creating two separate top-level windows.
I think I will actually have to create an Allegro widget which would integrate into Qt Quick scene graph. This widget will create Allegro window and then use platform-dependent code to make it child of widget, as in QtOgre (I've done something like that when I was using Allegro inside usual Qt widgets for my map editor). This does not sound like much fun (since platform-dependent code could get hairy), but I don't see any other way for now...