graphicslib
Intro
Discussion
Efficiency
Example
Source
History
TODO
I wanted an object oriented graphics library. So I started making OpenGL function calls into objects, and placing them on a global stack. This technique is very generic and can turn a procedure based API into a fully object orientated environment.
This has resulted in a very flexible and powerful graphics library. See gobj.h. A container class made making a scenegraph easy so by remembering where the objects are in a stack by indexing into the stack parameters can be changed, new geometry added and deleted, ... So this data structure is both a stack and trees in a stack.
All the code produced with this library is essentailly OpenGL. So it does not re interpret graphics and can be easily updated for the next version of OpenGL. The same technique could have been used on other graphics libraries.
The motivation is to give the programmer complete control and OOP is needed to do this. You can easily write your own graphics objects. You can employ advanced memory management strategies, upteenth versions of smart pointers. Stack based programming is amazing.
Having each function call wrapped in an object is expensive. However there is nothing to stop you writing a geometric object in the standard OpenGL way and puting that code with many OpenGL calls as a gobj. This is a standard technique used in OOP anyway.
You can also compile the graphics into display lists. The versatility of the stack was why I liked it most. I do not like seeing hard coded function calls in code because the code is always time consuming to modify or change, indeed code written this way is built never to change.
Another strategy I am persuing is to use templates to eliminate virtual function calls. This is inherently hard but as computers get faster the difference between virtual and non-virtual function calls gets greater. And I really want C++ to compete with C so it truely does what C does and is OO too.
To me OOP makes me a much more productive programmer. So while writing a OpenGL function into an object is expensive the positive is an increase in programming freedom. If I encounter a problem where the graphics are too slow I rewrite the object. For example in displaying tessellations I have two graphics containers, one for static geometry and the other for dynamic geometry. In this case the static geometry does change, but less frequently so its updated only when a change occures. The point is that a technique to address the bottleneck is more important if it can solve the bottleneck.
I needed graphics of a mesh that was changing over time. So if I put it on the global stack I would face the problem of not being able to easily delete it and remake the mesh.
By using a gobjContainer object - name the object
dynamicgraphics variable, and placing it on the stack instead
of all the other graphics then only this container needs to be re-emptied
and renewed. This is done by keeping a pointer to the container either
directly, or an integer index to the container from the stack base and
providing you do not delete any elements below its valid.
So while its good to have this new container, how do I have code that
uses it? For example the way I currently write graphics is to write
to the global graphics container
gobjContainer::global
because every class assumes its existence.
I do not want to tie any other containers to the classes where possible.
Again using stack processing solves this. Before you call the target code which will write to the global graphics container record the containers size. Call the target code. Clean the dynamicgraphics variable by calling nuke. Then move the newely created graphics from the global graphics container restoring it to its size prior to the target call.
As people will point out there are better ways to do this update. Well this is an OO environment so whatever you want you can write yourself. I'm not stopping you.
gobjSwitch and
gobjSwitchContainer to be able to turn
on and off the gobj's in the scene.
glerrordisplay() is used
to track down matrix stack corruption/overflow
by spreading it liberally throughout the code.
glGetIntegerv,
glGetError ,glGetString in gobj.h . Immediate drawing,
class hat {
void myshape()
{
glColor3f(1.0,0.0,0.0); ...
...
// main program
hat h1;
gobjpush( gobjcallbackcreatenew(h1,&hat::myshape) );
} };