#include <OSGConfig.h>

using namespace osg;

/*! \page PageSystemOGLObjects OpenGL Objects & Extension Handling

\section PageSystemOGLObj OpenGL Objects

OpenGL objects are an important way to manage data and speed up repetitive use.
OpenGL objects in OpenSG include everything that can be stored inside
OpenGL, most prominently display lists and texture objects.

Handling OpenGL objects in a multi-window and possibly multi-pipe environment
becomes an interesting problem. As the different windows may show different
parts of a scene or different scenes alltogether the actually used and defined
set of OpenGL objects should include only what's necessary to reduce the
consumed ressources.

To do that OpenGL objects are managed by the OpenSG Windows. Before they are
used they have to be registered with the osg::Window class. This is a static
operation on the Window class, as it affects all exisiting Windows. Multiple
objects can be registered in one call, and they will receive consecutive
object ids. The ids are assigned by the object manager. It can not be queried
from OpenGL, as the thread which creates the objects usually doesn't have a
valid OpenGL context. As a consequence you should not use OpenGL-assigned ids,
as they might interfere with OpenSGs handling of ids.

Part of the registration is to provide an update osg::Functor, which is called
whenever the object needs to be updated. This functor gets passed the id and
status of the object and has to execute the correct function. There are a
number of stati that the functor has to handle.

The first time it is called the status be osg::Window::GLObjectE::initialize.
The functor has to create the necessary OpenGL ressources and initialize the
OpenGL object. For a texture object this is the definition of the image via
glTexImage(). 

When the object changes there are two cases to distinguish. In the simple case
the object has changed significantly, needing a
osg::Window::GLObjectE::reinitialize. For textures this would be changing the
filter or changing the image size. Both of these actions necessitate a
recreation of the actual texture object. If only the data of the image changes
this can be handledmore efficiently via glTexSubImage() calls, which is an
example for a osg::Window::GLObjectE::refresh. The osg::Window is responsible
for keeping track of the current of the objects, and thus it has to be
notified whenever the state of the OpenSG object underlying an OpenGL has
changed, necessitating either a refresh or a reinitialize. This can be done by
calling the static osg::Window::refreshGLObject or
osg::Window::reinitializeGLObject methods. The object will be flagged as
changed in all Windows and at the next validate time it will be
refreshed/recreated.

Before an object can be used it has to be validated. This has to be done when
the OpenGL context is valid and should usually be done just before the object
is used. If the object is still valid, nothing happens. The
osg::Window::validateObject method is inline and thus the overhead of calling
it before every use is minimal.

When an object is not needed any more is needs to be destroyed. The
destruction can be started via osg::Window::destroyGLObject. It will actually
be executed the next time a Window has finished rendering (i.e. its
osg::Window::frameExit() function is called). The object's functor will be
called for the osg::Window::GLObjectE::destroy state, and it should free
context-specific resources. After this has happened for all Windows it will be
called one final time with osg::Window::GLObjectE::finaldestroy. Here
context-independent resources can be freed.

\section PageSystemOGLExt OpenGL Extensions

The situation with OpenGL extensions is similar to the one with OpenGL objects:
as the thread that initializes things probably has no OpenGl context, it cannot
call the necessary OpenGL functions directly. Further complicating matters is
the fact that in systems with multiple graohics cards they may not all be of
the same type, and thus might support different extensions.

To handle these situations the extensions themselves and the extension
functions need to be registered and accessed using the osg::Window. The
registration (osg::Window::registerExtension, osg::Window::registerFunction)
just needs the names and returns a handle that has to be be used to access the
extensions/functions. This registration can be done from any thread.

When using the extension/function it is necessary to check if it supported on
the currently active OpenGL context. To speed this up the Window caches the
test results and provides the osg::Window::hasExtension method to check it.
To access the functions osg::Window::getFunction method can be used. It is not
advisable to store the received extension functions, as there is no guarantee
that the pointer will be the same for different contexts.



*/
