diff --git a/Make/makedirdefs b/Make/makedirdefs index 604d06713..0c4a39de2 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -17,7 +17,8 @@ SRC_DIRS = \ osgText\ osgSim\ osgPlugins\ - Demos + ../examples\ + src/Demos ################################################################ @@ -70,6 +71,17 @@ PLUGIN_DIRS += gif # comment in if you have libtiff installed. PLUGIN_DIRS += tiff + +################################################################ +# Directories traversed in the TOPDIR/examples directory + +EXAMPLE_DIRS = \ + osgcameragroup\ + osgconv\ + osgtext\ + osgviewer\ + + ################################################################ # Directories traversed in the TOPDIR/src/Demos directory @@ -112,3 +124,4 @@ DEMOS_DIRS = \ osgvertexprogram\ osgviews\ sgv + diff --git a/examples/osgcameragroup/Makefile b/examples/osgcameragroup/Makefile new file mode 100644 index 000000000..77e39c580 --- /dev/null +++ b/examples/osgcameragroup/Makefile @@ -0,0 +1,19 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgcameragroup.cpp\ + +LIBS += -losgProducer -lProducer $(OSG_LIBS) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + Makefile.inst=Makefile + +EXEC = osgcameragroup + +CXXFLAGS += $(PRODUCER_INCLUDE_DIR) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgcameragroup/Makefile.inst b/examples/osgcameragroup/Makefile.inst new file mode 100644 index 000000000..119b0ee3c --- /dev/null +++ b/examples/osgcameragroup/Makefile.inst @@ -0,0 +1,15 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgcameragroup.cpp\ + +LIBS += -losgProducer -lProducer $(OSG_LIBS) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgcameragroup + +CXXFLAGS += $(PRODUCER_INCLUDE_DIR) +LDFLAGS += $(PRODUCER_LIB_DIR) + + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgcameragroup/osgcameragroup.cpp b/examples/osgcameragroup/osgcameragroup.cpp new file mode 100644 index 000000000..1a379a6a2 --- /dev/null +++ b/examples/osgcameragroup/osgcameragroup.cpp @@ -0,0 +1,220 @@ +//C++ source file - Open Producer - Copyright (C) 2002 Don Burns +//Distributed under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL) +//as published by the Free Software Foundation. + +// Simple example of use of Producer::RenderSurface +// The myGraphics class is a simple sample of how one would implement +// graphics drawing with Producer::RenderSurface + +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + +int main( int argc, char **argv ) +{ + + // threading model. + Producer::CameraGroup::ThreadingModel threadingModel = Producer::CameraGroup::SingleThreaded; + threadingModel = Producer::CameraGroup::ThreadPerCamera; + + // configuration file. + std::string configFile; + //configFile = "twoWindows.cfg"; + + // set up the database files to read. + std::vector filenameList; + if (argc>1) filenameList.push_back(argv[1]); + else filenameList.push_back("cow.osg"); + + + + // create the camera group. + osgProducer::CameraGroup *cg = configFile.empty() ? + (new osgProducer::CameraGroup()): + (new osgProducer::CameraGroup(configFile)); + + // set up the maximum number of graphics contexts, before loading the scene graph + // to ensure that texture objects and display buffers are configured to the correct size. + osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( cg->getNumberOfCameras() ); + + + // read the scene. + osg::ref_ptr loadedModel = osgDB::readNodeFiles(filenameList); + if (!loadedModel) return 1; + + osgUtil::Optimizer optimizer; + optimizer.optimize(loadedModel.get()); + + + // set up the keyboard and mouse handling. + Producer::InputArea *ia = cg->getCameraConfig()->getInputArea(); + Producer::KeyboardMouse *kbm = ia ? + (new Producer::KeyboardMouse(ia)) : + (new Producer::KeyboardMouse(cg->getCamera(0)->getRenderSurface())); + + // set up the time and frame counter. + unsigned int frameNumber = 0; + osg::Timer timer; + osg::Timer_t start_tick = timer.tick(); + + // set the keyboard mouse callback to catch the events from the windows. + bool done = false; + osgProducer::KeyboardMouseCallback kbmcb(done); + kbmcb.setStartTick(start_tick); + + // register the callback with the keyboard mouse manger. + kbm->setCallback( &kbmcb ); + //kbm->allowContinuousMouseMotionUpdate(true); + kbm->startThread(); + + + + // set the globa state + osg::ref_ptr globalStateSet = new osg::StateSet; + globalStateSet->setGlobalDefaults(); + cg->setGlobalStateSet(globalStateSet.get()); + + + // add either a headlight or sun light to the scene. + osg::LightSource* lightsource = new osg::LightSource; + osg::Light* light = new osg::Light; + lightsource->setLight(light); + lightsource->setReferenceFrame(osg::LightSource::RELATIVE_TO_ABSOLUTE); // headlight. + lightsource->setLocalStateSetModes(osg::StateAttribute::ON); + + lightsource->addChild(loadedModel.get()); + + + // set the scene to render +// cg->setSceneData(scene.get()); + cg->setSceneData(lightsource); + + // set up the pthread stack size to large enough to run into problems. + cg->setStackSize( 20*1024*1024); + + // create the windows and run the threads. + cg->realize(threadingModel); + + osg::ref_ptr frameStamp = cg->getFrameStamp(); + + osgUtil::UpdateVisitor update; + update.setFrameStamp(frameStamp.get()); + + + + // create a camera to use with the manipulators. + osg::ref_ptr old_style_osg_camera = new osg::Camera; + + osg::ref_ptr keyswitchManipulator = new osgGA::KeySwitchCameraManipulator; + keyswitchManipulator->addNumberedCameraManipulator(new osgGA::TrackballManipulator); + keyswitchManipulator->addNumberedCameraManipulator(new osgGA::FlightManipulator); + keyswitchManipulator->addNumberedCameraManipulator(new osgGA::DriveManipulator); + + keyswitchManipulator->setCamera(old_style_osg_camera.get()); + keyswitchManipulator->setNode(loadedModel.get()); + + + osg::ref_ptr statesetManipulator = new osgGA::StateSetManipulator; + statesetManipulator->setStateSet(globalStateSet.get()); + + // create an event handler list, we'll dispatch our event to these.. + typedef std::list< osg::ref_ptr > EventHandlerList; + EventHandlerList eventHandlerList; + eventHandlerList.push_back(keyswitchManipulator.get()); + eventHandlerList.push_back(statesetManipulator.get()); + + // create a dummy action adapter right now. + osgProducer::ActionAdapter actionAdapter; + + osg::ref_ptr init_event = new osgProducer::EventAdapter; + init_event->adaptFrame(0.0); + keyswitchManipulator->getCurrentCameraManipulator()->home(*init_event,actionAdapter); + + double previous_time_since_start = 0.0f; + int number_frames_since_last_print = 0; + int number_of_frame_samples = 10; + bool printOutFrameStats=true; + while( !done ) + { + // syncronize to screen refresh. + cg->sync(); + + // set the frame stamp for the new frame. + double time_since_start = timer.delta_s(start_tick,timer.tick()); + frameStamp->setFrameNumber(frameNumber); + frameStamp->setReferenceTime(time_since_start); + + if (printOutFrameStats) + { + if (number_frames_since_last_print==number_of_frame_samples) + { + cout << "frame rate = "<< (double)number_of_frame_samples/(time_since_start-previous_time_since_start)< frame_event = new osgProducer::EventAdapter; + frame_event->adaptFrame(frameStamp->getReferenceTime()); + queue.push_back(frame_event); + + // dispatch the events in order of arrival. + for(osgProducer::KeyboardMouseCallback::EventQueue::iterator event_itr=queue.begin(); + event_itr!=queue.end(); + ++event_itr) + { + bool handled = false; + for(EventHandlerList::iterator handler_itr=eventHandlerList.begin(); + handler_itr!=eventHandlerList.end() && !handled; + ++handler_itr) + { + handled = (*handler_itr)->handle(*(*event_itr),actionAdapter); + } + } + + // update the scene by traversing it with the the update visitor which will + // call all node update callbacks and animations. + cg->getSceneData()->accept(update); + + + // update the main producer camera + cg->setView(old_style_osg_camera->getModelViewMatrix().ptr()); + + // fire off the cull and draw traversals of the scene. + cg->frame(); + + // increment the frame number ready for the next frame + ++frameNumber; + } + return 0; +} + diff --git a/examples/osgconv/Makefile b/examples/osgconv/Makefile new file mode 100644 index 000000000..396717124 --- /dev/null +++ b/examples/osgconv/Makefile @@ -0,0 +1,21 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + OrientationConverter.cpp\ + osgconv.cpp\ + +HEADERFILES = \ + OrientationConverter.h + +LIBS += -losg -losgUtil -losgDB $(GL_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + $(HEADERFILES)\ + Makefile.inst=Makefile + +EXEC = osgconv + + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgconv/Makefile.inst b/examples/osgconv/Makefile.inst new file mode 100644 index 000000000..1607a0d46 --- /dev/null +++ b/examples/osgconv/Makefile.inst @@ -0,0 +1,16 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + OrientationConverter.cpp\ + osgconv.cpp\ + +LIBS += -losg -losgUtil -losgDB $(GL_LIBS) $(OTHER_LIBS) + +EXEC = osgconv + +INSTFILES =\ + $(CXXFILES)\ + Makefile.inst=Makefile + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgconv/OrientationConverter.cpp b/examples/osgconv/OrientationConverter.cpp new file mode 100644 index 000000000..1a450f02c --- /dev/null +++ b/examples/osgconv/OrientationConverter.cpp @@ -0,0 +1,64 @@ +#include + +#include +#include + +#include "OrientationConverter.h" + +using namespace osg; + +OrientationConverter::OrientationConverter( void ) +{ + R.makeIdentity(); + T.makeIdentity(); + _trans_set = false; + S.makeIdentity(); +} + +void OrientationConverter::setRotation( const Vec3 &from, const Vec3 &to ) +{ + R = Matrix::rotate( from, to ); +} + +void OrientationConverter::setTranslation( const Vec3 &trans ) +{ + T = Matrix::translate(trans); + _trans_set = true; +} + +void OrientationConverter::setScale( const Vec3 &scale ) +{ + S = Matrix::scale(scale); +} + + +Node* OrientationConverter::convert( Node *node ) +{ + // Order of operations here is : + // 1. Translate to world origin (0,0,0) + // 2. Rotate to new orientation + // 3. Scale in new orientation coordinates + // 4. If an absolute translation was specified then + // - translate to absolute translation in world coordinates + // else + // - translate back to model's original origin. + BoundingSphere bs = node->getBound(); + Matrix C = Matrix::translate( -bs.center() ); + if( _trans_set == false ) + T = Matrix::translate( bs.center() ); + + osg::Group* root = new osg::Group; + osg::MatrixTransform* transform = new osg::MatrixTransform; + + transform->setDataVariance(osg::Object::STATIC); + transform->setMatrix( C * R * S * T ); + + root->addChild(transform); + transform->addChild(node); + + osgUtil::Optimizer::FlattenStaticTransformsVisitor fstv; + root->accept(fstv); + fstv.removeTransforms(root); + + return root->getChild(0); +} diff --git a/examples/osgconv/OrientationConverter.h b/examples/osgconv/OrientationConverter.h new file mode 100644 index 000000000..7a509d2ca --- /dev/null +++ b/examples/osgconv/OrientationConverter.h @@ -0,0 +1,29 @@ +#ifndef _ORIENTATION_CONVERTER_H +#define _ORIENTATION_CONVERTER_H + +#include +#include +#include +#include + +class OrientationConverter { + public : + OrientationConverter(void); + void setRotation( const osg::Vec3 &from, + const osg::Vec3 &to ); + void setTranslation( const osg::Vec3 &trans); + void setScale( const osg::Vec3 &trans); + + /** return the root of the updated subgraph as the subgraph + * the node passed in my flatten during optimization.*/ + osg::Node* convert( osg::Node* node ); + + private : + OrientationConverter( const OrientationConverter& ) {} + OrientationConverter& operator = (const OrientationConverter& ) { return *this; } + + osg::Matrix R, T, S; + bool _trans_set; + +}; +#endif diff --git a/examples/osgconv/osgconv.cpp b/examples/osgconv/osgconv.cpp new file mode 100644 index 000000000..68c8b307a --- /dev/null +++ b/examples/osgconv/osgconv.cpp @@ -0,0 +1,249 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "OrientationConverter.h" + +typedef std::vector FileNameList; + +static bool do_convert = false; + + +static void usage( const char *prog, const char *msg ) +{ + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE) << msg << std::endl; + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE)<<"usage:"<< std::endl; + osg::notify(osg::NOTICE)<<" " << prog << " [options] infile1 [infile2 ...] outfile"<< std::endl; + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE)<<"options:"<< std::endl; + osg::notify(osg::NOTICE)<<" -O option - ReaderWriter option"<< std::endl; + osg::notify(osg::NOTICE)<<" -l libraryName - load plugin of name libraryName"<< std::endl; + osg::notify(osg::NOTICE)<<" i.e. -l osgdb_pfb"<< std::endl; + osg::notify(osg::NOTICE)<<" Useful for loading reader/writers which can load"<< std::endl; + osg::notify(osg::NOTICE)<<" other file formats in addition to its extension."<< std::endl; + osg::notify(osg::NOTICE)<<" -e extensionName - load reader/wrter plugin for file extension"<< std::endl; + osg::notify(osg::NOTICE)<<" i.e. -e pfb"<< std::endl; + osg::notify(osg::NOTICE)<<" Useful short hand for specifying full library name as"<< std::endl; + osg::notify(osg::NOTICE)<<" done with -l above, as it automatically expands to the"<< std::endl; + osg::notify(osg::NOTICE)<<" full library name appropriate for each platform."<< std::endl; + osg::notify(osg::NOTICE)<<" -o orientation - Convert geometry from input files to output files."<< std::endl; + osg::notify(osg::NOTICE)<< + " Format of orientation argument must be the following:\n" + "\n" + " X1,Y1,Z1-X2,Y2,Z2\n" + "\n" + " where X1,Y1,Z1 represent the UP vector in the input\n" + " files and X2,Y2,Z2 represent the UP vector of the\n" + " output file. For example, to convert a model built\n" + " in a Y-Up coordinate system to a model with a Z-up\n" + " coordinate system, the argument looks like\n" + "\n" + " 0,1,0-0,0,1" + "\n" + << std::endl; + osg::notify(osg::NOTICE)<<" -t translation - Convert spatial position of output files. Format of\n" + " translation argument must be the following :\n" + "\n" + " X,Y,Z\n" + "\n" + " where X, Y, and Z represent the coordinates of the\n" + " absolute position in world space\n" + << std::endl; + osg::notify(osg::NOTICE)<<" -s scale - Scale size of model. Scale argument must be the \n" + " following :\n" + "\n" + " SX,SY,SZ\n" + "\n" + " where SX, SY, and SZ represent the scale factors\n" + " Caution: Scaling will be done in destination orientation\n" + << std::endl; +} + +static bool +parse_args( int argc, char **argv, FileNameList &fileNames, + OrientationConverter &oc, osgDB::ReaderWriter::Options* options ) +{ + int nexti; + std::string opt = ""; + + for(int i = 1; i < argc; i=nexti ) + { + nexti = i+1; + + if (argv[i][0]=='-') + { + for( unsigned int j = 1; j < strlen( argv[i] ); j++ ) + { + switch(argv[i][j]) + { + case 'O': + if (nexticreateLibraryNameForExt(argv[nexti++]); + osgDB::Registry::instance()->loadLibrary(libName); + } + else + { + usage( argv[0], "Extension option requires an argument." ); + return false; + } + break; + + case('l'): + if (nextiloadLibrary(argv[nexti++]); + } + else + { + usage( argv[0], "Library option requires an argument." ); + return false; + } + break; + + case 'o' : + if( nexti < argc ) + { + osg::Vec3 from, to; + if( sscanf( argv[nexti++], "%f,%f,%f-%f,%f,%f", + &from[0], &from[1], &from[2], + &to[0], &to[1], &to[2] ) + != 6 ) + { + usage( argv[0], "Orientation argument format incorrect." ); + return false; + } + oc.setRotation( from, to ); + do_convert = true; + } + else + { + usage( argv[0], "Orientation conversion option requires an argument." ); + return false; + } + break; + + case 't' : + if( nexti < argc ) + { + osg::Vec3 trans(0,0,0); + if( sscanf( argv[nexti++], "%f,%f,%f", + &trans[0], &trans[1], &trans[2] ) != 3 ) + { + usage( argv[0], "Translation argument format incorrect." ); + return false; + } + oc.setTranslation( trans ); + do_convert = true; + } + else + { + usage( argv[0], "Translation conversion option requires an argument." ); + return false; + } + break; + + case 's' : + if( nexti < argc ) + { + osg::Vec3 scale(0,0,0); + if( sscanf( argv[nexti++], "%f,%f,%f", + &scale[0], &scale[1], &scale[2] ) != 3 ) + { + usage( argv[0], "Scale argument format incorrect." ); + return false; + } + oc.setScale( scale ); + do_convert = true; + } + else + { + usage( argv[0], "Scale conversion option requires an argument." ); + return false; + } + break; + + default : + std::string a = "Invalid option " ; + a += "'"; + a += argv[i][j] ; + a += "'."; + usage( argv[0], a.c_str() ); + return false; + break; + } + } + } else + { + fileNames.push_back(argv[i]); + } + } + + if (fileNames.empty()) + { + usage( argv[0], "No files specified." ); + return false; + } + + options->setOptionString(opt); + + return true; +} + +int main( int argc, char **argv ) +{ + FileNameList fileNames; + OrientationConverter oc; + + osgDB::ReaderWriter::Options* options = new osgDB::ReaderWriter::Options; + osgDB::Registry::instance()->setOptions(options); + + if( parse_args( argc, argv, fileNames, oc, options ) == false ) + return -1; + + std::string fileNameOut("converted.osg"); + if (fileNames.size()>1) + { + fileNameOut = fileNames.back(); + fileNames.pop_back(); + } + + osg::ref_ptr root = osgDB::readNodeFiles(fileNames); + + if( do_convert ) + root = oc.convert( root.get() ); + + if (root.valid()) + { + osgDB::writeNodeFile(*root,fileNameOut); + osg::notify(osg::NOTICE)<<"Data written to '"< +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + + +/////////////////////////////////////////////////////////////////////////////// +// globals +#define TEXT_POLYGON "Polygon Font - jygq" +#define TEXT_OUTLINE "Outline Font - jygq" +#define TEXT_TEXTURE "Texture Font - jygq" +#define TEXT_BITMAP "Bitmap Font - jygq" +#define TEXT_PIXMAP "Pixmap Font - jygq" + +#define TEXT_COL_2D osg::Vec4(.9,.9,.9,1) +#define TEXT_COL_3D osg::Vec4(.99,.3,.2,1) + + +std::string ttfPath("fonts/times.ttf"); +std::string ttfPath1("fonts/arial.ttf"); + +int gFontSize=18; +int gFontSize1=24; +std::vector > gTextList; +osgText::Text::AlignmentType gAlignment=osgText::Text::LEFT_BOTTOM; + +osg::Group* createText() +{ + osg::Group* rootNode = new osg::Group; + + osgText::Text* text; + osg::Geode* geode; + osg::Material* textMaterial; + osg::StateSet* textState; + double xOffset=150; + double yOffset=gFontSize+10; + + /////////////////////////////////////////////////////////////////////////// + // setup the texts + + /////////////////////////////////////////////////////////////////////////// + // BitmapFont + osgText::BitmapFont* bitmapFont= new osgText::BitmapFont(ttfPath, + gFontSize1); + text= new osgText::Text(bitmapFont); + gTextList.push_back(text); + text->setText(std::string("2d ")+std::string(TEXT_BITMAP)); + text->setPosition(osg::Vec3(xOffset,yOffset,0)); + text->setDrawMode( osgText::Text::TEXT | + osgText::Text::BOUNDINGBOX | + osgText::Text::ALIGNMENT ); + text->setAlignment(gAlignment); + geode = new osg::Geode(); + geode->setName("BitmapFont"); + geode->addDrawable( text ); + + textMaterial = new osg::Material(); + textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE); + textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D); + textState = new osg::StateSet(); + textState->setAttribute(textMaterial ); + geode->setStateSet( textState ); + + rootNode->addChild(geode); + + xOffset+=90; + yOffset+=120; + + /////////////////////////////////////////////////////////////////////////// + // PixmapFont + osgText::PixmapFont* pixmapFont= new osgText::PixmapFont(ttfPath, + gFontSize1); + text= new osgText::Text(pixmapFont); + gTextList.push_back(text); + text->setText(std::string("2d ")+std::string(TEXT_PIXMAP)); + text->setPosition(osg::Vec3(xOffset,yOffset,0)); + text->setDrawMode( osgText::Text::TEXT | + osgText::Text::BOUNDINGBOX | + osgText::Text::ALIGNMENT ); + text->setAlignment(gAlignment); + geode = new osg::Geode(); + geode->setName("PixmapFont"); + geode->addDrawable( text ); + + textMaterial = new osg::Material(); + textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE); + textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK,TEXT_COL_2D); + // to get antiaA pixmapFonts we have to draw them with blending + osg::BlendFunc *transp= new osg::BlendFunc(); + transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + + + + textState = new osg::StateSet(); + textState->setAttribute(textMaterial ); + textState->setAttribute(transp); + textState->setMode(GL_BLEND,osg::StateAttribute::ON); + textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + + + geode->setStateSet( textState ); + + rootNode->addChild(geode); + + xOffset+=90; + yOffset+=120; + + /////////////////////////////////////////////////////////////////////////// + // TextureFont + osgText::TextureFont* textureFont= new osgText::TextureFont(ttfPath1, + gFontSize1); + text= new osgText::Text(textureFont); + gTextList.push_back(text); + text->setText(std::string("2d ")+std::string(TEXT_TEXTURE)); + text->setPosition(osg::Vec3(xOffset,yOffset,0)); + text->setDrawMode( osgText::Text::TEXT | + osgText::Text::BOUNDINGBOX | + osgText::Text::ALIGNMENT ); + text->setAlignment(gAlignment); + geode = new osg::Geode(); + geode->setName("TextureFont"); + geode->addDrawable( text ); + + textMaterial = new osg::Material(); + textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE); + textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D); + // to get antiaA pixmapFonts we have to draw them with blending + transp= new osg::BlendFunc(); + transp->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + textState = new osg::StateSet(); + textState->setAttribute(textMaterial ); + textState->setAttribute(transp); + + textState->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON); + textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + geode->setStateSet( textState ); + + rootNode->addChild(geode); + + xOffset+=90; + yOffset+=120; + + /////////////////////////////////////////////////////////////////////////// + // PolygonFont + osgText::PolygonFont* polygonFont= new osgText::PolygonFont(ttfPath, + gFontSize1, + 3); + text= new osgText::Text(polygonFont); + gTextList.push_back(text); + text->setText(std::string("2d ")+std::string("TEXT_POLYGON")); + text->setPosition(osg::Vec3(xOffset,yOffset,0)); + text->setDrawMode( osgText::Text::TEXT | + osgText::Text::BOUNDINGBOX | + osgText::Text::ALIGNMENT ); + text->setAlignment(gAlignment); + geode = new osg::Geode(); + geode->setName("PolygonFont"); + geode->addDrawable( text ); + + textMaterial = new osg::Material(); + textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE); + textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D); + textState = new osg::StateSet(); + textState->setAttribute(textMaterial ); + geode->setStateSet( textState ); + + rootNode->addChild(geode); + + xOffset+=90; + yOffset+=120; + + /////////////////////////////////////////////////////////////////////////// + // OutlineFont + osgText::OutlineFont* outlineFont= new osgText::OutlineFont(ttfPath, + gFontSize1, + 3); + + text= new osgText::Text(outlineFont); + gTextList.push_back(text); + text->setText(std::string("2d ")+std::string(TEXT_OUTLINE)); + text->setPosition(osg::Vec3(xOffset,yOffset,0)); + text->setDrawMode( osgText::Text::TEXT | + osgText::Text::BOUNDINGBOX | + osgText::Text::ALIGNMENT ); + text->setAlignment(gAlignment); + geode = new osg::Geode(); + geode->setName("OutlineFont"); + geode->addDrawable( text ); + + textMaterial = new osg::Material(); + textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE); + textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D); + textState = new osg::StateSet(); + textState->setAttribute(textMaterial ); + geode->setStateSet( textState ); + + rootNode->addChild(geode); + + + // now add a depth attribute to the scene to force it to draw on top. + osg::Depth* depth = new osg::Depth; + depth->setRange(0.0,0.0); + + osg::StateSet* rootState = new osg::StateSet(); + rootState->setAttribute(depth); + rootState->setMode(GL_LIGHTING,osg::StateAttribute::OFF); + + rootNode->setStateSet(rootState); + + return rootNode; +} + + +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. + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getProgramName()+" [options] [filename] ..."); + 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(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(cout); + return 1; + } + + + // read the scene from the list of file specified commandline args. + osg::ref_ptr rootNode = osgDB::readNodeFiles(arguments); + + // prepare scene. + { + + if (rootNode.valid()) + { + // optimize the scene graph, remove rendundent nodes and state etc. + osgUtil::Optimizer optimizer; + optimizer.optimize(rootNode.get()); + } + + // make sure the root node is group so we can add extra nodes to it. + osg::Group* group = dynamic_cast(rootNode.get()); + if (!group) + { + group = new osg::Group; + + if (rootNode.valid()) group->addChild(rootNode.get()); + + rootNode = group; + } + + // create the hud. + osg::Projection* projection = new osg::Projection; + projection->setMatrix(osg::Matrix::ortho2D(0,1024,0,768)); + + osg::MatrixTransform* modelview_abs = new osg::MatrixTransform; + modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE); + modelview_abs->setMatrix(osg::Matrix::identity()); + + modelview_abs->addChild(createText()); + + projection->addChild(modelview_abs); + + group->addChild(projection); + + } + + // set the scene to render + viewer.setSceneData(rootNode.get()); + + // create the windows and run the threads. + viewer.realize(Producer::CameraGroup::ThreadPerCamera); + + 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(); + + } + + return 0; +} diff --git a/examples/osgviewer/Makefile b/examples/osgviewer/Makefile new file mode 100644 index 000000000..c0ef5ee6e --- /dev/null +++ b/examples/osgviewer/Makefile @@ -0,0 +1,19 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgviewer.cpp\ + +LIBS += -losgProducer -lProducer $(OSG_LIBS) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + Makefile.inst=Makefile + +EXEC = osgviewer + +CXXFLAGS += $(PRODUCER_INCLUDE_DIR) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgviewer/Makefile.inst b/examples/osgviewer/Makefile.inst new file mode 100644 index 000000000..623aaac59 --- /dev/null +++ b/examples/osgviewer/Makefile.inst @@ -0,0 +1,15 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgviewer.cpp\ + +LIBS += -losgProducer -lProducer $(OSG_LIBS) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgviewer + +CXXFLAGS += $(PRODUCER_INCLUDE_DIR) +LDFLAGS += $(PRODUCER_LIB_DIR) + + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgviewer/osgviewer.cpp b/examples/osgviewer/osgviewer.cpp new file mode 100644 index 000000000..a89a354d7 --- /dev/null +++ b/examples/osgviewer/osgviewer.cpp @@ -0,0 +1,93 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include +#include + +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. + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getProgramName()+" [options] filename ..."); + 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; + } + + + // read the scene from the list of file specified commandline args. + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + + // if no model has been successfully loaded report failure. + if (!loadedModel) + { + std::cout << arguments.getProgramName() <<": No data loaded" << std::endl; + return 1; + } + + + // optimize the scene graph, remove rendundent nodes and state etc. + osgUtil::Optimizer optimizer; + optimizer.optimize(loadedModel.get()); + + // set the scene to render + viewer.setSceneData(loadedModel.get()); + + // create the windows and run the threads. + viewer.realize(Producer::CameraGroup::ThreadPerCamera); + + 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(); + + } + + return 0; +} + diff --git a/include/osgProducer/Viewer b/include/osgProducer/Viewer index 936d5486b..2b689cc47 100644 --- a/include/osgProducer/Viewer +++ b/include/osgProducer/Viewer @@ -17,6 +17,7 @@ #include #include #include +#include #include #include