matus-chochlik / oglplus

OGLplus is a collection of open-source, cross-platform libraries which implement an object-oriented facade over the OpenGL® (version 3 and higher) and also OpenAL® (version 1.1) and EGL (version 1.4) C-language APIs. It provides wrappers which automate resource and object management and make the use of these libraries in C++ safer and more convenient.
http://oglplus.org/
Boost Software License 1.0
491 stars 72 forks source link

Create an OpenGL state management class #88

Open jherico opened 9 years ago

jherico commented 9 years ago

One of the biggest impediments to using or creating OpenGL libraries is the issue of state management. For a library to do anything interesting, it typically needs to touch the OpenGL state machine and change settings. However, this is problematic, because aggressively making lots of calls to get the state you want is bad, and forces the library caller to aggressively restore state.

On the other hand, changing state only when needed and restoring changed states is problematic, because glGet calls will often trigger flushes and introduce stalls in the rendering pipeline.

A solution would be to provide a class that can track state changes and essentially provide on the CPU side the state pushing and popping functionality that has been deprecated in modern OpenGL.

This kind of class would be useful both for writing GL based libraries using oglplus, as well as for applications that use oglplus and might need to use libraries that don't. For the latter, a debugging mode could allow application writers to make calls into a GL based library and then determine what states had been changed by the library, and thus wrap such library calls in a mechanism that would restore those states on the return from the call.

matus-chochlik commented 9 years ago

I've made some progress in regard to this issue; I've added the ClientContext class which maintains a stack for each GL state variable and allows to push/pop and get/set their values independently. If the user sets a new value for a context variable, the current value is checked and the GL state is changed only if the new value is different from the top of the stack.

This is currently still work-in-progress and only a subset of the whole GL state is implemented, but one of the examples (example/oglplus/002_rect.cpp) has already been updated to show the usage.

In order to work properly one instance of ClientContext per each GL context must be created and it must be used exclusively to manipulate the state of any such context, otherwise it will go out of sync with the actual GL state. Also ClientContext is quite heavyweight and in the constructor it queries the state of each maintained GL state variable, so the construction is a rather expensive operation (as is to be expected).

There is one problem though; because of a bug [1], MSVC currently fails to compile the ClientContext class and all workarounds I've found so far are rather ugly. It works without problems on g++ and clang++.

[1] http://stackoverflow.com/questions/25069219/possible-visual-studio-c-compiler-bug-trouble-with-template-template-non-typ

jherico commented 9 years ago

I'll take a look.