2007-06-12 22:20:16 +08:00
/* OpenSceneGraph example, osgshadow.
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
2006-11-10 23:07:13 +08:00
# include <osg/ArgumentParser>
2007-02-19 23:26:14 +08:00
# include <osg/ComputeBoundsVisitor>
# include <osg/Texture2D>
2007-02-20 00:45:42 +08:00
# include <osg/ShapeDrawable>
# include <osg/MatrixTransform>
2007-06-07 00:27:00 +08:00
# include <osg/Geometry>
2006-10-06 22:16:11 +08:00
2007-01-11 05:05:26 +08:00
# include <osgGA/TrackballManipulator>
2007-01-23 20:10:44 +08:00
# include <osgGA/FlightManipulator>
# include <osgGA/DriveManipulator>
# include <osgGA/KeySwitchMatrixManipulator>
# include <osgGA/AnimationPathManipulator>
# include <osgGA/TerrainManipulator>
2007-01-19 06:32:18 +08:00
# include <osgGA/AnimationPathManipulator>
2007-01-23 23:51:43 +08:00
# include <osgGA/StateSetManipulator>
2007-01-11 05:05:26 +08:00
# include <osgViewer/Viewer>
2007-06-07 00:23:20 +08:00
# include <osgViewer/ViewerEventHandlers>
2006-10-06 22:16:11 +08:00
2007-02-09 01:23:40 +08:00
# include <osgShadow/ShadowedScene>
# include <osgShadow/ShadowVolume>
2007-02-19 23:26:14 +08:00
# include <osgShadow/ShadowTexture>
# include <osgShadow/ShadowMap>
2007-08-12 20:15:21 +08:00
# include <osgShadow/SoftShadowMap>
2006-10-06 22:16:11 +08:00
# include <osgDB/ReadFile>
2007-01-19 06:32:18 +08:00
# include <osgDB/WriteFile>
2006-10-06 22:16:11 +08:00
2007-01-11 05:05:26 +08:00
# include <iostream>
2006-10-06 22:16:11 +08:00
2007-02-20 00:45:42 +08:00
// for the grid data..
# include "../osghangglide/terrain_coords.h"
2007-06-04 16:38:11 +08:00
const int ReceivesShadowTraversalMask = 0x1 ;
2007-02-20 00:45:42 +08:00
const int CastsShadowTraversalMask = 0x2 ;
namespace ModelOne
2007-01-24 01:42:43 +08:00
{
2007-02-20 00:45:42 +08:00
enum Faces
{
FRONT_FACE = 1 ,
BACK_FACE = 2 ,
LEFT_FACE = 4 ,
RIGHT_FACE = 8 ,
TOP_FACE = 16 ,
BOTTOM_FACE = 32
} ;
osg : : Node * createCube ( unsigned int mask )
2007-01-24 19:18:27 +08:00
{
2007-02-20 00:45:42 +08:00
osg : : Geode * geode = new osg : : Geode ;
osg : : Geometry * geometry = new osg : : Geometry ;
geode - > addDrawable ( geometry ) ;
osg : : Vec3Array * vertices = new osg : : Vec3Array ;
geometry - > setVertexArray ( vertices ) ;
osg : : Vec3Array * normals = new osg : : Vec3Array ;
geometry - > setNormalArray ( normals ) ;
geometry - > setNormalBinding ( osg : : Geometry : : BIND_PER_VERTEX ) ;
osg : : Vec4Array * colours = new osg : : Vec4Array ;
geometry - > setColorArray ( colours ) ;
geometry - > setColorBinding ( osg : : Geometry : : BIND_OVERALL ) ;
colours - > push_back ( osg : : Vec4 ( 1.0f , 1.0f , 1.0f , 1.0f ) ) ;
osg : : Vec3 origin ( 0.0f , 0.0f , 0.0f ) ;
osg : : Vec3 dx ( 2.0f , 0.0f , 0.0f ) ;
osg : : Vec3 dy ( 0.0f , 1.0f , 0.0f ) ;
osg : : Vec3 dz ( 0.0f , 0.0f , 1.0f ) ;
osg : : Vec3 px ( 1.0f , 0.0 , 0.0f ) ;
osg : : Vec3 nx ( - 1.0f , 0.0 , 0.0f ) ;
osg : : Vec3 py ( 0.0f , 1.0f , 0.0f ) ;
osg : : Vec3 ny ( 0.0f , - 1.0f , 0.0f ) ;
osg : : Vec3 pz ( 0.0f , 0.0f , 1.0f ) ;
osg : : Vec3 nz ( 0.0f , 0.0f , - 1.0f ) ;
if ( mask & FRONT_FACE )
{
// front face
vertices - > push_back ( origin ) ;
vertices - > push_back ( origin + dx ) ;
vertices - > push_back ( origin + dx + dz ) ;
vertices - > push_back ( origin + dz ) ;
normals - > push_back ( ny ) ;
normals - > push_back ( ny ) ;
normals - > push_back ( ny ) ;
normals - > push_back ( ny ) ;
}
if ( mask & BACK_FACE )
{
// back face
vertices - > push_back ( origin + dy ) ;
vertices - > push_back ( origin + dy + dz ) ;
vertices - > push_back ( origin + dy + dx + dz ) ;
vertices - > push_back ( origin + dy + dx ) ;
normals - > push_back ( py ) ;
normals - > push_back ( py ) ;
normals - > push_back ( py ) ;
normals - > push_back ( py ) ;
}
if ( mask & LEFT_FACE )
{
// left face
vertices - > push_back ( origin + dy ) ;
vertices - > push_back ( origin ) ;
vertices - > push_back ( origin + dz ) ;
vertices - > push_back ( origin + dy + dz ) ;
normals - > push_back ( nx ) ;
normals - > push_back ( nx ) ;
normals - > push_back ( nx ) ;
normals - > push_back ( nx ) ;
}
if ( mask & RIGHT_FACE )
{
// right face
vertices - > push_back ( origin + dx + dy ) ;
vertices - > push_back ( origin + dx + dy + dz ) ;
vertices - > push_back ( origin + dx + dz ) ;
vertices - > push_back ( origin + dx ) ;
normals - > push_back ( px ) ;
normals - > push_back ( px ) ;
normals - > push_back ( px ) ;
normals - > push_back ( px ) ;
}
if ( mask & TOP_FACE )
{
// top face
vertices - > push_back ( origin + dz ) ;
vertices - > push_back ( origin + dz + dx ) ;
vertices - > push_back ( origin + dz + dx + dy ) ;
vertices - > push_back ( origin + dz + dy ) ;
normals - > push_back ( pz ) ;
normals - > push_back ( pz ) ;
normals - > push_back ( pz ) ;
normals - > push_back ( pz ) ;
}
if ( mask & BOTTOM_FACE )
{
// bottom face
vertices - > push_back ( origin ) ;
vertices - > push_back ( origin + dy ) ;
vertices - > push_back ( origin + dx + dy ) ;
vertices - > push_back ( origin + dx ) ;
normals - > push_back ( nz ) ;
normals - > push_back ( nz ) ;
normals - > push_back ( nz ) ;
normals - > push_back ( nz ) ;
}
geometry - > addPrimitiveSet ( new osg : : DrawArrays ( GL_QUADS , 0 , vertices - > size ( ) ) ) ;
return geode ;
2007-01-24 19:18:27 +08:00
}
2007-02-20 00:45:42 +08:00
class SwitchHandler : public osgGA : : GUIEventHandler
2007-01-24 19:18:27 +08:00
{
2007-02-20 00:45:42 +08:00
public :
SwitchHandler ( ) :
_childNum ( 0 ) { }
virtual bool handle ( const osgGA : : GUIEventAdapter & ea , osgGA : : GUIActionAdapter & /*aa*/ , osg : : Object * object , osg : : NodeVisitor * /*nv*/ )
{
osg : : Switch * sw = dynamic_cast < osg : : Switch * > ( object ) ;
if ( ! sw ) return false ;
if ( ea . getHandled ( ) ) return false ;
2007-01-24 19:18:27 +08:00
2007-02-20 00:45:42 +08:00
switch ( ea . getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : KEYDOWN ) :
{
if ( ea . getKey ( ) = = ' n ' )
{
+ + _childNum ;
if ( _childNum > = sw - > getNumChildren ( ) ) _childNum = 0 ;
sw - > setSingleChildOn ( _childNum ) ;
return true ;
}
break ;
}
default :
break ;
}
return false ;
}
protected :
virtual ~ SwitchHandler ( ) { }
unsigned int _childNum ;
} ;
osg : : Node * createModel ( osg : : ArgumentParser & /*arguments*/ )
2007-01-24 19:18:27 +08:00
{
2007-02-20 00:45:42 +08:00
osg : : Switch * sw = new osg : : Switch ;
sw - > setEventCallback ( new ModelOne : : SwitchHandler ) ;
sw - > addChild ( ModelOne : : createCube ( ModelOne : : FRONT_FACE ) , true ) ;
sw - > addChild ( ModelOne : : createCube ( ModelOne : : FRONT_FACE | ModelOne : : BACK_FACE ) , false ) ;
sw - > addChild ( ModelOne : : createCube ( ModelOne : : FRONT_FACE | ModelOne : : BACK_FACE | ModelOne : : LEFT_FACE ) , false ) ;
sw - > addChild ( ModelOne : : createCube ( ModelOne : : FRONT_FACE | ModelOne : : BACK_FACE | ModelOne : : LEFT_FACE | ModelOne : : RIGHT_FACE ) , false ) ;
sw - > addChild ( ModelOne : : createCube ( ModelOne : : FRONT_FACE | ModelOne : : BACK_FACE | ModelOne : : LEFT_FACE | ModelOne : : RIGHT_FACE | ModelOne : : TOP_FACE ) , false ) ;
sw - > addChild ( ModelOne : : createCube ( ModelOne : : FRONT_FACE | ModelOne : : BACK_FACE | ModelOne : : LEFT_FACE | ModelOne : : RIGHT_FACE | ModelOne : : TOP_FACE | ModelOne : : BOTTOM_FACE ) , false ) ;
return sw ;
2007-01-24 19:18:27 +08:00
}
2007-02-20 00:45:42 +08:00
}
2007-01-24 19:18:27 +08:00
2007-02-20 00:45:42 +08:00
namespace ModelTwo
{
osg : : AnimationPath * createAnimationPath ( const osg : : Vec3 & center , float radius , double looptime )
2007-01-24 19:18:27 +08:00
{
2007-02-20 00:45:42 +08:00
// set up the animation path
osg : : AnimationPath * animationPath = new osg : : AnimationPath ;
animationPath - > setLoopMode ( osg : : AnimationPath : : LOOP ) ;
int numSamples = 40 ;
float yaw = 0.0f ;
float yaw_delta = 2.0f * osg : : PI / ( ( float ) numSamples - 1.0f ) ;
float roll = osg : : inDegrees ( 30.0f ) ;
double time = 0.0f ;
double time_delta = looptime / ( double ) numSamples ;
for ( int i = 0 ; i < numSamples ; + + i )
{
osg : : Vec3 position ( center + osg : : Vec3 ( sinf ( yaw ) * radius , cosf ( yaw ) * radius , 0.0f ) ) ;
osg : : Quat rotation ( osg : : Quat ( roll , osg : : Vec3 ( 0.0 , 1.0 , 0.0 ) ) * osg : : Quat ( - ( yaw + osg : : inDegrees ( 90.0f ) ) , osg : : Vec3 ( 0.0 , 0.0 , 1.0 ) ) ) ;
animationPath - > insert ( time , osg : : AnimationPath : : ControlPoint ( position , rotation ) ) ;
yaw + = yaw_delta ;
time + = time_delta ;
}
return animationPath ;
2007-01-24 19:18:27 +08:00
}
2007-02-20 00:45:42 +08:00
osg : : Node * createBase ( const osg : : Vec3 & center , float radius )
2007-01-24 19:18:27 +08:00
{
2007-01-24 01:42:43 +08:00
2007-02-20 00:45:42 +08:00
osg : : Geode * geode = new osg : : Geode ;
2006-11-24 01:29:43 +08:00
2007-02-20 00:45:42 +08:00
// set up the texture of the base.
osg : : StateSet * stateset = new osg : : StateSet ( ) ;
osg : : Image * image = osgDB : : readImageFile ( " Images/lz.rgb " ) ;
if ( image )
{
osg : : Texture2D * texture = new osg : : Texture2D ;
texture - > setImage ( image ) ;
stateset - > setTextureAttributeAndModes ( 0 , texture , osg : : StateAttribute : : ON ) ;
}
2007-01-24 19:18:27 +08:00
2007-02-20 00:45:42 +08:00
geode - > setStateSet ( stateset ) ;
2007-01-25 20:02:51 +08:00
2007-02-20 00:45:42 +08:00
osg : : HeightField * grid = new osg : : HeightField ;
grid - > allocate ( 38 , 39 ) ;
grid - > setOrigin ( center + osg : : Vec3 ( - radius , - radius , 0.0f ) ) ;
grid - > setXInterval ( radius * 2.0f / ( float ) ( 38 - 1 ) ) ;
grid - > setYInterval ( radius * 2.0f / ( float ) ( 39 - 1 ) ) ;
float minHeight = FLT_MAX ;
float maxHeight = - FLT_MAX ;
unsigned int r ;
for ( r = 0 ; r < 39 ; + + r )
2007-01-24 19:18:27 +08:00
{
2007-02-20 00:45:42 +08:00
for ( unsigned int c = 0 ; c < 38 ; + + c )
2007-01-24 19:18:27 +08:00
{
2007-02-20 00:45:42 +08:00
float h = vertex [ r + c * 39 ] [ 2 ] ;
if ( h > maxHeight ) maxHeight = h ;
if ( h < minHeight ) minHeight = h ;
}
}
2007-01-24 19:18:27 +08:00
2007-02-20 00:45:42 +08:00
float hieghtScale = radius * 0.5f / ( maxHeight - minHeight ) ;
float hieghtOffset = - ( minHeight + maxHeight ) * 0.5f ;
for ( r = 0 ; r < 39 ; + + r )
{
for ( unsigned int c = 0 ; c < 38 ; + + c )
{
float h = vertex [ r + c * 39 ] [ 2 ] ;
grid - > setHeight ( c , r , ( h + hieghtOffset ) * hieghtScale ) ;
2007-01-24 19:18:27 +08:00
}
}
2007-02-20 00:45:42 +08:00
geode - > addDrawable ( new osg : : ShapeDrawable ( grid ) ) ;
osg : : Group * group = new osg : : Group ;
group - > addChild ( geode ) ;
return group ;
2007-01-24 19:18:27 +08:00
}
2007-02-20 00:45:42 +08:00
osg : : Node * createMovingModel ( const osg : : Vec3 & center , float radius )
{
float animationLength = 10.0f ;
osg : : AnimationPath * animationPath = createAnimationPath ( center , radius , animationLength ) ;
osg : : Group * model = new osg : : Group ;
osg : : Node * cessna = osgDB : : readNodeFile ( " cessna.osg " ) ;
if ( cessna )
{
const osg : : BoundingSphere & bs = cessna - > getBound ( ) ;
float size = radius / bs . radius ( ) * 0.3f ;
osg : : MatrixTransform * positioned = new osg : : MatrixTransform ;
positioned - > setDataVariance ( osg : : Object : : STATIC ) ;
positioned - > setMatrix ( osg : : Matrix : : translate ( - bs . center ( ) ) *
osg : : Matrix : : scale ( size , size , size ) *
osg : : Matrix : : rotate ( osg : : inDegrees ( 180.0f ) , 0.0f , 0.0f , 2.0f ) ) ;
2007-01-24 19:18:27 +08:00
2007-02-20 00:45:42 +08:00
positioned - > addChild ( cessna ) ;
osg : : MatrixTransform * xform = new osg : : MatrixTransform ;
xform - > setUpdateCallback ( new osg : : AnimationPathCallback ( animationPath , 0.0f , 2.0 ) ) ;
xform - > addChild ( positioned ) ;
model - > addChild ( xform ) ;
}
return model ;
}
osg : : Node * createModel ( osg : : ArgumentParser & /*arguments*/ )
{
osg : : Vec3 center ( 0.0f , 0.0f , 0.0f ) ;
float radius = 100.0f ;
osg : : Vec3 lightPosition ( center + osg : : Vec3 ( 0.0f , 0.0f , radius ) ) ;
// the shadower model
osg : : Node * shadower = createMovingModel ( center , radius * 0.5f ) ;
shadower - > setNodeMask ( CastsShadowTraversalMask ) ;
// the shadowed model
osg : : Node * shadowed = createBase ( center - osg : : Vec3 ( 0.0f , 0.0f , radius * 0.25 ) , radius ) ;
2007-06-04 16:38:11 +08:00
shadowed - > setNodeMask ( ReceivesShadowTraversalMask ) ;
2007-02-20 00:45:42 +08:00
osg : : Group * group = new osg : : Group ;
group - > addChild ( shadowed ) ;
group - > addChild ( shadower ) ;
return group ;
}
}
namespace ModelThree
{
osg : : Group * createModel ( osg : : ArgumentParser & arguments )
{
osg : : Group * scene = new osg : : Group ;
osg : : ref_ptr < osg : : Geode > geode_1 = new osg : : Geode ;
scene - > addChild ( geode_1 . get ( ) ) ;
osg : : ref_ptr < osg : : Geode > geode_2 = new osg : : Geode ;
osg : : ref_ptr < osg : : MatrixTransform > transform_2 = new osg : : MatrixTransform ;
transform_2 - > addChild ( geode_2 . get ( ) ) ;
transform_2 - > setUpdateCallback ( new osg : : AnimationPathCallback ( osg : : Vec3 ( 0 , 0 , 0 ) , osg : : Z_AXIS , osg : : inDegrees ( 45.0f ) ) ) ;
scene - > addChild ( transform_2 . get ( ) ) ;
osg : : ref_ptr < osg : : Geode > geode_3 = new osg : : Geode ;
osg : : ref_ptr < osg : : MatrixTransform > transform_3 = new osg : : MatrixTransform ;
transform_3 - > addChild ( geode_3 . get ( ) ) ;
transform_3 - > setUpdateCallback ( new osg : : AnimationPathCallback ( osg : : Vec3 ( 0 , 0 , 0 ) , osg : : Z_AXIS , osg : : inDegrees ( - 22.5f ) ) ) ;
scene - > addChild ( transform_3 . get ( ) ) ;
const float radius = 0.8f ;
const float height = 1.0f ;
osg : : ref_ptr < osg : : TessellationHints > hints = new osg : : TessellationHints ;
hints - > setDetailRatio ( 2.0f ) ;
osg : : ref_ptr < osg : : ShapeDrawable > shape ;
shape = new osg : : ShapeDrawable ( new osg : : Box ( osg : : Vec3 ( 0.0f , 0.0f , - 2.0f ) , 10 , 10.0f , 0.1f ) , hints . get ( ) ) ;
shape - > setColor ( osg : : Vec4 ( 0.5f , 0.5f , 0.7f , 1.0f ) ) ;
geode_1 - > addDrawable ( shape . get ( ) ) ;
shape = new osg : : ShapeDrawable ( new osg : : Sphere ( osg : : Vec3 ( 0.0f , 0.0f , 0.0f ) , radius * 2 ) , hints . get ( ) ) ;
shape - > setColor ( osg : : Vec4 ( 0.8f , 0.8f , 0.8f , 1.0f ) ) ;
geode_1 - > addDrawable ( shape . get ( ) ) ;
shape = new osg : : ShapeDrawable ( new osg : : Sphere ( osg : : Vec3 ( - 3.0f , 0.0f , 0.0f ) , radius ) , hints . get ( ) ) ;
shape - > setColor ( osg : : Vec4 ( 0.6f , 0.8f , 0.8f , 1.0f ) ) ;
geode_2 - > addDrawable ( shape . get ( ) ) ;
shape = new osg : : ShapeDrawable ( new osg : : Box ( osg : : Vec3 ( 3.0f , 0.0f , 0.0f ) , 2 * radius ) , hints . get ( ) ) ;
shape - > setColor ( osg : : Vec4 ( 0.4f , 0.9f , 0.3f , 1.0f ) ) ;
geode_2 - > addDrawable ( shape . get ( ) ) ;
shape = new osg : : ShapeDrawable ( new osg : : Cone ( osg : : Vec3 ( 0.0f , - 3.0f , 0.0f ) , radius , height ) , hints . get ( ) ) ;
shape - > setColor ( osg : : Vec4 ( 0.2f , 0.5f , 0.7f , 1.0f ) ) ;
geode_2 - > addDrawable ( shape . get ( ) ) ;
shape = new osg : : ShapeDrawable ( new osg : : Cylinder ( osg : : Vec3 ( 0.0f , 3.0f , 0.0f ) , radius , height ) , hints . get ( ) ) ;
shape - > setColor ( osg : : Vec4 ( 1.0f , 0.3f , 0.3f , 1.0f ) ) ;
geode_2 - > addDrawable ( shape . get ( ) ) ;
shape = new osg : : ShapeDrawable ( new osg : : Box ( osg : : Vec3 ( 0.0f , 0.0f , 3.0f ) , 2.0f , 2.0f , 0.1f ) , hints . get ( ) ) ;
shape - > setColor ( osg : : Vec4 ( 0.8f , 0.8f , 0.4f , 1.0f ) ) ;
geode_3 - > addDrawable ( shape . get ( ) ) ;
// material
osg : : ref_ptr < osg : : Material > matirial = new osg : : Material ;
matirial - > setColorMode ( osg : : Material : : DIFFUSE ) ;
matirial - > setAmbient ( osg : : Material : : FRONT_AND_BACK , osg : : Vec4 ( 0 , 0 , 0 , 1 ) ) ;
matirial - > setSpecular ( osg : : Material : : FRONT_AND_BACK , osg : : Vec4 ( 1 , 1 , 1 , 1 ) ) ;
matirial - > setShininess ( osg : : Material : : FRONT_AND_BACK , 64.0f ) ;
scene - > getOrCreateStateSet ( ) - > setAttributeAndModes ( matirial . get ( ) , osg : : StateAttribute : : ON ) ;
bool withBaseTexture = true ;
while ( arguments . read ( " --with-base-texture " ) ) { withBaseTexture = true ; }
while ( arguments . read ( " --no-base-texture " ) ) { withBaseTexture = false ; }
if ( withBaseTexture )
{
scene - > getOrCreateStateSet ( ) - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( osgDB : : readImageFile ( " Images/lz.rgb " ) ) , osg : : StateAttribute : : ON ) ;
}
return scene ;
}
}
2007-01-24 19:18:27 +08:00
2007-02-19 23:26:14 +08:00
osg : : Node * createTestModel ( osg : : ArgumentParser & arguments )
2007-01-24 19:18:27 +08:00
{
2007-02-19 23:26:14 +08:00
if ( arguments . read ( " -1 " ) )
{
2007-02-20 00:45:42 +08:00
return ModelOne : : createModel ( arguments ) ;
2007-02-19 23:26:14 +08:00
}
else if ( arguments . read ( " -2 " ) )
{
2007-02-20 00:45:42 +08:00
return ModelTwo : : createModel ( arguments ) ;
2007-02-19 23:26:14 +08:00
}
else /*if (arguments.read("-3"))*/
{
2007-02-20 00:45:42 +08:00
return ModelThree : : createModel ( arguments ) ;
2007-02-19 23:26:14 +08:00
}
2007-01-24 19:18:27 +08:00
}
2006-10-06 22:16:11 +08:00
int main ( int argc , char * * argv )
{
// use an ArgumentParser object to manage the program arguments.
2006-11-10 23:07:13 +08:00
osg : : ArgumentParser arguments ( & argc , argv ) ;
2006-10-06 22:16:11 +08:00
// set up the usage document, in case we need to print out how to use this program.
arguments . getApplicationUsage ( ) - > setDescription ( arguments . getApplicationName ( ) + " is the example which demonstrates using of GL_ARB_shadow extension implemented in osg::Texture class " ) ;
arguments . getApplicationUsage ( ) - > setCommandLineUsage ( arguments . getApplicationName ( ) ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -h or --help " , " Display this information " ) ;
2007-01-23 22:43:07 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --positionalLight " , " Use a positional light. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --directionalLight " , " Use a direction light. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --noUpdate " , " Disable the updating the of light source. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --base " , " Add a base geometry to test shadows. " ) ;
2007-02-20 00:59:52 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --sv " , " Select ShadowVolume implementation. " ) ;
2007-08-12 20:15:21 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --ssm " , " Select SoftShadowMap implementation. " ) ;
2007-02-20 00:59:52 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --sm " , " Select ShadowMap implementation. " ) ;
2007-06-13 17:56:12 +08:00
// arguments.getApplicationUsage()->addCommandLineOption("--pssm", "Select ParallelSplitShadowMap implementation.");
2007-03-04 21:04:12 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -1 " , " Use test model one. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -2 " , " Use test model two. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -3 " , " Use test model three. " ) ;
2007-01-23 22:43:07 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --two-sided " , " Use two-sided stencil extension for shadow volumes. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --two-pass " , " Use two-pass stencil for shadow volumes. " ) ;
2006-10-06 22:16:11 +08:00
2007-01-23 23:51:43 +08:00
2006-10-06 22:16:11 +08:00
// construct the viewer.
2007-01-11 05:05:26 +08:00
osgViewer : : Viewer viewer ;
2006-10-06 22:16:11 +08:00
// if user request help write it out to cout.
if ( arguments . read ( " -h " ) | | arguments . read ( " --help " ) )
{
arguments . getApplicationUsage ( ) - > write ( std : : cout ) ;
return 1 ;
}
2007-02-10 05:31:29 +08:00
// default to single threaded during dev work.
viewer . setThreadingModel ( osgViewer : : Viewer : : SingleThreaded ) ;
while ( arguments . read ( " --SingleThreaded " ) ) viewer . setThreadingModel ( osgViewer : : Viewer : : SingleThreaded ) ;
while ( arguments . read ( " --CullDrawThreadPerContext " ) ) viewer . setThreadingModel ( osgViewer : : Viewer : : CullDrawThreadPerContext ) ;
while ( arguments . read ( " --DrawThreadPerContext " ) ) viewer . setThreadingModel ( osgViewer : : Viewer : : DrawThreadPerContext ) ;
while ( arguments . read ( " --CullThreadPerCameraDrawThreadPerContext " ) ) viewer . setThreadingModel ( osgViewer : : Viewer : : CullThreadPerCameraDrawThreadPerContext ) ;
2007-02-20 00:45:42 +08:00
bool postionalLight = true ;
2006-11-30 18:29:03 +08:00
while ( arguments . read ( " --positionalLight " ) ) postionalLight = true ;
while ( arguments . read ( " --directionalLight " ) ) postionalLight = false ;
bool updateLightPosition = true ;
2006-12-01 00:30:24 +08:00
while ( arguments . read ( " --noUpdate " ) ) updateLightPosition = false ;
2006-11-30 18:29:03 +08:00
2007-01-25 20:02:51 +08:00
2007-01-23 23:51:43 +08:00
int screenNum = - 1 ;
while ( arguments . read ( " --screen " , screenNum ) ) viewer . setUpViewOnSingleScreen ( screenNum ) ;
2007-01-23 20:10:44 +08:00
// set up the camera manipulators.
2007-01-19 06:32:18 +08:00
{
2007-01-23 20:10:44 +08:00
osg : : ref_ptr < osgGA : : KeySwitchMatrixManipulator > keyswitchManipulator = new osgGA : : KeySwitchMatrixManipulator ;
keyswitchManipulator - > addMatrixManipulator ( ' 1 ' , " Trackball " , new osgGA : : TrackballManipulator ( ) ) ;
keyswitchManipulator - > addMatrixManipulator ( ' 2 ' , " Flight " , new osgGA : : FlightManipulator ( ) ) ;
keyswitchManipulator - > addMatrixManipulator ( ' 3 ' , " Drive " , new osgGA : : DriveManipulator ( ) ) ;
keyswitchManipulator - > addMatrixManipulator ( ' 4 ' , " Terrain " , new osgGA : : TerrainManipulator ( ) ) ;
std : : string pathfile ;
char keyForAnimationPath = ' 5 ' ;
while ( arguments . read ( " -p " , pathfile ) )
{
osgGA : : AnimationPathManipulator * apm = new osgGA : : AnimationPathManipulator ( pathfile ) ;
if ( apm | | ! apm - > valid ( ) )
{
unsigned int num = keyswitchManipulator - > getNumMatrixManipulators ( ) ;
keyswitchManipulator - > addMatrixManipulator ( keyForAnimationPath , " Path " , apm ) ;
keyswitchManipulator - > selectMatrixManipulator ( num ) ;
+ + keyForAnimationPath ;
}
}
viewer . setCameraManipulator ( keyswitchManipulator . get ( ) ) ;
2007-01-19 06:32:18 +08:00
}
2007-01-23 23:51:43 +08:00
// add the state manipulator
viewer . addEventHandler ( new osgGA : : StateSetManipulator ( viewer . getCamera ( ) - > getOrCreateStateSet ( ) ) ) ;
2007-01-23 20:10:44 +08:00
// add stats
viewer . addEventHandler ( new osgViewer : : StatsHandler ( ) ) ;
2006-11-30 20:05:51 +08:00
2006-11-10 23:07:13 +08:00
osg : : ref_ptr < osg : : Node > model = osgDB : : readNodeFiles ( arguments ) ;
2007-02-20 00:45:42 +08:00
if ( model . valid ( ) )
{
2007-06-04 16:38:11 +08:00
model - > setNodeMask ( CastsShadowTraversalMask | ReceivesShadowTraversalMask ) ;
2007-02-20 00:45:42 +08:00
}
else
2006-10-06 22:16:11 +08:00
{
2007-02-19 23:26:14 +08:00
model = createTestModel ( arguments ) ;
2006-10-06 22:16:11 +08:00
}
2006-11-30 18:29:03 +08:00
// get the bounds of the model.
2007-02-19 23:26:14 +08:00
osg : : ComputeBoundsVisitor cbbv ;
2006-11-30 18:29:03 +08:00
model - > accept ( cbbv ) ;
osg : : BoundingBox bb = cbbv . getBoundingBox ( ) ;
2006-12-01 23:19:21 +08:00
2007-02-19 23:26:14 +08:00
osg : : Vec4 lightpos ;
if ( postionalLight )
2006-12-01 23:19:21 +08:00
{
2007-02-19 23:26:14 +08:00
lightpos . set ( bb . center ( ) . x ( ) , bb . center ( ) . y ( ) , bb . zMax ( ) + bb . radius ( ) , 1.0f ) ;
}
else
{
lightpos . set ( 0.5f , 0.25f , 0.8f , 0.0f ) ;
}
osg : : ref_ptr < osgShadow : : ShadowedScene > shadowedScene = new osgShadow : : ShadowedScene ;
2007-06-04 16:38:11 +08:00
shadowedScene - > setReceivesShadowTraversalMask ( ReceivesShadowTraversalMask ) ;
2007-02-20 00:45:42 +08:00
shadowedScene - > setCastsShadowTraversalMask ( CastsShadowTraversalMask ) ;
2007-02-19 23:26:14 +08:00
if ( arguments . read ( " --sv " ) )
{
2007-02-20 00:59:52 +08:00
// hint to tell viewer to request stencil buffer when setting up windows
osg : : DisplaySettings : : instance ( ) - > setMinimumNumStencilBits ( 8 ) ;
2007-02-19 23:26:14 +08:00
osg : : ref_ptr < osgShadow : : ShadowVolume > sv = new osgShadow : : ShadowVolume ;
sv - > setDynamicShadowVolumes ( updateLightPosition ) ;
while ( arguments . read ( " --two-sided " ) ) sv - > setDrawMode ( osgShadow : : ShadowVolumeGeometry : : STENCIL_TWO_SIDED ) ;
while ( arguments . read ( " --two-pass " ) ) sv - > setDrawMode ( osgShadow : : ShadowVolumeGeometry : : STENCIL_TWO_PASS ) ;
shadowedScene - > setShadowTechnique ( sv . get ( ) ) ;
}
else if ( arguments . read ( " --st " ) )
{
osg : : ref_ptr < osgShadow : : ShadowTexture > st = new osgShadow : : ShadowTexture ;
shadowedScene - > setShadowTechnique ( st . get ( ) ) ;
}
2007-06-13 17:56:12 +08:00
#if 0
2007-02-19 23:26:14 +08:00
else if ( arguments . read ( " --pssm " ) )
{
osg : : ref_ptr < osgShadow : : ParallelSplitShadowMap > pssm = new osgShadow : : ParallelSplitShadowMap ;
shadowedScene - > setShadowTechnique ( pssm . get ( ) ) ;
}
2007-06-13 17:56:12 +08:00
# endif
2007-08-12 20:15:21 +08:00
else if ( arguments . read ( " --ssm " ) )
{
osg : : ref_ptr < osgShadow : : SoftShadowMap > sm = new osgShadow : : SoftShadowMap ;
shadowedScene - > setShadowTechnique ( sm . get ( ) ) ;
}
2007-02-19 23:26:14 +08:00
else /* if (arguments.read("--sm")) */
{
osg : : ref_ptr < osgShadow : : ShadowMap > sm = new osgShadow : : ShadowMap ;
shadowedScene - > setShadowTechnique ( sm . get ( ) ) ;
}
if ( arguments . read ( " --base " ) )
{
2006-12-01 23:19:21 +08:00
osg : : Geode * geode = new osg : : Geode ;
osg : : Vec3 widthVec ( bb . radius ( ) , 0.0f , 0.0f ) ;
osg : : Vec3 depthVec ( 0.0f , bb . radius ( ) , 0.0f ) ;
osg : : Vec3 centerBase ( ( bb . xMin ( ) + bb . xMax ( ) ) * 0.5f , ( bb . yMin ( ) + bb . yMax ( ) ) * 0.5f , bb . zMin ( ) - bb . radius ( ) * 0.1f ) ;
2007-01-11 05:05:26 +08:00
geode - > addDrawable ( osg : : createTexturedQuadGeometry ( centerBase - widthVec * 1.5f - depthVec * 1.5f ,
widthVec * 3.0f , depthVec * 3.0f ) ) ;
2007-02-19 23:26:14 +08:00
2007-06-04 16:38:11 +08:00
geode - > setNodeMask ( shadowedScene - > getReceivesShadowTraversalMask ( ) ) ;
2006-12-01 23:19:21 +08:00
2007-02-19 23:26:14 +08:00
geode - > getOrCreateStateSet ( ) - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( osgDB : : readImageFile ( " Images/lz.rgb " ) ) ) ;
shadowedScene - > addChild ( geode ) ;
2006-12-01 23:19:21 +08:00
}
2007-02-19 23:26:14 +08:00
osg : : ref_ptr < osg : : LightSource > ls = new osg : : LightSource ;
ls - > getLight ( ) - > setPosition ( lightpos ) ;
if ( arguments . read ( " --coloured-light " ) )
2006-11-30 18:29:03 +08:00
{
2007-02-19 23:26:14 +08:00
ls - > getLight ( ) - > setAmbient ( osg : : Vec4 ( 1.0 , 0.0 , 0.0 , 1.0 ) ) ;
ls - > getLight ( ) - > setDiffuse ( osg : : Vec4 ( 0.0 , 1.0 , 0.0 , 1.0 ) ) ;
2006-11-30 18:29:03 +08:00
}
else
{
2007-02-19 23:26:14 +08:00
ls - > getLight ( ) - > setAmbient ( osg : : Vec4 ( 0.2 , 0.2 , 0.2 , 1.0 ) ) ;
ls - > getLight ( ) - > setDiffuse ( osg : : Vec4 ( 0.8 , 0.8 , 0.8 , 1.0 ) ) ;
2006-11-30 18:29:03 +08:00
}
2006-11-30 20:05:51 +08:00
2007-02-10 05:31:29 +08:00
shadowedScene - > addChild ( model . get ( ) ) ;
shadowedScene - > addChild ( ls . get ( ) ) ;
2007-02-16 06:28:32 +08:00
2007-02-10 05:31:29 +08:00
viewer . setSceneData ( shadowedScene . get ( ) ) ;
2007-01-23 23:51:43 +08:00
2006-10-06 22:16:11 +08:00
// create the windows and run the threads.
viewer . realize ( ) ;
2007-01-24 00:27:07 +08:00
// osgDB::writeNodeFile(*group,"test.osg");
2007-01-19 06:32:18 +08:00
2006-10-06 22:16:11 +08:00
while ( ! viewer . done ( ) )
{
2006-11-30 18:29:03 +08:00
if ( updateLightPosition )
{
2007-01-25 20:02:51 +08:00
float t = viewer . getFrameStamp ( ) - > getSimulationTime ( ) ;
2006-11-30 18:29:03 +08:00
if ( postionalLight )
{
lightpos . set ( bb . center ( ) . x ( ) + sinf ( t ) * bb . radius ( ) , bb . center ( ) . y ( ) + cosf ( t ) * bb . radius ( ) , bb . zMax ( ) + bb . radius ( ) , 1.0f ) ;
}
else
{
2007-02-10 05:31:29 +08:00
lightpos . set ( sinf ( t ) , cosf ( t ) , 1.0f , 0.0f ) ;
2006-11-30 18:29:03 +08:00
}
2007-02-10 05:31:29 +08:00
ls - > getLight ( ) - > setPosition ( lightpos ) ;
2007-01-11 05:05:26 +08:00
}
viewer . frame ( ) ;
2006-10-06 22:16:11 +08:00
}
return 0 ;
}