00001 #include "osgVRJPrecompiled.h"
00002 #include "Application.h"
00003
00004 #include <osgUtil/RenderStage>
00005 #include <osgUtil/RenderGraph>
00006 #include <osg/FrameStamp>
00007 #include <osg/LightModel>
00008 #include <osg/MatrixTransform>
00009 #include <osgUtil/UpdateVisitor>
00010
00011 #ifdef _OSG096_
00012 #include <osgUtil/DisplayListVisitor>
00013 #else
00014 #include <osgUtil/GLObjectsVisitor>
00015 #endif
00016
00017 #include <vrj/Kernel/Kernel.h>
00018
00019 #include <stdexcept>
00020
00021 using namespace osgVRJ;
00022
00023 #define CONSTRUCTOR_INITIALIZER_LIST\
00024 _scene_data(0x0),\
00025 _frame_stamp(new osg::FrameStamp),\
00026 _init_visitor(0x0),\
00027 _update_visitor(new osgUtil::UpdateVisitor),\
00028 _global_stateset(new osg::StateSet),\
00029 _scene_decorator(0x0),\
00030 _viewport(0x0),\
00031 _background_color(0,0,0,1),\
00032 _context_in_sync(false),\
00033 _frameNumber(0),\
00034 _initial_time(0.0),\
00035 _head_tracker(),\
00036 _sceneview()
00037
00038 Application::Application() : vrj::GlApp(),
00039 CONSTRUCTOR_INITIALIZER_LIST
00040 {
00041 this->_construct();
00042 }
00043
00044 Application::Application(vrj::Kernel* kern) : vrj::GlApp(kern),
00045 CONSTRUCTOR_INITIALIZER_LIST
00046 {
00047 this->_construct();
00048 }
00049
00050 namespace osgVRJ
00051 {
00052 namespace Detail
00053 {
00054 struct LoadConfigFile
00055 {
00056 void operator() (const std::string& file)
00057 {
00058 vrj::Kernel* kern = vrj::Kernel::instance();
00059 kern->loadConfigFile( file.c_str() );
00060 }
00061 };
00062 };
00063 };
00064
00065 Application::Application(const std::list<std::string>& configs) : vrj::GlApp(),
00066 CONSTRUCTOR_INITIALIZER_LIST
00067 {
00068 this->_construct();
00069 std::for_each(configs.begin(),configs.end(), Detail::LoadConfigFile());
00070 }
00071
00072 void Application::_construct()
00073 {
00074
00075
00076
00077
00078 osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts ( 20 );
00079 }
00080
00081 Application::~Application()
00082 {
00083 }
00084
00085 void Application::run()
00086 {
00087 vrj::Kernel* kernel = vrj::Kernel::instance();
00088 kernel->setApplication( this );
00089 kernel->start();
00090 kernel->waitForKernelStop();
00091 }
00092
00093
00094 void Application::viewAll ( osg::MatrixTransform* node, osg::Matrix::value_type zScale )
00095 {
00096
00097 osg::BoundingSphere bs = node->getBound();
00098 osg::Vec3 c = bs.center();
00099
00100
00101 osg::Matrix matrix;
00102 osg::Matrix::value_type z ( zScale * bs.radius() + c[2] );
00103 matrix.makeTranslate( -c[0], -c[1], -z );
00104 node->postMult( matrix );
00105 }
00106
00107 void Application::contextInit()
00108 {
00109
00110 osg::ref_ptr<osg::State> state = new osg::State;
00111
00112
00113 #ifdef _OSG096_
00114 typedef osgUtil::DisplayListVisitor VisitorType;
00115 #else
00116 typedef osgUtil::GLObjectsVisitor VisitorType;
00117 #endif
00118
00119 VisitorType::Mode dlvMode = VisitorType::COMPILE_STATE_ATTRIBUTES;
00120 #ifndef __sgi
00121 dlvMode |= VisitorType::COMPILE_DISPLAY_LISTS;
00122 #endif
00123
00124 osg::ref_ptr<VisitorType> dlv = new VisitorType(dlvMode);
00125 dlv->setState( state.get() );
00126 dlv->setNodeMaskOverride( 0xffffffff );
00127
00128
00129 osg::ref_ptr<osgUtil::RenderStage> rs = new osgUtil::RenderStage;
00130 osg::ref_ptr<osgUtil::RenderGraph> rg = new osgUtil::RenderGraph;
00131
00132
00133 osg::ref_ptr<osgUtil::CullVisitor> cv = new osgUtil::CullVisitor;
00134 cv->setRenderStage( rs.get() );
00135 cv->setRenderGraph( rg.get() );
00136
00137 osgUtil::SceneView* sv = new osgUtil::SceneView;
00138 sv->setState( state.get() );
00139 sv->setInitVisitor( dlv.get() );
00140 sv->setCullVisitor( cv.get() );
00141 sv->setRenderStage( rs.get() );
00142 sv->setRenderGraph( rg.get() );
00143
00144 unsigned int unique_context_id = vrj::GlDrawManager::instance()->getCurrentContext();
00145 sv->getState()->setContextID(unique_context_id);
00146
00147
00148
00149
00150 setUpSceneViewWithData(sv);
00151
00152 sv->init();
00153 (*_sceneview) = sv;
00154 }
00155
00156 void Application::contextPreDraw()
00157 {
00158 osgUtil::SceneView* sv = getContextSpecificSceneView();
00159
00160
00161 if(!_context_in_sync)
00162 setUpSceneViewWithData(sv);
00163 }
00164
00165
00166
00167
00168 namespace osgVRJ
00169 {
00170 namespace Detail
00171 {
00172 struct OpenGlStackPushPop
00173 {
00174 OpenGlStackPushPop()
00175 {
00176 #if 0
00177
00178 while ( GL_ERROR_NO != ::glGetError() ){}
00179 #endif
00180
00181 glPushAttrib(GL_ALL_ATTRIB_BITS);
00182
00183 glMatrixMode(GL_MODELVIEW);
00184 glPushMatrix();
00185
00186 glMatrixMode(GL_PROJECTION);
00187 glPushMatrix();
00188
00189 glMatrixMode(GL_TEXTURE);
00190 glPushMatrix();
00191 }
00192 ~OpenGlStackPushPop()
00193 {
00194
00195 #if 0
00196 assert ( GL_ERROR_NO == ::glGetError() );
00197 #endif
00198
00199 glMatrixMode(GL_TEXTURE);
00200 glPopMatrix();
00201
00202 glMatrixMode(GL_PROJECTION);
00203 glPopMatrix();
00204
00205 glMatrixMode(GL_MODELVIEW);
00206 glPopMatrix();
00207
00208 glPopAttrib();
00209 }
00210 };
00211 };
00212 };
00213
00214
00215 void Application::draw()
00216 {
00217
00218 Detail::OpenGlStackPushPop pushPop;
00219
00220 osgUtil::SceneView* sv = getContextSpecificSceneView();
00221 vrj::GlDrawManager* mgr = vrj::GlDrawManager::instance();
00222 vprASSERT(mgr != NULL);
00223
00224
00225 osg::Viewport* vp = sv->getViewport();
00226 setViewportByDrawManager(sv->getViewport(),mgr);
00227
00228
00229 vrj::GlUserData* userData = mgr->currentUserData();
00230 vrj::Projection* projection = userData->getProjection();
00231 vrj::Frustum frustum = projection->getFrustum();
00232 sv->setProjectionMatrixAsFrustum(frustum[vrj::Frustum::VJ_LEFT],
00233 frustum[vrj::Frustum::VJ_RIGHT],
00234 frustum[vrj::Frustum::VJ_BOTTOM],
00235 frustum[vrj::Frustum::VJ_TOP],
00236 frustum[vrj::Frustum::VJ_NEAR],
00237 frustum[vrj::Frustum::VJ_FAR]);
00238
00239
00240 gmtl::Matrix44f proj_mat = projection->getViewMatrix();
00241
00242 osg::ref_ptr<osg::RefMatrix> osg_proj_xform_mat= new osg::RefMatrix;
00243 osg_proj_xform_mat->set(proj_mat.mData);
00244 sv->setViewMatrix(*osg_proj_xform_mat);
00245
00246 sv->cull();
00247 sv->draw();
00248 }
00249
00250
00251 osgUtil::SceneView* Application::getContextSpecificSceneView()
00252 {
00253 osg::ref_ptr<osgUtil::SceneView> sv = *(_sceneview);
00254 return( sv.get() );
00255 }
00256
00257 osg::Node* Application::getSceneData()
00258 {
00259 if(_scene_decorator.valid())
00260 return(_scene_decorator.get());
00261
00262 else
00263 return(_scene_data.get());
00264 }
00265
00266 double Application::getTimeSinceStart()
00267 {
00268 return(_head_tracker->getTimeStamp().secd() - _initial_time);
00269 }
00270
00271 void Application::init()
00272 {
00273 _head_tracker.init("VJHead");
00274 _initial_time = _head_tracker->getTimeStamp().secd();
00275
00276 if(_scene_data.valid())
00277 setSceneData(_scene_data.get());
00278
00279
00280 _frame_stamp->setFrameNumber(0);
00281 _frame_stamp->setReferenceTime(_initial_time);
00282
00283
00284 _update_visitor->setFrameStamp(_frame_stamp.get());
00285 _update_visitor->setTraversalNumber(_frame_stamp->getFrameNumber());
00286
00287
00288 this->initGlobalStateSet();
00289 }
00290
00291 void Application::preFrame()
00292 {
00293
00294 _frame_stamp->setFrameNumber(_frameNumber++);
00295 _frame_stamp->setReferenceTime(getTimeSinceStart());
00296
00297 update();
00298 }
00299
00300 void Application::postFrame()
00301 {
00302 if(!_context_in_sync)
00303 _context_in_sync = true;
00304 }
00305
00306
00307
00308
00309 void Application::initGlobalStateSet()
00310 {
00311
00312 if(_update_visitor.valid())
00313 _update_visitor->setFrameStamp(_frame_stamp.get());
00314
00315
00316 _global_stateset = new osg::StateSet;
00317 _global_stateset->setGlobalDefaults();
00318 _global_stateset->setMode(GL_LIGHTING,osg::StateAttribute::ON);
00319 _global_stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::ON);
00320 _global_stateset->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
00321
00322 osg::AlphaFunc* alpha_func = new osg::AlphaFunc;
00323 alpha_func->setFunction(osg::AlphaFunc::GREATER,0.0f);
00324 _global_stateset->setAttributeAndModes(alpha_func,osg::StateAttribute::ON);
00325
00326 osg::TexEnv* texEnv = new osg::TexEnv;
00327 texEnv->setMode(osg::TexEnv::MODULATE);
00328 _global_stateset->setTextureAttributeAndModes(0,texEnv,osg::StateAttribute::ON);
00329
00330 osg::LightModel* light_model = new osg::LightModel;
00331 light_model->setAmbientIntensity(osg::Vec4(0.1f,0.1f,0.1f,1.0f));
00332 _global_stateset->setAttributeAndModes(light_model,osg::StateAttribute::ON);
00333
00334
00335 setBackgroundColor( osg::Vec4(0.2,0.2,0.4,1.0) );
00336
00337
00338 _context_in_sync = false;
00339 }
00340
00341 void Application::setSceneData(osg::Node* data)
00342 {
00343 if(_scene_data == data)
00344 return;
00345
00346 if(_scene_decorator.valid() && _scene_data.valid())
00347 _scene_decorator->removeChild( _scene_data.get() );
00348
00349 _scene_data = data;
00350
00351 if(_scene_decorator.valid() && _scene_data.valid())
00352 _scene_decorator->addChild( _scene_data.get() );
00353
00354 _context_in_sync = false;
00355 }
00356
00357 void Application::setSceneDecorator(osg::Group* decor)
00358 {
00359 if(_scene_decorator == decor) return;
00360
00361 _scene_decorator = decor;
00362
00363 if( decor && _scene_data.valid())
00364 {
00365 decor->addChild(_scene_data.get());
00366 }
00367
00368 _context_in_sync = false;
00369 }
00370
00371
00372 void Application::setUpSceneViewWithData(osgUtil::SceneView* sv)
00373 {
00374
00375
00376 if(_scene_decorator.valid())
00377 sv->setSceneData(_scene_decorator.get());
00378
00379 else if(_scene_data.valid())
00380 sv->setSceneData(_scene_data.get());
00381
00382 else
00383 sv->setSceneData( 0 );
00384
00385
00386 if(_frame_stamp.valid())
00387 sv->setFrameStamp(_frame_stamp.get());
00388
00389
00390 if(_global_stateset.valid())
00391 sv->setGlobalStateSet(_global_stateset.get());
00392
00393
00394 #ifdef _OSG096_
00395 sv->setBackgroundColor(_background_color);
00396 #else
00397 sv->setClearColor( _background_color );
00398 #endif
00399
00400 sv->setLightingMode(osgUtil::SceneView::NO_SCENEVIEW_LIGHT);
00401 sv->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);
00402 }
00403
00404 void Application::setViewportByDrawManager(osg::Viewport* vp, vrj::GlDrawManager* mgr)
00405 {
00406 float vpX,vpY,vpW,vpH;
00407 unsigned int winX,winY,winW,winH;
00408
00409 mgr->currentUserData()->getViewport()->getOriginAndSize(vpX,vpY,vpW,vpH);
00410 mgr->currentUserData()->getGlWindow()->getOriginSize(winX,winY,winW,winH);
00411
00412 unsigned int x,y,w,h;
00413 x = unsigned(vpX*float(winW));
00414 y = unsigned(vpY*float(winH));
00415 w = unsigned(vpW*float(winW));
00416 h = unsigned(vpH*float(winH));
00417
00418 vp->setViewport(x,y,w,h);
00419 }
00420
00421 void Application::update()
00422 {
00423 if(_scene_data.valid() && _update_visitor.valid())
00424 {
00425 _update_visitor->reset();
00426 _update_visitor->setFrameStamp(_frame_stamp.get());
00427
00428 if(_frame_stamp.valid())
00429 {
00430 _update_visitor->setTraversalNumber(_frame_stamp->getFrameNumber());
00431 }
00432
00433 getSceneData()->accept(*_update_visitor.get());
00434 getSceneData()->getBound();
00435 }
00436 }
00437
00438 void Application::quit()
00439 {
00440 vrj::Kernel::instance()->stop();
00441 }
00442
00443
00445
00446
00447
00449
00450 void Application::normalize ( bool on )
00451 {
00452 const osg::StateSet *temp = this->getGlobalStateSet();
00453 if ( !temp )
00454 throw std::runtime_error ( "Error 4271807142, failed to get global state set." );
00455
00456 osg::ref_ptr<osg::StateSet> ss ( new osg::StateSet ( *temp ) );
00457 if ( !ss.valid() )
00458 throw std::runtime_error ( "Error 2255713473, failed to copy global state set." );
00459
00460 ss->setMode ( GL_NORMALIZE, ( ( on ) ? osg::StateAttribute::ON : osg::StateAttribute::OFF ) );
00461 this->setGlobalStateSet ( ss.get() );
00462 }
00463
00464
00466
00467
00468
00470
00471 bool Application::normalize() const
00472 {
00473 const osg::StateSet *ss = this->getGlobalStateSet();
00474 return ( ( ss && osg::StateAttribute::ON == ss->getMode ( GL_NORMALIZE ) ) ? true : false );
00475 }