class ssgLeaf
- Leaf nodes.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 () ; } ;
typedef int (*ssgCallback)( ssgEntity * ) ; ssgCallback getCallback ( int which ) ; void setCallback ( int which, ssgCallback cb ) ;(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.
ssgLeaf::makeDList()
. 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.
You can call ssgLeaf::deleteDList()
to stop
this leaf from being display listed from now on and to
free up the display list memory.
ssgLeaf::getDListIndex()
returns the OpenGL
display list handle - or zero if no display list exists
for this leaf.
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.
ssgLeaf::setCullFace(cf)
where cf
is TRUE to enable backface culling,
FALSE to disable it. You can test the state of face culling
using ssgLeaf::getCullFace()
.
Nodes may also be stateless - but that isn't useful for any of the existing SSG leaf node types.
You can set the state for a node using ssgLeaf::setState(state)
and query it using ssgLeaf::getState()
. You can ask if
a node has state information attached using ssgLeaf::hasState()
.
Since OpenGL does not render translucent object well when Z-buffering
is enabled, it's often useful to know if an object is translucent.
ssgLeaf::isTranslucent()
handles that test.
It is often useful to tag ssgState's with external properties - and
you can retrieve the property of a leaf's state using
ssgLeaf::getExternalPropertyIndex()
.
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.
Firstly, you can get a count of the number of triangles in this
leaf using ssgLeaf::getNumTriangles()
. Each triangle
has an index number for each vertex which can be queried using
ssgLeaf::getTriangle(n,&v1,&v2,&v3)
which copies
the 'short' indices for the n'th triangle's three vertices into
v1, v2 and v3.
Once you know the indices of a triangle's vertices, you can ask for
more information about that vertex using
ssgLeaf::getVertex(i)
,
ssgLeaf::getNormal(i)
,
ssgLeaf::getColour(i)
, and
ssgLeaf::getTexCoord(i)
. 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.
Analogous to getting the triangles,
you may use ssgLeaf::getNumLines ()
and ssgLeaf::getLine ( int n, short *v1, short *v2 ) ;
to get the number of lines and to get the n. line.
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.
ssgLeaf::transform(matrix)
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).
It's inadvisable to repeatedly transform a leaf using transform
since roundoff error will be accumulated with bad consequences (eventually).
In those cases, use an ssgTransform node.
class ssgVtxTable
- A Vertex-table leaf node.ssgVtxTable ( GLenum ty, ssgVertexArray *vl, ssgNormalArray *nl, ssgTexCoordArray *tl, ssgColourArray *cl ) ;'ty' is an OpenGL primitive type (such as one might pass to glBegin):
GL_POLYGON GL_TRIANGLE_FAN GL_TRIANGLES GL_TRIANGLE_STRIP GL_QUAD_STRIP GL_QUADSthe remaining arguments are lists of (x,y,z) vertices, (nx,ny,nz) normals, (s,t) texture coordinates and (r,g,b,a) colours.
class ssgVertexArray/ssgNormalArray/ssgTexCoordArray/ssgColourArray
- Vertex data storage classes.ssg*Array::ssg*Array ( int init = 3 ) ;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.
void ssgVertexArray ::add ( sgVec3 data ) ; void ssgNormalArray ::add ( sgVec3 data ) ; void ssgTexCoordArray::add ( sgVec2 data ) ; void ssgColourArray ::add ( sgVec4 data ) ;These functions tack another data element onto the end of the array.
float *ssg*Array::get ( int i ) ;Returns the address of the i'th element of the array.
int ssg*Array::getNum () ;Returns the number of data elements currently stored in the array.
void ssg*Array::removeAll () ;Empties the array.
class ssgTween
- A Vertex-table morphing node.Hence, one constructs an ssgTween by specifying it's OpenGL primitive type:
ssgTween::ssgTween ( GLenum ty ) ;And then create some number of 'banks' of data arrays by calling:
int ssgTween::newBank ( ssgVertexArray *vl, ssgNormalArray *nl, ssgTexCoordArray *tl, ssgColourArray *cl ) ;...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:
void ssgTween::setBank ( int bankID ) ; int ssgTween::getBank () ;(newBank returns the number of the bank it created in case you lose count!).
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.
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.
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:
<= previous = | Return to SSG Index | = next => |
Steve J. Baker. <sjbaker1@airmail.net> |