2003-03-15 04:35:45 +08:00
# include <osg/Geode>
# include <osg/TexGen>
# include <osg/Texture2D>
# include <osgDB/ReadFile>
# include <osgProducer/Viewer>
// The classic OpenGL teapot... taken form glut-3.7/lib/glut/glut_teapot.c
/* Copyright (c) Mark J. Kilgard, 1994. */
/**
( c ) Copyright 1993 , Silicon Graphics , Inc .
ALL RIGHTS RESERVED
Permission to use , copy , modify , and distribute this software
for any purpose and without fee is hereby granted , provided
that the above copyright notice appear in all copies and that
both the copyright notice and this permission notice appear in
supporting documentation , and that the name of Silicon
Graphics , Inc . not be used in advertising or publicity
pertaining to distribution of the software without specific ,
written prior permission .
THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
" AS-IS " AND WITHOUT WARRANTY OF ANY KIND , EXPRESS , IMPLIED OR
OTHERWISE , INCLUDING WITHOUT LIMITATION , ANY WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE . IN NO
EVENT SHALL SILICON GRAPHICS , INC . BE LIABLE TO YOU OR ANYONE
ELSE FOR ANY DIRECT , SPECIAL , INCIDENTAL , INDIRECT OR
CONSEQUENTIAL DAMAGES OF ANY KIND , OR ANY DAMAGES WHATSOEVER ,
INCLUDING WITHOUT LIMITATION , LOSS OF PROFIT , LOSS OF USE ,
SAVINGS OR REVENUE , OR THE CLAIMS OF THIRD PARTIES , WHETHER OR
NOT SILICON GRAPHICS , INC . HAS BEEN ADVISED OF THE POSSIBILITY
OF SUCH LOSS , HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ,
ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION , USE OR
PERFORMANCE OF THIS SOFTWARE .
US Government Users Restricted Rights
Use , duplication , or disclosure by the Government is subject to
restrictions set forth in FAR 52.227 .19 ( c ) ( 2 ) or subparagraph
( c ) ( 1 ) ( ii ) of the Rights in Technical Data and Computer
Software clause at DFARS 252.227 - 7013 and / or in similar or
successor clauses in the FAR or the DOD or NASA FAR
Supplement . Unpublished - - rights reserved under the copyright
laws of the United States . Contractor / manufacturer is Silicon
Graphics , Inc . , 2011 N . Shoreline Blvd . , Mountain View , CA
94039 - 7311.
OpenGL ( TM ) is a trademark of Silicon Graphics , Inc .
*/
/* Rim, body, lid, and bottom data must be reflected in x and
y ; handle and spout data across the y axis only . */
static int patchdata [ ] [ 16 ] =
{
/* rim */
{ 102 , 103 , 104 , 105 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 ,
12 , 13 , 14 , 15 } ,
/* body */
{ 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 ,
24 , 25 , 26 , 27 } ,
{ 24 , 25 , 26 , 27 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 ,
37 , 38 , 39 , 40 } ,
/* lid */
{ 96 , 96 , 96 , 96 , 97 , 98 , 99 , 100 , 101 , 101 , 101 ,
101 , 0 , 1 , 2 , 3 , } ,
{ 0 , 1 , 2 , 3 , 106 , 107 , 108 , 109 , 110 , 111 , 112 ,
113 , 114 , 115 , 116 , 117 } ,
/* bottom */
{ 118 , 118 , 118 , 118 , 124 , 122 , 119 , 121 , 123 , 126 ,
125 , 120 , 40 , 39 , 38 , 37 } ,
/* handle */
{ 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 ,
53 , 54 , 55 , 56 } ,
{ 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 ,
28 , 65 , 66 , 67 } ,
/* spout */
{ 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 ,
80 , 81 , 82 , 83 } ,
{ 80 , 81 , 82 , 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 91 ,
92 , 93 , 94 , 95 }
} ;
/* *INDENT-OFF* */
static float cpdata [ ] [ 3 ] =
{
{ 0.2 , 0 , 2.7 } , { 0.2 , - 0.112 , 2.7 } , { 0.112 , - 0.2 , 2.7 } , { 0 ,
- 0.2 , 2.7 } , { 1.3375 , 0 , 2.53125 } , { 1.3375 , - 0.749 , 2.53125 } ,
{ 0.749 , - 1.3375 , 2.53125 } , { 0 , - 1.3375 , 2.53125 } , { 1.4375 ,
0 , 2.53125 } , { 1.4375 , - 0.805 , 2.53125 } , { 0.805 , - 1.4375 ,
2.53125 } , { 0 , - 1.4375 , 2.53125 } , { 1.5 , 0 , 2.4 } , { 1.5 , - 0.84 ,
2.4 } , { 0.84 , - 1.5 , 2.4 } , { 0 , - 1.5 , 2.4 } , { 1.75 , 0 , 1.875 } ,
{ 1.75 , - 0.98 , 1.875 } , { 0.98 , - 1.75 , 1.875 } , { 0 , - 1.75 ,
1.875 } , { 2 , 0 , 1.35 } , { 2 , - 1.12 , 1.35 } , { 1.12 , - 2 , 1.35 } ,
{ 0 , - 2 , 1.35 } , { 2 , 0 , 0.9 } , { 2 , - 1.12 , 0.9 } , { 1.12 , - 2 ,
0.9 } , { 0 , - 2 , 0.9 } , { - 2 , 0 , 0.9 } , { 2 , 0 , 0.45 } , { 2 , - 1.12 ,
0.45 } , { 1.12 , - 2 , 0.45 } , { 0 , - 2 , 0.45 } , { 1.5 , 0 , 0.225 } ,
{ 1.5 , - 0.84 , 0.225 } , { 0.84 , - 1.5 , 0.225 } , { 0 , - 1.5 , 0.225 } ,
{ 1.5 , 0 , 0.15 } , { 1.5 , - 0.84 , 0.15 } , { 0.84 , - 1.5 , 0.15 } , { 0 ,
- 1.5 , 0.15 } , { - 1.6 , 0 , 2.025 } , { - 1.6 , - 0.3 , 2.025 } , { - 1.5 ,
- 0.3 , 2.25 } , { - 1.5 , 0 , 2.25 } , { - 2.3 , 0 , 2.025 } , { - 2.3 , - 0.3 ,
2.025 } , { - 2.5 , - 0.3 , 2.25 } , { - 2.5 , 0 , 2.25 } , { - 2.7 , 0 ,
2.025 } , { - 2.7 , - 0.3 , 2.025 } , { - 3 , - 0.3 , 2.25 } , { - 3 , 0 ,
2.25 } , { - 2.7 , 0 , 1.8 } , { - 2.7 , - 0.3 , 1.8 } , { - 3 , - 0.3 , 1.8 } ,
{ - 3 , 0 , 1.8 } , { - 2.7 , 0 , 1.575 } , { - 2.7 , - 0.3 , 1.575 } , { - 3 ,
- 0.3 , 1.35 } , { - 3 , 0 , 1.35 } , { - 2.5 , 0 , 1.125 } , { - 2.5 , - 0.3 ,
1.125 } , { - 2.65 , - 0.3 , 0.9375 } , { - 2.65 , 0 , 0.9375 } , { - 2 ,
- 0.3 , 0.9 } , { - 1.9 , - 0.3 , 0.6 } , { - 1.9 , 0 , 0.6 } , { 1.7 , 0 ,
1.425 } , { 1.7 , - 0.66 , 1.425 } , { 1.7 , - 0.66 , 0.6 } , { 1.7 , 0 ,
0.6 } , { 2.6 , 0 , 1.425 } , { 2.6 , - 0.66 , 1.425 } , { 3.1 , - 0.66 ,
0.825 } , { 3.1 , 0 , 0.825 } , { 2.3 , 0 , 2.1 } , { 2.3 , - 0.25 , 2.1 } ,
{ 2.4 , - 0.25 , 2.025 } , { 2.4 , 0 , 2.025 } , { 2.7 , 0 , 2.4 } , { 2.7 ,
- 0.25 , 2.4 } , { 3.3 , - 0.25 , 2.4 } , { 3.3 , 0 , 2.4 } , { 2.8 , 0 ,
2.475 } , { 2.8 , - 0.25 , 2.475 } , { 3.525 , - 0.25 , 2.49375 } ,
{ 3.525 , 0 , 2.49375 } , { 2.9 , 0 , 2.475 } , { 2.9 , - 0.15 , 2.475 } ,
{ 3.45 , - 0.15 , 2.5125 } , { 3.45 , 0 , 2.5125 } , { 2.8 , 0 , 2.4 } ,
{ 2.8 , - 0.15 , 2.4 } , { 3.2 , - 0.15 , 2.4 } , { 3.2 , 0 , 2.4 } , { 0 , 0 ,
3.15 } , { 0.8 , 0 , 3.15 } , { 0.8 , - 0.45 , 3.15 } , { 0.45 , - 0.8 ,
3.15 } , { 0 , - 0.8 , 3.15 } , { 0 , 0 , 2.85 } , { 1.4 , 0 , 2.4 } , { 1.4 ,
- 0.784 , 2.4 } , { 0.784 , - 1.4 , 2.4 } , { 0 , - 1.4 , 2.4 } , { 0.4 , 0 ,
2.55 } , { 0.4 , - 0.224 , 2.55 } , { 0.224 , - 0.4 , 2.55 } , { 0 , - 0.4 ,
2.55 } , { 1.3 , 0 , 2.55 } , { 1.3 , - 0.728 , 2.55 } , { 0.728 , - 1.3 ,
2.55 } , { 0 , - 1.3 , 2.55 } , { 1.3 , 0 , 2.4 } , { 1.3 , - 0.728 , 2.4 } ,
{ 0.728 , - 1.3 , 2.4 } , { 0 , - 1.3 , 2.4 } , { 0 , 0 , 0 } , { 1.425 ,
- 0.798 , 0 } , { 1.5 , 0 , 0.075 } , { 1.425 , 0 , 0 } , { 0.798 , - 1.425 ,
0 } , { 0 , - 1.5 , 0.075 } , { 0 , - 1.425 , 0 } , { 1.5 , - 0.84 , 0.075 } ,
{ 0.84 , - 1.5 , 0.075 }
} ;
static float tex [ 2 ] [ 2 ] [ 2 ] =
{
{ { 0 , 0 } ,
{ 1 , 0 } } ,
{ { 0 , 1 } ,
{ 1 , 1 } }
} ;
/* *INDENT-ON* */
static void
teapot ( GLint grid , GLenum type )
{
float p [ 4 ] [ 4 ] [ 3 ] , q [ 4 ] [ 4 ] [ 3 ] , r [ 4 ] [ 4 ] [ 3 ] , s [ 4 ] [ 4 ] [ 3 ] ;
long i , j , k , l ;
glPushAttrib ( GL_ENABLE_BIT | GL_EVAL_BIT ) ;
glEnable ( GL_AUTO_NORMAL ) ;
glEnable ( GL_NORMALIZE ) ;
glEnable ( GL_MAP2_VERTEX_3 ) ;
glEnable ( GL_MAP2_TEXTURE_COORD_2 ) ;
for ( i = 0 ; i < 10 ; i + + ) {
for ( j = 0 ; j < 4 ; j + + ) {
for ( k = 0 ; k < 4 ; k + + ) {
for ( l = 0 ; l < 3 ; l + + ) {
p [ j ] [ k ] [ l ] = cpdata [ patchdata [ i ] [ j * 4 + k ] ] [ l ] ;
q [ j ] [ k ] [ l ] = cpdata [ patchdata [ i ] [ j * 4 + ( 3 - k ) ] ] [ l ] ;
if ( l = = 1 )
q [ j ] [ k ] [ l ] * = - 1.0 ;
if ( i < 6 ) {
r [ j ] [ k ] [ l ] =
cpdata [ patchdata [ i ] [ j * 4 + ( 3 - k ) ] ] [ l ] ;
if ( l = = 0 )
r [ j ] [ k ] [ l ] * = - 1.0 ;
s [ j ] [ k ] [ l ] = cpdata [ patchdata [ i ] [ j * 4 + k ] ] [ l ] ;
if ( l = = 0 )
s [ j ] [ k ] [ l ] * = - 1.0 ;
if ( l = = 1 )
s [ j ] [ k ] [ l ] * = - 1.0 ;
}
}
}
}
glMap2f ( GL_MAP2_TEXTURE_COORD_2 , 0 , 1 , 2 , 2 , 0 , 1 , 4 , 2 ,
& tex [ 0 ] [ 0 ] [ 0 ] ) ;
glMap2f ( GL_MAP2_VERTEX_3 , 0 , 1 , 3 , 4 , 0 , 1 , 12 , 4 ,
& p [ 0 ] [ 0 ] [ 0 ] ) ;
glMapGrid2f ( grid , 0.0 , 1.0 , grid , 0.0 , 1.0 ) ;
glEvalMesh2 ( type , 0 , grid , 0 , grid ) ;
glMap2f ( GL_MAP2_VERTEX_3 , 0 , 1 , 3 , 4 , 0 , 1 , 12 , 4 ,
& q [ 0 ] [ 0 ] [ 0 ] ) ;
glEvalMesh2 ( type , 0 , grid , 0 , grid ) ;
if ( i < 6 ) {
glMap2f ( GL_MAP2_VERTEX_3 , 0 , 1 , 3 , 4 , 0 , 1 , 12 , 4 ,
& r [ 0 ] [ 0 ] [ 0 ] ) ;
glEvalMesh2 ( type , 0 , grid , 0 , grid ) ;
glMap2f ( GL_MAP2_VERTEX_3 , 0 , 1 , 3 , 4 , 0 , 1 , 12 , 4 ,
& s [ 0 ] [ 0 ] [ 0 ] ) ;
glEvalMesh2 ( type , 0 , grid , 0 , grid ) ;
}
}
glPopAttrib ( ) ;
}
// Now the OSG wrapper for the above OpenGL code, the most complicated bit is computing
// the bounding box for the above example, normally you'll find this the easy bit.
class Teapot : public osg : : Drawable
{
public :
Teapot ( ) { }
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Teapot ( const Teapot & teapot , const osg : : CopyOp & copyop = osg : : CopyOp : : SHALLOW_COPY ) :
osg : : Drawable ( teapot , copyop ) { }
META_Object ( myTeapotApp , Teapot )
// the draw immediate mode method is where the OSG wraps up the drawing of
// of OpenGL primitives.
virtual void drawImplementation ( osg : : State & ) const
{
// teapot(..) doens't use vertex arrays at all so we don't need to toggle their state
// if we did we'd need to something like following call
// state.disableAllVertexArrays(), see src/osg/Geometry.cpp for the low down.
// just call the OpenGL code.
teapot ( 14 , GL_FILL ) ;
}
// we need to set up the bounding box of the data too, so that the scene graph knows where this
// objects is, for both positioning the camera at start up, and most importantly for culling.
2005-05-12 22:03:22 +08:00
virtual osg : : BoundingBox computeBound ( ) const
2003-03-15 04:35:45 +08:00
{
2005-05-12 22:03:22 +08:00
osg : : BoundingBox bbox ;
2003-03-15 04:35:45 +08:00
// follow is some truely horrible code required to calculate the
// bounding box of the teapot. Have used the original code above to do
// help compute it.
float p [ 4 ] [ 4 ] [ 3 ] , q [ 4 ] [ 4 ] [ 3 ] , r [ 4 ] [ 4 ] [ 3 ] , s [ 4 ] [ 4 ] [ 3 ] ;
long i , j , k , l ;
for ( i = 0 ; i < 10 ; i + + ) {
for ( j = 0 ; j < 4 ; j + + ) {
for ( k = 0 ; k < 4 ; k + + ) {
for ( l = 0 ; l < 3 ; l + + ) {
p [ j ] [ k ] [ l ] = cpdata [ patchdata [ i ] [ j * 4 + k ] ] [ l ] ;
q [ j ] [ k ] [ l ] = cpdata [ patchdata [ i ] [ j * 4 + ( 3 - k ) ] ] [ l ] ;
if ( l = = 1 )
q [ j ] [ k ] [ l ] * = - 1.0 ;
if ( i < 6 ) {
r [ j ] [ k ] [ l ] =
cpdata [ patchdata [ i ] [ j * 4 + ( 3 - k ) ] ] [ l ] ;
if ( l = = 0 )
r [ j ] [ k ] [ l ] * = - 1.0 ;
s [ j ] [ k ] [ l ] = cpdata [ patchdata [ i ] [ j * 4 + k ] ] [ l ] ;
if ( l = = 0 )
s [ j ] [ k ] [ l ] * = - 1.0 ;
if ( l = = 1 )
s [ j ] [ k ] [ l ] * = - 1.0 ;
}
}
2005-05-12 22:03:22 +08:00
bbox . expandBy ( osg : : Vec3 ( p [ j ] [ k ] [ 0 ] , p [ j ] [ k ] [ 1 ] , p [ j ] [ k ] [ 2 ] ) ) ;
bbox . expandBy ( osg : : Vec3 ( q [ j ] [ k ] [ 0 ] , q [ j ] [ k ] [ 1 ] , q [ j ] [ k ] [ 2 ] ) ) ;
2003-03-15 04:35:45 +08:00
if ( i < 6 )
{
2005-05-12 22:03:22 +08:00
bbox . expandBy ( osg : : Vec3 ( r [ j ] [ k ] [ 0 ] , r [ j ] [ k ] [ 1 ] , r [ j ] [ k ] [ 2 ] ) ) ;
bbox . expandBy ( osg : : Vec3 ( s [ j ] [ k ] [ 0 ] , s [ j ] [ k ] [ 1 ] , s [ j ] [ k ] [ 2 ] ) ) ;
2003-03-15 04:35:45 +08:00
}
}
}
}
2005-05-12 22:03:22 +08:00
return bbox ;
2003-03-15 04:35:45 +08:00
}
2005-05-12 22:03:22 +08:00
protected :
virtual ~ Teapot ( ) { }
2003-03-15 04:35:45 +08:00
} ;
osg : : Geode * createTeapot ( )
{
osg : : Geode * geode = new osg : : Geode ( ) ;
// add the teapot to the geode.
geode - > addDrawable ( new Teapot ) ;
// add a reflection map to the teapot.
osg : : Image * image = osgDB : : readImageFile ( " Images/reflect.rgb " ) ;
if ( image )
{
osg : : Texture2D * texture = new osg : : Texture2D ;
texture - > setImage ( image ) ;
osg : : TexGen * texgen = new osg : : TexGen ;
texgen - > setMode ( osg : : TexGen : : SPHERE_MAP ) ;
osg : : StateSet * stateset = new osg : : StateSet ;
stateset - > setTextureAttributeAndModes ( 0 , texture , osg : : StateAttribute : : ON ) ;
stateset - > setTextureAttributeAndModes ( 0 , texgen , osg : : StateAttribute : : ON ) ;
geode - > setStateSet ( stateset ) ;
}
return geode ;
}
int main ( int argc , char * * argv )
{
// use an ArgumentParser object to manage the program arguments.
osg : : ArgumentParser arguments ( & argc , argv ) ;
// set up the usage document, in case we need to print out how to use this program.
2003-04-09 19:44:32 +08:00
arguments . getApplicationUsage ( ) - > setDescription ( arguments . getApplicationName ( ) + " is the example which demonstrates how to encpsulate OpenGL rendering code via sublcassing of osg::Drawable.. " ) ;
2003-04-07 05:32:44 +08:00
arguments . getApplicationUsage ( ) - > setCommandLineUsage ( arguments . getApplicationName ( ) + " [options] filename ... " ) ;
2003-03-15 04:35:45 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -h or --help " , " Display this information " ) ;
// construct the viewer.
osgProducer : : Viewer viewer ( arguments ) ;
// set up the value with sensible default event handlers.
viewer . setUpViewer ( osgProducer : : Viewer : : STANDARD_SETTINGS ) ;
// get details on keyboard and mouse bindings used by the viewer.
viewer . getUsage ( * arguments . getApplicationUsage ( ) ) ;
// if user request help write it out to cout.
if ( arguments . read ( " -h " ) | | arguments . read ( " --help " ) )
{
arguments . getApplicationUsage ( ) - > write ( std : : cout ) ;
return 1 ;
}
// any option left unread are converted into errors to write out later.
arguments . reportRemainingOptionsAsUnrecognized ( ) ;
// report any errors if they have occured when parsing the program aguments.
if ( arguments . errors ( ) )
{
arguments . writeErrorMessages ( std : : cout ) ;
return 1 ;
}
// add model to viewer.
viewer . setSceneData ( createTeapot ( ) ) ;
// create the windows and run the threads.
2003-04-08 23:18:45 +08:00
viewer . realize ( ) ;
2003-03-15 04:35:45 +08:00
while ( ! viewer . done ( ) )
{
// wait for all cull and draw threads to complete.
viewer . sync ( ) ;
// update the scene by traversing it with the the update visitor which will
// call all node update callbacks and animations.
viewer . update ( ) ;
// fire off the cull and draw traversals of the scene.
viewer . frame ( ) ;
}
2003-03-25 18:05:09 +08:00
// wait for all cull and draw threads to complete before exit.
viewer . sync ( ) ;
2003-03-15 04:35:45 +08:00
return 0 ;
}