306 lines
11 KiB
HTML
306 lines
11 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<TITLE>A Simple Scene Graph API for OpenGL.</TITLE>
|
|
</HEAD>
|
|
<BODY text="#B5A642" link="#8FFF8F" vlink="#18A515" alink="#20336B"
|
|
bgcolor="#005000" background="../marble.png">
|
|
|
|
<H2><code>class ssgLeaf</code> - Leaf nodes.</h2>
|
|
Leaf nodes are those that actually make OpenGL calls
|
|
or take other 'rendering' actions - they contain
|
|
all of the geometric information in the scene.
|
|
<pre>
|
|
|
|
class ssgLeaf : public ssgEntity
|
|
{
|
|
public:
|
|
int getExternalPropertyIndex ()
|
|
int isTranslucent ()
|
|
int hasState ()
|
|
ssgState *getState ()
|
|
void setState ( ssgState *st )
|
|
|
|
virtual float *getVertex ( int i )
|
|
virtual float *getNormal ( int i )
|
|
virtual float *getColour ( int i )
|
|
virtual float *getTexCoord ( int i )
|
|
|
|
virtual int getNumTriangles() ;
|
|
virtual void getTriangle ( int n, short *v1, short *v2, short *v3 )
|
|
|
|
virtual int getNumLines () ;
|
|
virtual void getLine ( int n, short *v1, short *v2 ) ;
|
|
|
|
int getNumLines () ;
|
|
void getLine ( int n, short *v1, short *v2 ) ;
|
|
|
|
virtual void transform ( sgMat4 m )
|
|
|
|
void setCullFace ( int cf )
|
|
int getCullFace ()
|
|
|
|
void makeDList () ;
|
|
void deleteDList () ;
|
|
GLuint getDListIndex () ;
|
|
} ;
|
|
|
|
</pre>
|
|
|
|
<H3>Pre- and Post-Draw Callbacks.</H3>
|
|
It's frequently useful to have an application function called
|
|
just before and/or just after a leaf node is rendered.
|
|
<pre>
|
|
|
|
typedef int (*ssgCallback)( ssgEntity * ) ;
|
|
ssgCallback getCallback ( int which ) ;
|
|
void setCallback ( int which, ssgCallback cb ) ;
|
|
|
|
</pre>
|
|
(Where 'which' is either SSG_CALLBACK_PREDRAW for a function that's
|
|
to be called before the node is drawn or SSG_CALLBACK_POSTDRAW for
|
|
one that's called after rendering.) In both cases, the function will
|
|
be passed a pointer to the leaf node that's about to be drawn, and
|
|
(in the case of PREDRAW callbacks), may return FALSE to prevent the
|
|
node from being drawn, or TRUE to have it draw normally.
|
|
<H3>Display Lists</H3>
|
|
A leaf node is normally rendered in 'immediate' mode in OpenGL,
|
|
so that changes you make to the leaf will be reflected on the
|
|
screen on the next occasion that it's drawn. However, on some
|
|
graphics hardware, it's more efficient to create an OpenGL
|
|
display list for each leaf node. This can be managed by
|
|
calling <code>ssgLeaf::makeDList()</code>. If you want to
|
|
make changes to the Leaf, you'll have to call makeDList again
|
|
since OpenGL does not support the editing of display lists.
|
|
<p>
|
|
You can call <code>ssgLeaf::deleteDList()</code> to stop
|
|
this leaf from being display listed from now on and to
|
|
free up the display list memory.
|
|
<code>ssgLeaf::getDListIndex()</code> returns the OpenGL
|
|
display list handle - or zero if no display list exists
|
|
for this leaf.
|
|
<p>
|
|
If you change a leaf node's geometry when it has an
|
|
active display list without calling either deleteDList
|
|
or makeDList again, then any subsequent operation
|
|
involving rendering this node could fail.
|
|
|
|
<H3>Face Culling.</H3>
|
|
By default, ssgLeaf nodes are back-face culled, you can change
|
|
that for any given node using <code>ssgLeaf::setCullFace(cf)</code>
|
|
where <code>cf</code> is TRUE to enable backface culling,
|
|
FALSE to disable it. You can test the state of face culling
|
|
using <code>ssgLeaf::getCullFace()</code>.
|
|
<H3>State Management.</H3>
|
|
OpenGL supports a wide selection of state information - things like
|
|
texture, materials and such. All of this information is held in a
|
|
separate SSG class hierarchy: 'ssgState'. Each leaf has a state
|
|
which it sets up before drawing the geometry that the leaf contains.
|
|
<p>
|
|
Nodes may also be stateless - but that isn't useful for any
|
|
of the existing SSG leaf node types.
|
|
<p>
|
|
You can set the state for a node using <code>ssgLeaf::setState(state)</code>
|
|
and query it using <code>ssgLeaf::getState()</code>. You can ask if
|
|
a node has state information attached using <code>ssgLeaf::hasState()</code>.
|
|
<p>
|
|
Since OpenGL does not render translucent object well when Z-buffering
|
|
is enabled, it's often useful to know if an object is translucent.
|
|
<code>ssgLeaf::isTranslucent()</code> handles that test.
|
|
<p>
|
|
It is often useful to tag ssgState's with external properties - and
|
|
you can retrieve the property of a leaf's state using
|
|
<code>ssgLeaf::getExternalPropertyIndex()</code>.
|
|
<H3>Querying Geometry</H3>
|
|
The actual storage format for geometry in classes derived from
|
|
ssgLeaf varies from class to class. However, it's very useful
|
|
to be able to query the geometry in an implementation-independent
|
|
manner.
|
|
<p>
|
|
Although classes derived from ssgLeaf are entitled to store their
|
|
geometry in any form, all of them are required to respond to
|
|
queries about basic triangle primitives.
|
|
<p>
|
|
Firstly, you can get a count of the number of triangles in this
|
|
leaf using <code>ssgLeaf::getNumTriangles()</code>. Each triangle
|
|
has an index number for each vertex which can be queried using
|
|
<code>ssgLeaf::getTriangle(n,&v1,&v2,&v3)</code> which copies
|
|
the 'short' indices for the n'th triangle's three vertices into
|
|
v1, v2 and v3.
|
|
<p>
|
|
Once you know the indices of a triangle's vertices, you can ask for
|
|
more information about that vertex using
|
|
<code>ssgLeaf::getVertex(i)</code>,
|
|
<code>ssgLeaf::getNormal(i)</code>,
|
|
<code>ssgLeaf::getColour(i)</code>, and
|
|
<code>ssgLeaf::getTexCoord(i)</code>. These calls allow you to
|
|
retrieve the i'th vertex, normal, colour or texture coordinate as
|
|
a short floating point array. (3 elements for Vertex and Normal,
|
|
4 elements for Colour (RGBA) and two elements for a texture coordinate.
|
|
<p>
|
|
Analogous to getting the triangles,
|
|
you may use <code>ssgLeaf::getNumLines ()</code>
|
|
and <code>ssgLeaf::getLine ( int n, short *v1, short *v2 ) ;</code>
|
|
to get the number of lines and to get the n. line.
|
|
|
|
<p>
|
|
You can transform all the vertices of a leaf each frame by placing
|
|
an ssgTransform node above the leaf in the scene graph - but for
|
|
transformations that never change, it's more efficient to pre-transform
|
|
the vertices in the leaf node.
|
|
<code>ssgLeaf::transform(matrix)</code> permenantly transforms all
|
|
the vertices and normals of this leaf by multiplying them by the
|
|
matrix. (In the case of the normals, the translation part of the
|
|
matrix is ignored).
|
|
<p>
|
|
It's inadvisable to repeatedly transform a leaf using <code>transform</code>
|
|
since roundoff error will be accumulated with bad consequences (eventually).
|
|
In those cases, use an ssgTransform node.
|
|
|
|
<H2><code>class ssgVtxTable</code> - A Vertex-table leaf node.</H2>
|
|
This class allows one to represent leaf geometry as arrays of vertex,
|
|
normal, texture coordinate and colour data. As a derived class of
|
|
ssgLeaf, Vertex Tables add a constructor function to take the
|
|
pre-computed vertex data:
|
|
<pre>
|
|
|
|
ssgVtxTable ( GLenum ty, ssgVertexArray *vl,
|
|
ssgNormalArray *nl,
|
|
ssgTexCoordArray *tl,
|
|
ssgColourArray *cl ) ;
|
|
|
|
</pre>
|
|
'ty' is an OpenGL primitive type (such as one might pass to glBegin):
|
|
<pre>
|
|
|
|
GL_POLYGON
|
|
GL_TRIANGLE_FAN
|
|
GL_TRIANGLES
|
|
GL_TRIANGLE_STRIP
|
|
GL_QUAD_STRIP
|
|
GL_QUADS
|
|
|
|
</pre>
|
|
the remaining arguments are lists of (x,y,z) vertices, (nx,ny,nz)
|
|
normals, (s,t) texture coordinates and (r,g,b,a) colours.
|
|
<H2><code>class ssgVertexArray/ssgNormalArray/ssgTexCoordArray/ssgColourArray</code> - Vertex data storage classes.</H2>
|
|
These four classes are used for storing vertex data for ssgVtxTable nodes.
|
|
Each class implements an extensible array that grows as you add data to
|
|
it.
|
|
<pre>
|
|
|
|
ssg*Array::ssg*Array ( int init = 3 ) ;
|
|
|
|
</pre>
|
|
When you construct the array, you may specify an initial size for it,
|
|
the default is three elements. If you don't know how big the array
|
|
is, don't worry about it - but if you do know, there are time and
|
|
storage space advantages to telling the class the exact number.
|
|
<pre>
|
|
|
|
void ssgVertexArray ::add ( sgVec3 data ) ;
|
|
void ssgNormalArray ::add ( sgVec3 data ) ;
|
|
void ssgTexCoordArray::add ( sgVec2 data ) ;
|
|
void ssgColourArray ::add ( sgVec4 data ) ;
|
|
|
|
</pre>
|
|
These functions tack another data element onto the end of the array.
|
|
<pre>
|
|
|
|
float *ssg*Array::get ( int i ) ;
|
|
|
|
</pre>
|
|
Returns the address of the i'th element of the array.
|
|
<pre>
|
|
|
|
int ssg*Array::getNum () ;
|
|
|
|
</pre>
|
|
Returns the number of data elements currently stored in the array.
|
|
<pre>
|
|
|
|
void ssg*Array::removeAll () ;
|
|
|
|
</pre>
|
|
Empties the array.
|
|
<H2><code>class ssgTween</code> - A Vertex-table morphing node.</H2>
|
|
This node is derived from ssgVtxTable. Where VtxTable can retain
|
|
a set of arrays, one each for Vertex coordinates, Normals, Texture
|
|
Coordinates and Colours, the ssgTween node can store an unlimited
|
|
number of 'banks' of these arrays.
|
|
<p>
|
|
Hence, one constructs an ssgTween by specifying it's OpenGL primitive
|
|
type:
|
|
<pre>
|
|
|
|
ssgTween::ssgTween ( GLenum ty ) ;
|
|
|
|
</pre>
|
|
And then create some number of 'banks' of data arrays by calling:
|
|
<pre>
|
|
|
|
int ssgTween::newBank ( ssgVertexArray *vl,
|
|
ssgNormalArray *nl,
|
|
ssgTexCoordArray *tl,
|
|
ssgColourArray *cl ) ;
|
|
|
|
</pre>
|
|
...once for each bank. All other ssgVtxTable calls operate ONLY
|
|
on the 'current bank' - which is either the most recent one you
|
|
created with newBank - or you can go back to an older bank by
|
|
calling:
|
|
<pre>
|
|
|
|
void ssgTween::setBank ( int bankID ) ;
|
|
int ssgTween::getBank () ;
|
|
|
|
</pre>
|
|
(newBank returns the number of the bank it created in case you
|
|
lose count!).
|
|
<p>
|
|
ssgTween's idea of the 'current bank' is reset to zero after
|
|
rendering it...so be sure to always call setBank immediately
|
|
before working on it's component arrays.
|
|
<p>
|
|
When the ssgTween node is rendered, it works cooperatively
|
|
with whichever ssgTweenController node is above it in the
|
|
scene graph. See the section on ssgTweenController for more
|
|
details.
|
|
<p>
|
|
IMPORTANT NOTE: There must be an identical number of vertices,
|
|
normals, etc in each bank. If you get that wrong, SSG will
|
|
exit with an 'abort'. Note that there is a specific optimisation
|
|
in ssgTween that avoids the computational cost of interpolating
|
|
between two sets of vertex data if EITHER:
|
|
<ul>
|
|
<li>The ssgTweenController's selected bank number happens to
|
|
be an integer.
|
|
<li>The previous and next banks have the same ssg*Array pointer.
|
|
Since one generally doesn't wish to interpolate normals, colours
|
|
or texture coordinates, it's important to pay attention to this.
|
|
</ul>
|
|
<hr>
|
|
<table width="100%">
|
|
<tr>
|
|
<td width="33%" align="left"><a href="ssgEntity.html"><= previous =</a></td>
|
|
<td width="34%" align="center"><a href="index.html">Return to SSG Index</a></td>
|
|
<td width="33%" align="right"><a href="branches.html">= next =></a></td>
|
|
</tr>
|
|
</table>
|
|
<hr>
|
|
<table>
|
|
<tr>
|
|
<td>
|
|
<a href="http://validator.w3.org/check/referer"><img border="0" src="../valid-html40.png" alt="Valid HTML 4.0!" height="31" width="88"></a>
|
|
<td>
|
|
<ADDRESS>
|
|
<A HREF="http://www.sjbaker.org">
|
|
Steve J. Baker.</A>
|
|
<<A HREF="mailto:sjbaker1@airmail.net">sjbaker1@airmail.net</A>>
|
|
</ADDRESS>
|
|
</table>
|
|
</BODY>
|
|
</HTML>
|
|
|