User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

Advice for sharing an OpenGL context with Noesis

31 Dec 2022, 13:00

Hello,

I'm intending to use Noesis purely for its GUI rendering, i.e. a different framework (Cinder) drives the underlying application aspects. I've progressed far enough to render a Hello World example as well as tie some functionality into the NoesisGUI.

Now I'm experimenting with relying on some of Cinder's rendering features to ease the burden of porting my work to NoesisGUI.

I've found that once I call NoesisApp::GLFactory::CreateDevice(), the rendering calls that Cinder make now cease to function. I'm assuming this is likely due to Noesis altering various OpenGL rendering settings.

I'm familiar with the ability to push/pop various settings in OpenGL - particularly its render matrices - but that functionality doesn't seem to be as applicable here as the changes to the rendering pipeline aren't all happening in the Draw() call, but instead in each of the two frameworks' way they initially setup OpenGL for all future rendering.

I find OpenGL debugging incredibly tedious and time-consuming, often ending up with just a black window if things aren't working, so I thought I'd just pose an open question if anyone else has had any experience and suggestions with saving/loading Noesis' (or other frameworks) entire OpenGL setting stack in order to switch between them if necessary?

Cheers,
Lasse
 
User avatar
jsantos
Site Admin
Posts: 3905
Joined: 20 Jan 2012, 17:18
Contact:

Re: Advice for sharing an OpenGL context with Noesis

02 Jan 2023, 13:11

Agree with you, debugging OpenGL is tedious. I recommend using RenderDoc, it can save hours of debugging.

In general, we don't recommend pushing and popping state using GL mechanisms because it is much faster if you restore the state on your side, manually. You have the source code of the renderer, so you can know exactly what states we are changing (or you can even modify the implementation).

The entry points where the GL state can be modified are:
  • GLRenderer constructor
  • IRenderer::RenderOffscreen()
  • IRenderer::Render()
Hope this helps.
 
User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

Re: Advice for sharing an OpenGL context with Noesis

02 Jan 2023, 16:16

Appreciate the advice and reply jsantos.

Using RenderDoc is good advice, perhaps it can help me pin down exactly the differences in OpenGL's state. Even with your helpful pinpointing of function calls to begin looking at (constructor, RenderOffscreen(), etc.), I still find it tricky at times quickly summarizing what calls actually matter to me/the OpenGL state.

You don't explicitly use the term 'context' in your response, so I thought I'd remove some ambiguity and list the approaches I see that'd make 2 different libraries - that modify the OpenGL state - work simultaneously:
  1. Give them each their own OpenGL context and switch between these whenever calling OpenGL related functions in either library.
  2. Rely on a single context, push and pop OpenGL state variables. My understanding is that OpenGL supports doing this 'nicely' with certain properties, such as matrices, and less 'nicely' with other ones like line width or such, where it's up to developer to query a value, store it, and then re-apply it later.
My understanding is you recommend approach 2, and furthermore to not use OpenGL's native push/pop support, yes?

While losing performance sucks, my primary concern is all the overhead I need to carry if pursuing option 2. I've been experimenting with option 1 and it so far seems promising. Do you think there would be any other concerns with option 1 other than performance loss?

Last but not least, if I were to pursue option 2, is state is all I have to worry about? I'm no OpenGL guru but I noticed that the Noesis provided GLRenderDevice also appears to have some memory allocation code. I wonder if more than just state might clash between 2 libraries fiddle with the same OpenGL context? Sorry that this question is a big vague.

Cheers,
Lasse
 
User avatar
jsantos
Site Admin
Posts: 3905
Joined: 20 Jan 2012, 17:18
Contact:

Re: Advice for sharing an OpenGL context with Noesis

03 Jan 2023, 13:55

My understanding is you recommend approach 2, and furthermore to not use OpenGL's native push/pop support, yes?
Yes, exactly, that's my recommendation. You could implement a InvalidateState() function of your side that should be called after entering the 3 Noesis points described above. I assume you will be caching GL state on your side, InvalidateState() should invalidate that cache.
While losing performance sucks, my primary concern is all the overhead I need to carry if pursuing option 2. I've been experimenting with option 1 and it so far seems promising. Do you think there would be any other concerns with option 1 other than performance loss?
If you are not an OpenGL expert, I don't recommend having two different contexts, because you will need to share resources (at least a render target texture) and that's a tricky part with potential driver issues too. It is also not compatible OpenGL ES, not sure if that's important to you.
Last but not least, if I were to pursue option 2, is state is all I have to worry about? I'm no OpenGL guru but I noticed that the Noesis provided GLRenderDevice also appears to have some memory allocation code. I wonder if more than just state might clash between 2 libraries fiddle with the same OpenGL context? Sorry that this question is a big vague.
You can extend our GLRenderDevice to have more control about the memory allocations, but in general, I would say that's not necessary, at least in the first integration.
 
User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

Re: Advice for sharing an OpenGL context with Noesis

09 Jan 2023, 17:33

Appreciate the reply jsantos.
If you are not an OpenGL expert, I don't recommend having two different contexts, because you will need to share resources (at least a render target texture) and that's a tricky part with potential driver issues too. It is also not compatible OpenGL ES, not sure if that's important to you.
Luckily Cinder does some of the heavy lifting with multiple-contexts, allowing one context to be created with a reference to a different context with which it must share resources, e.g.:
mContextCinderRender = ci::gl::context();
mContextNoesis = ci::gl::Context::create( mContextCinderRender );
mContextNoesis->makeCurrent();
That being said - I came across this informative post on reddit which elaborates on suddenly needing to potentially manage synchronization across both, if they do interact which, yeah, doesn't sound like fun at all.

The potential driver issues you mention also concern me. I wasn't able to google much concrete information on that matter though. Any personal experience you'd be open to sharing re. issues you've experienced?

OpenGL ES isn't something I plan on using, but the prior two points are likely already enough for me to at least spend a few days on seeing if I can't figure out how to manage the 2 differing states on my own, with a single shared context.

Cheers,
Gazoo
 
User avatar
jsantos
Site Admin
Posts: 3905
Joined: 20 Jan 2012, 17:18
Contact:

Re: Advice for sharing an OpenGL context with Noesis

10 Jan 2023, 15:12

The potential driver issues you mention also concern me. I wasn't able to google much concrete information on that matter though. Any personal experience you'd be open to sharing re. issues you've experienced?
At the very beginning we experimented with not sharing the client context and using a separate context for NoesisGUI. We found many issues (including performance ones), I don't remember specific details right now, but enough problems to recommend avoiding that path.

We also released a Vulkan renderer in the current 3.2 beta. If possible we recommend moving to Vulkan.

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 71 guests