Using LibCinder with Qt

Hey Embers,

Does anyone have experience or recommendations of having Qt and LibCinder play together? I’ve found next to no previous code or even discussion topics on here apart from this one.

My current understanding of Qt is that it must have its QWindow executing on the main GUI thread. All my use of LibCinder has simply relied on Cinder to manage the window, but if I were to introduce Qt, they somehow have to share the Window and render context, and I honestly am a little lost at where to start. All ears if someone has some pointers.

As for why even do this? I’ve been looking for a C++ based Gui library that supports multi-touch which honestly isn’t easy to find. I’ve spent a few weeks with NoesisGui and found their WPF/Xaml approach difficult to work with, so I’m revisiting the question of which library to pick for the long haul. Qt isn’t exactly glamorous but it has pretty much everything you could want out of a basic GUI, I just have no idea of how to make it play nice along side Qt since they both seem to want to own the application window.

I use libcinder extensively for it’s wonderful OpenGl rendering classes, so while I’m ok with a solution where Qt becomes the main window ‘host’ so to speak, I don’t want to entirely give up on rendering some parts using libcinder.

Thanks in advance,
Gazoo

I think it would only be a pleasant setup if Qt handled all of the windowing and GL context setup. ci::gl has the ability to share OpenGL contexts, so you’ll have to dip into that if you want to use things like ci::gl::Batch or ci::gl::Fbo, etc. Doesn’t seem like there’s anything stop that though, and you can also still use any of cinder’s utility classes, ones that don’t realy on the ci::app or ci::gl namespaces.

Cheers,
Rich

Much appreciate the response @rich.e

I agree, I think Qt would behave best (if at all) it handles all the windowing and GL context setup as you mentioned. But… Is there any way to ‘start up’ cinder without the windowing and GL context created by libcinder?

I’m not familiar with any code or examples that achieve this…?

Cheers,
Gazoo

Cinder doesn’t need to be ‘started’ if you are not making an app::AppBase (subclassed for whatever platform you’re on). Since about 0.9.1 or so we separated out non-windowing functionality into the app::Platform global class that can be used for things like loading assets, setting up the base loggers, etc, so if you do need things like that it is still accessible. The original use case here was to command line based tools, such as HTTP clients and asset prepropcessors, but also for game engine plugins and things like that.

Also, if you do a code search for app::Platform::get() in the main cinder codebase, you’ll see that we use it throughout rather than app::whatever(), because Platform doesn’t assume that a windowing envirotnment exists.

The tricky part in getting this to work (which I think would be really cool, gaining the graphics power of cinder with the GUIs of QT), will be getting ci::gl::Context::createFromExisting() ([source line](https://github.com/cinder/Cinder/blob/8998b3f51ea4ef33a5b0e89567fbacd22b76a444/include/cinder/gl/Context.h#L82)) to work. Only code examples I see on a quick skim are how all of cinder's app::Renderer's use it when initializing their window. But keep in mind that cinder's ci::app::RendererGland friends are only meant to be used with aci::app::Window`, not what you want.

Noting the comment above that method here as well:

//! Creates based on an existing platform-specific GL context. \a platformContext is CGLContextObj on Mac OS X, EAGLContext on iOS, HGLRC on MSW. \a platformContext is an HDC on MSW and ignored elsewhere. Does not assume ownership of the platform’s context.

1 Like

I think I must have overlooked this reply @rich.e , as if nothing else I would have wanted to reach out and thank you for the insight. I had no idea that it was possible to actually leverage Cinder in a non-app capacity. I don’t think there’s a sample that illustrates this usage…? (Which admittedly would then require another windows handler)

Given that my Ui needs have a strong real-time component to them, I’ve opted to exploring using Coherent Labs Gameface Ui meant for real-time games.

It looks promising, but also a commercial product, so the pro is that it’s quite fleshed out, the con, even as a complete indie product, some cash needs to be dropped if I move forward with it.

Yea it hasn’t been tested to a great deal (a dedicated test would be nice), but the intent was to enable some features like asset loading, logging, system things for either command line apps or when using cinder in conjunction with other frameworks, game engines etc.

I just created this gist that is from one of the earliest uses of app::Platform without there being an instanciated app, which was for archiving assets in order to ship them within a production .exe (uses cereal). Basically leverages asset loading and logging.

Here is another more recent cmake setup where I’ve been exploring Diligent Engine for using modern day graphics APIs (DX 12 and vulkan) and also using select functionality from cinder. In this case, I decided to use GLFW to learn it a bit better (although I imagine using a ci::app::Renderer made for diligent will be the way to go in the long run), so I opted to exclude app::AppMsw and related files, and diligent is directly used for graphics. Just some ideas!

For your needs, I think you’ll have to figure out how to get the shared gl context thing working, which I believe is totally doable but will take experimenting as we don’t have any existing examples of doing that with Qt or other frameworks that I can think of.

Cheers,
Rich

@rich.e - I’ll definitely have to check out that Diligent Engine example at some point. That looks really cool.

As for the context sharing, the base problem I seem to run into (note the small sample size of 2 gui libraries) is that they don’t seem to maintain their own state of an OpenGL context like Cinder. Cinder pushes and pops OpenGL state changes when they happen, basically ‘cleaning up after itself’. The current libraries I’ve tried set a state and then expect anyone else who needs the state differently to ‘reset’ it, which seem counter-intuitive to me.

Thanks to another forum post, I’ve managed to make some headway, but am still running into some texture issues I’m trying to pin down which I’ll post about separately.