| 1 |
#include <OSGConfig.h> |
|---|
| 2 |
|
|---|
| 3 |
using namespace OSG; |
|---|
| 4 |
|
|---|
| 5 |
/*! \page PageSystemOGLObjects OpenGL Objects & Extension Handling |
|---|
| 6 |
|
|---|
| 7 |
\section PageSystemOGLObj OpenGL Objects |
|---|
| 8 |
|
|---|
| 9 |
OpenGL objects are an important way to manage data and speed up repetitive use. |
|---|
| 10 |
OpenGL objects in OpenSG include everything that can be stored inside |
|---|
| 11 |
OpenGL, most prominently display lists and texture objects. |
|---|
| 12 |
|
|---|
| 13 |
Handling OpenGL objects in a multi-window and possibly multi-pipe environment |
|---|
| 14 |
becomes an interesting problem. As the different windows may show different |
|---|
| 15 |
parts of a scene or different scenes alltogether the actually used and defined |
|---|
| 16 |
set of OpenGL objects should include only what's necessary to reduce the |
|---|
| 17 |
consumed ressources. |
|---|
| 18 |
|
|---|
| 19 |
To do that OpenGL objects are managed by the OpenSG Windows. Before they are |
|---|
| 20 |
used they have to be registered with the osg::Window class. This is a static |
|---|
| 21 |
operation on the Window class, as it affects all exisiting Windows. Multiple |
|---|
| 22 |
objects can be registered in one call, and they will receive consecutive |
|---|
| 23 |
object ids. The ids are assigned by the object manager. It can not be queried |
|---|
| 24 |
from OpenGL, as the thread which creates the objects usually doesn't have a |
|---|
| 25 |
valid OpenGL context. As a consequence you should not use OpenGL-assigned ids, |
|---|
| 26 |
as they might interfere with OpenSGs handling of ids. |
|---|
| 27 |
|
|---|
| 28 |
Part of the registration is to provide an update osg::Functor, which is called |
|---|
| 29 |
whenever the object needs to be updated. This functor gets passed the id and |
|---|
| 30 |
status of the object and has to execute the correct function. There are a |
|---|
| 31 |
number of stati that the functor has to handle. |
|---|
| 32 |
|
|---|
| 33 |
The first time it is called the status be osg::Window::GLObjectE::initialize. |
|---|
| 34 |
The functor has to create the necessary OpenGL ressources and initialize the |
|---|
| 35 |
OpenGL object. For a texture object this is the definition of the image via |
|---|
| 36 |
glTexImage(). |
|---|
| 37 |
|
|---|
| 38 |
When the object changes there are two cases to distinguish. In the simple case |
|---|
| 39 |
the object has changed significantly, needing a |
|---|
| 40 |
osg::Window::GLObjectE::reinitialize. For textures this would be changing the |
|---|
| 41 |
filter or changing the image size. Both of these actions necessitate a |
|---|
| 42 |
recreation of the actual texture object. If only the data of the image changes |
|---|
| 43 |
this can be handledmore efficiently via glTexSubImage() calls, which is an |
|---|
| 44 |
example for a osg::Window::GLObjectE::refresh. The osg::Window is responsible |
|---|
| 45 |
for keeping track of the current of the objects, and thus it has to be |
|---|
| 46 |
notified whenever the state of the OpenSG object underlying an OpenGL has |
|---|
| 47 |
changed, necessitating either a refresh or a reinitialize. This can be done by |
|---|
| 48 |
calling the static osg::Window::refreshGLObject or |
|---|
| 49 |
osg::Window::reinitializeGLObject methods. The object will be flagged as |
|---|
| 50 |
changed in all Windows and at the next validate time it will be |
|---|
| 51 |
refreshed/recreated. |
|---|
| 52 |
|
|---|
| 53 |
Before an object can be used it has to be validated. This has to be done when |
|---|
| 54 |
the OpenGL context is valid and should usually be done just before the object |
|---|
| 55 |
is used. If the object is still valid, nothing happens. The |
|---|
| 56 |
osg::Window::validateObject method is inline and thus the overhead of calling |
|---|
| 57 |
it before every use is minimal. |
|---|
| 58 |
|
|---|
| 59 |
When an object is not needed any more is needs to be destroyed. The |
|---|
| 60 |
destruction can be started via osg::Window::destroyGLObject. It will actually |
|---|
| 61 |
be executed the next time a Window has finished rendering (i.e. its |
|---|
| 62 |
osg::Window::frameExit() function is called). The object's functor will be |
|---|
| 63 |
called for the osg::Window::GLObjectE::destroy state, and it should free |
|---|
| 64 |
context-specific resources. After this has happened for all Windows it will be |
|---|
| 65 |
called one final time with osg::Window::GLObjectE::finaldestroy. Here |
|---|
| 66 |
context-independent resources can be freed. |
|---|
| 67 |
|
|---|
| 68 |
\section PageSystemOGLExt OpenGL Extensions |
|---|
| 69 |
|
|---|
| 70 |
The situation with OpenGL extensions is similar to the one with OpenGL objects: |
|---|
| 71 |
as the thread that initializes things probably has no OpenGl context, it cannot |
|---|
| 72 |
call the necessary OpenGL functions directly. Further complicating matters is |
|---|
| 73 |
the fact that in systems with multiple graohics cards they may not all be of |
|---|
| 74 |
the same type, and thus might support different extensions. |
|---|
| 75 |
|
|---|
| 76 |
To handle these situations the extensions themselves and the extension |
|---|
| 77 |
functions need to be registered and accessed using the osg::Window. The |
|---|
| 78 |
registration (osg::Window::registerExtension, osg::Window::registerFunction) |
|---|
| 79 |
just needs the names and returns a handle that has to be be used to access the |
|---|
| 80 |
extensions/functions. This registration can be done from any thread. |
|---|
| 81 |
|
|---|
| 82 |
When using the extension/function it is necessary to check if it supported on |
|---|
| 83 |
the currently active OpenGL context. To speed this up the Window caches the |
|---|
| 84 |
test results and provides the osg::Window::hasExtension method to check it. |
|---|
| 85 |
To access the functions osg::Window::getFunction method can be used. It is not |
|---|
| 86 |
advisable to store the received extension functions, as there is no guarantee |
|---|
| 87 |
that the pointer will be the same for different contexts. |
|---|
| 88 |
|
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 |
*/ |
|---|