3
votes

I have a Windows app which can create several view windows which can render some models using OpenGL (3.2+). Each window can either render it's own independent object, or two (or more) windows can render the same object (but for example from different camera perspectives):

example

After reading various posts here on stackoverflow I decided to create a single OpenGL context (HGLRC), and for each window that I am rendering to (HDC) I switch with

wglMakeCurrent(targetWindowHDC, m_deviceContext)

As you can see in the screenshot, that principally seems to work fine (the window code is happening on the main thread, and for Rendering I have my own RenderThread to which all the OpenGL operations are limited to). For each of the windows I render to an FBO (which has MSAA support if the user activates it), which only gets updated in case something in the scene changes, otherwise it will just draw it to the window as is.

My question is now, what states do I have to set every time I switch to drawing to another window? And is my approach reasonable in terms of performance?

This is what I now set every time after I make the context current for another HDC:

glClearDepth( 1.0f );
glClearColor( color.r, color.g, color.b, 1.0f );
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
glPointSize(3.0f);
glEnable(GL_BLEND);
glBlendFunc( srcBlend, dstBlend );
glPolygonMode( GL_FRONT_AND_BACK, targetType );
glEnable( GL_CULL_FACE );
glCullFace( GL_BACK );    
glViewport( 0, 0, vp.width, vp.height );

These are basically all the settings that could be changed when the user sets up the render windows, so I need to be sure they are set correctly before rendering each window.

But is it really necessary to do all those calls? It means in the above example with 4 render windows I need to call those 4 times each frame. Is there a better way? Would it be more efficient with several GL contexts?

1
If for example glDepthFunc stays the same throughout all four render windows then there is no need to set it for each window! Just set it once at the start of the render loop.Eejin
Thanks for your feedback. Well the problem is that I don't know if it changes, a user can create new windows in his app which I don't know about beforehand, and set different attributes to each RenderView. Was wondering if there is some equivalent to a VAO or so which could be used to compact the calls into a single oneBjoern

1 Answers

4
votes

The absolute minimum set of state you need to track between windows is the viewport, clearing color, color and depth masks, depth test function and depth range; you've got those covered in your code snippet already, so you're good.

Most other OpenGL state should be set on-demand right before it's needed anyway (and also cleaned up when no longer needed). So I'd say setting blend modes, face culling and so on actually is superfluous in your snippet.


Using the same context for multiple windows makes sense if the kind of rendering is the same for all the windows. For example in a typical 3D modeler there's a "quad view". If those subviews are implemented using multiple windows, then reusing a single context makes sense.

I'm one of those guys who keeps reminding people, that there's no need to have a separate OpenGL context for each window. That doesn't mean doing this is a bad thing if it makes your life simpler.

If your concern is about multiple windows with largely different rendering settings, then using separate render contexts is sensible.

So how do you decide if to use multiple context or a single one. Well, that's easy:

If the windows are sharing much of the render code and conceptually show the same thing (the same scene from different vantage points, different objects that make use of the same texture and are rendered using the same code) then context reuse it is.

If the contents of the windows differ a lot, then multiple contexts.