#if defined(_MSC_VER) #pragma warning( disable : 4786 ) #endif #include #if !defined(WIN32) && !defined(macintosh) #include #include #endif #include #include #include #include "osgGLUT/Viewer" #include "osgGLUT/GLUTEventAdapter" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WIN32 #define USE_FLTK #define USE_GLUT #endif #include #ifdef WIN32 #include #else #endif #include osg::Timer g_timer; osg::Timer_t g_initTime; //static GLenum polymodes [] = { GL_FILL, GL_LINE, GL_POINT }; static osg::PolygonMode::Mode polymodes [] = { osg::PolygonMode::FILL, osg::PolygonMode::LINE, osg::PolygonMode::POINT }; using namespace osg; using namespace osgUtil; using namespace osgGLUT; Viewer* Viewer::s_theViewer = 0; Viewer::Viewer() { s_theViewer = this; fullscreen = false; _is_open = 0; _saved_wx = wx = _saved_wy = wy = 0; _saved_ww = ww = 800, _saved_wh = wh = 600; _title = "OSG Viewer"; mx = ww/2, my = wh/2; mbutton = 0; polymode = 0; texture = 1; backface = 1; lighting = 1; flat_shade = 0; _printStats = 0; // gwm change from bool was : false; #ifdef SGV_USE_RTFS fs = new RTfs( RTFS_MODE_RTC_SPIN ); frame_rate = 16; fs->setUpdateRate( frame_rate ); #endif _viewFrustumCullingActive = true; _smallFeatureCullingActive = true; _two_sided_lighting=0; _useDisplayLists = true; _saveFileName = "saved_model.osg"; osg::notify(osg::INFO)<<"Scene Graph Viewer (sgv)"<_cameraManipList.empty()) { osg::notify(osg::NOTICE)<<"osgGLUT::Viewer::open() called without any camara manipulators registered for a viewport,"<_cameraManipulator.valid()) selectCameraManipulator(0,index); } GLUTEventAdapter::setWindowSize( wx, wy, ww, wh ); GLUTEventAdapter::setButtonMask(0); // Set the absolute viewport for each SceneView based on the // relative viewport coordinates given to us for(itr=_viewportList.begin(); itr!=_viewportList.end(); ++itr) { osgUtil::SceneView* sceneView = itr->sceneView.get(); int view[4] = { int(itr->viewport[0]*ww), int(itr->viewport[1]*wh), int(itr->viewport[2]*ww), int(itr->viewport[3]*wh) }; sceneView->setViewport(view[0], view[1], view[2], view[3]); osg::ref_ptr ea = new GLUTEventAdapter; ea->adaptResize(clockSeconds(), view[0], view[1], view[0]+view[2], view[1]+view[3]); if (itr->_cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled reshape "<sceneView->getSceneData(); if (node) node->accept(vrv); } #ifdef _DEBUG vrv.setMinimumNumStencilBits(8); //gwm 12.8.01 to force stencils available for DC test #endif // set up each render stage to clear the appropriate buffers. GLbitfield clear_mask=0; if (vrv.requiresRGB()) clear_mask |= GL_COLOR_BUFFER_BIT; if (vrv.requiresDepthBuffer()) clear_mask |= GL_DEPTH_BUFFER_BIT; if (vrv.requiresStencilBuffer()) clear_mask |= GL_STENCIL_BUFFER_BIT; for(itr=_viewportList.begin(); itr!=_viewportList.end(); ++itr) { osgUtil::RenderStage *stage = itr->sceneView->getRenderStage(); stage->setClearMask(clear_mask); } // set the GLUT display mode bit mask up to handle it. unsigned int displayMode=0; if (vrv.requiresDoubleBuffer()) displayMode |= GLUT_DOUBLE; else displayMode |= GLUT_SINGLE; if (vrv.requiresRGB()) displayMode |= GLUT_RGB; if (vrv.requiresDepthBuffer()) displayMode |= GLUT_DEPTH; if (vrv.requiresAlphaBuffer()) displayMode |= GLUT_ALPHA; if (vrv.requiresStencilBuffer()) displayMode |= GLUT_STENCIL; // and we'll add in multisample so that on systems like Onyx's can // go ahead and use there loverly anti-aliasing. This is ignored // by other systems I've come across so not need to worry about it. displayMode |= GLUT_MULTISAMPLE; osg::notify(osg::INFO) <<"osgGLUT::Viewer::open() requesting displayMode = "<=_viewportList.size()) return; _focusedViewport = pos; } void Viewer::selectCameraManipulator(unsigned int pos, unsigned int viewport) { if (viewport>=_viewportList.size()) return; ViewportDef &viewp = _viewportList[viewport]; if (pos>=viewp._cameraManipList.size()) return; viewp._cameraManipulator = viewp._cameraManipList[pos]; osgUtil::SceneView *sceneView = viewp.sceneView.get(); viewp._cameraManipulator->setCamera(sceneView->getCamera()); viewp._cameraManipulator->setNode(sceneView->getSceneData()); osg::ref_ptr ea = new GLUTEventAdapter; viewp._cameraManipulator->init(*ea,*this); } void Viewer::requestWarpPointer(int x,int y) { // glutWarpPointer core dumps if invoked before a GLUT window is open if ( !_is_open ) { osg::notify(osg::INFO)<<"osgGLUT::Viewer::requestWarpPointer() called with window closed; ignored."<setFrameStamp(_frameStamp.get()); getViewportSceneView(viewport)->app(); // update the camera manipulator. osg::ref_ptr ea = new GLUTEventAdapter; ea->adaptFrame(_frameStamp->getReferenceTime()); if (_viewportList[viewport]._cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled update frame"<cull(); osg::Timer_t beforeDraw = _timer.tick(); return _timer.delta_m(beforeCull,beforeDraw); } float Viewer::draw(unsigned int viewport) { osg::Timer_t beforeDraw = _timer.tick(); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,_two_sided_lighting); // do draw traversal. getViewportSceneView(viewport)->draw(); osg::Timer_t afterDraw = _timer.tick(); return _timer.delta_m(beforeDraw,afterDraw); } int Viewer::mapWindowXYToSceneView(int x, int y) { int ogl_y = wh-y; int index = 0; for(ViewportList::iterator itr=_viewportList.begin(); itr!=_viewportList.end(); ++itr, ++index) { if ( x >= int( itr->viewport[0]*ww ) && ogl_y >= int( itr->viewport[1]*wh ) && x <= int( (itr->viewport[0]+itr->viewport[2])*ww ) && ogl_y <= int( (itr->viewport[1]+itr->viewport[3])*wh ) ) return index; } return -1; } void Viewer::displayCB() { s_theViewer->display(); } //void Viewer::reshapeCB(GLint w, GLint h) void Viewer::reshapeCB(int w, int h) { s_theViewer->reshape(w, h); } void Viewer::visibilityCB( int state ) { s_theViewer->visibility(state); } void Viewer::mouseCB(int button, int state, int x, int y) { s_theViewer->mouse(button, state, x, y); } void Viewer::mouseMotionCB(int x, int y) { s_theViewer->mouseMotion(x,y); } void Viewer::mousePassiveMotionCB(int x, int y) { s_theViewer->mousePassiveMotion(x,y); } void Viewer::keyboardCB(unsigned char key, int x, int y) { s_theViewer->keyboard(key,x,y); } GLuint makeRasterFont(void) { // GWM creates a set of display lists which may be used to render a character string on the screen // data from GWM's reading of the Windows ASCII_FIXED_FONT. GLubyte rasters[][12] = { // ascii symbols 32-127, small font {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x00}, {0x00, 0x00, 0x28, 0x28, 0x7e, 0x14, 0x14, 0x14, 0x3f, 0x0a, 0x0a, 0x00}, {0x00, 0x00, 0x08, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c, 0x08, 0x00}, {0x00, 0x00, 0x02, 0x45, 0x22, 0x10, 0x08, 0x04, 0x22, 0x51, 0x20, 0x00}, {0x00, 0x00, 0x3b, 0x44, 0x4a, 0x49, 0x30, 0x10, 0x20, 0x20, 0x18, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00}, {0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00}, {0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x36, 0x1c, 0x7f, 0x1c, 0x36, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00}, {0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00}, {0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00}, {0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x08, 0x00}, {0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x22, 0x1c, 0x00}, {0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x22, 0x1c, 0x00}, {0x00, 0x00, 0x0e, 0x04, 0x3e, 0x24, 0x14, 0x14, 0x0c, 0x0c, 0x04, 0x00}, {0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x3c, 0x20, 0x20, 0x20, 0x3e, 0x00}, {0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x10, 0x0c, 0x00}, {0x00, 0x00, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x22, 0x3e, 0x00}, {0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00}, {0x00, 0x00, 0x18, 0x04, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1c, 0x00}, {0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x04, 0x02, 0x02, 0x22, 0x1c, 0x00}, {0x00, 0x00, 0x1c, 0x20, 0x4e, 0x55, 0x55, 0x55, 0x4d, 0x21, 0x1e, 0x00}, {0x00, 0x00, 0x77, 0x22, 0x3e, 0x22, 0x14, 0x14, 0x08, 0x08, 0x18, 0x00}, {0x00, 0x00, 0x7e, 0x21, 0x21, 0x21, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00}, {0x00, 0x00, 0x1e, 0x21, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, 0x1e, 0x00}, {0x00, 0x00, 0x7c, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x7c, 0x00}, {0x00, 0x00, 0x7f, 0x21, 0x20, 0x24, 0x3c, 0x24, 0x20, 0x21, 0x7f, 0x00}, {0x00, 0x00, 0x78, 0x20, 0x20, 0x24, 0x3c, 0x24, 0x20, 0x21, 0x7f, 0x00}, {0x00, 0x00, 0x1e, 0x21, 0x41, 0x47, 0x40, 0x40, 0x40, 0x21, 0x1e, 0x00}, {0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x77, 0x00}, {0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00}, {0x00, 0x00, 0x38, 0x44, 0x44, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1e, 0x00}, {0x00, 0x00, 0x73, 0x22, 0x24, 0x38, 0x28, 0x24, 0x24, 0x22, 0x73, 0x00}, {0x00, 0x00, 0x7f, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00}, {0x00, 0x00, 0x77, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x36, 0x22, 0x63, 0x00}, {0x00, 0x00, 0x72, 0x22, 0x26, 0x26, 0x2a, 0x32, 0x32, 0x22, 0x67, 0x00}, {0x00, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00}, {0x00, 0x00, 0x78, 0x20, 0x20, 0x20, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00}, {0x00, 0x1b, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00}, {0x00, 0x00, 0x73, 0x22, 0x24, 0x24, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00}, {0x00, 0x00, 0x3e, 0x41, 0x01, 0x01, 0x3e, 0x40, 0x40, 0x41, 0x3e, 0x00}, {0x00, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x49, 0x7f, 0x00}, {0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x77, 0x00}, {0x00, 0x00, 0x08, 0x08, 0x14, 0x14, 0x14, 0x22, 0x22, 0x22, 0x77, 0x00}, {0x00, 0x00, 0x14, 0x14, 0x2a, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x77, 0x00}, {0x00, 0x00, 0x77, 0x22, 0x14, 0x14, 0x08, 0x14, 0x14, 0x22, 0x77, 0x00}, {0x00, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00}, {0x00, 0x00, 0x7f, 0x21, 0x10, 0x10, 0x08, 0x04, 0x04, 0x42, 0x7f, 0x00}, {0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00}, {0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00}, {0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08}, {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00}, {0x00, 0x00, 0x3d, 0x42, 0x42, 0x3e, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x7e, 0x21, 0x21, 0x21, 0x21, 0x3e, 0x20, 0x20, 0x60, 0x00}, {0x00, 0x00, 0x3e, 0x41, 0x40, 0x40, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x3f, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x06, 0x00}, {0x00, 0x00, 0x3e, 0x41, 0x40, 0x7f, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x3c, 0x10, 0x10, 0x10, 0x10, 0x3c, 0x10, 0x10, 0x0c, 0x00}, {0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3f, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x32, 0x2c, 0x20, 0x20, 0x60, 0x00}, {0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x08, 0x00}, {0x38, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x3c, 0x00, 0x00, 0x04, 0x00}, {0x00, 0x00, 0x63, 0x24, 0x38, 0x28, 0x24, 0x26, 0x20, 0x20, 0x60, 0x00}, {0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00}, {0x00, 0x00, 0x6b, 0x2a, 0x2a, 0x2a, 0x2a, 0x74, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x32, 0x6c, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x3e, 0x41, 0x41, 0x41, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00}, {0x70, 0x20, 0x3e, 0x21, 0x21, 0x21, 0x21, 0x7e, 0x00, 0x00, 0x00, 0x00}, {0x07, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x3f, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x19, 0x76, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x3e, 0x41, 0x06, 0x38, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x0c, 0x12, 0x10, 0x10, 0x10, 0x3c, 0x10, 0x10, 0x00, 0x00}, {0x00, 0x00, 0x1b, 0x26, 0x22, 0x22, 0x22, 0x66, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x14, 0x14, 0x2a, 0x2a, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x77, 0x22, 0x1c, 0x1c, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00}, {0x30, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x7e, 0x22, 0x10, 0x08, 0x44, 0x7e, 0x00, 0x00, 0x00, 0x00}, {0x06, 0x08, 0x08, 0x08, 0x08, 0x30, 0x08, 0x08, 0x08, 0x08, 0x06, 0x00}, {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, {0x30, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x49, 0x31, 0x00, 0x00}, {0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x00} }; // the remaining lines of this routine are similar to code developed and published in the // OPENGL big red book. However I have modified the code slightly, and // SGI are not responsible for any errors, omissions etc. static GLuint fontOffset; // first display list if (!fontOffset) { // then make the raster fonts GLuint i; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); fontOffset = glGenLists (128); for (i = 32; i < 127; i++) { glNewList(i+fontOffset, GL_COMPILE); glBitmap(8, 12, 0.0, 2.0, 10.0, 0.0, rasters[i-32]); glEndList(); } } return fontOffset; } void displaytext(int x, int y, char *s) { // GWM July 2001 statistics text display at xy text S GLuint fontOffset=makeRasterFont(); // first display list glRasterPos2i(x,y); // glPushAttrib (GL_LIST_BIT); glListBase(fontOffset); glCallLists(strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); glListBase(0); // glPopAttrib (); } // GWM July 2001 - add Statistics structure, and related RenderBin #include #include void Viewer::showStats() { static GLfloat tmax=100; glViewport(0,0,ww,wh); float vh = wh; glDisable( GL_DEPTH_TEST ); // to see the stats always glDisable( GL_ALPHA_TEST ); glDisable( GL_LIGHTING ); glDisable( GL_TEXTURE_2D ); glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); // set tmax using hysteresis to prevent flip-flopping between two values of tmax if (times[2].timeFrame>360.0f && tmax<1600) tmax=1600; else if (times[2].timeFrame<300.0f && tmax>800) tmax=800; else if (times[2].timeFrame>180.0f && tmax<800) tmax=800; else if (times[2].timeFrame<150.0f && tmax>400) tmax=400; else if (times[2].timeFrame>90.0f && tmax<400) tmax=400; else if (times[2].timeFrame<75.0f && tmax>200) tmax=200; else if (times[2].timeFrame>45.0f && tmax<200) tmax=200; else if (times[2].timeFrame<36.0f && tmax>100) tmax=100; glOrtho(-0.1f*tmax, tmax*1.1f,0,vh,0,500); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); glDisable(GL_STENCIL_TEST); // dont want to count pixels set by performance graphs if (_printStats>0) { // output the text frame rate char clin[72]; // buffer to print glColor3f(1.0f,1.0f,0.0f); if (frRate>10.0f) { float smoothRatio = 0.4; // should be >0 and <= 1.0, // lower the value greater smoothing. frRate=(1.0f-smoothRatio)*frRate+smoothRatio*frameRate(); // smooth out variations in frame rate } else { frRate=frameRate(); // frame rate so slow no need to smooth in frame rate } sprintf(clin,"%.1f Hz.", frRate); displaytext(0,(int)(0.98f*vh),clin); } if (_printStats>1) { // more stats - graphs this time int sampleIndex = 2; float timeApp=times[sampleIndex].timeApp; float timeCull=times[sampleIndex].timeCull; float timeDraw=times[sampleIndex].timeDraw; float timeFrame=times[sampleIndex].timeFrame; osg::Vec4 app_color(0.0f,1.0f,0.0f,1.0f); osg::Vec4 cull_color(1.0f,0.0f,1.0f,1.0f); osg::Vec4 draw_color(0.0f,1.0f,1.0f,1.0f); osg::Vec4 swap_color(1.0f,0.5f,0.5f,1.0f); osg::Vec4 frame_color(1.0f,1.0f,0.0f,1.0f); char clin[72]; // buffer to print glColor4fv((GLfloat * )&app_color); sprintf(clin,"App %.1f ms.", timeApp); displaytext((int)(.15f*tmax),(int)(0.98f*vh),clin); glColor4fv((GLfloat * )&cull_color); sprintf(clin,"Cull %.1f ms.", timeCull); displaytext((int)(.35*tmax),(int)(0.98f*vh),clin); glColor4fv((GLfloat * )&draw_color); sprintf(clin,"Draw %.1f ms.", timeDraw); displaytext((int)(.55*tmax),(int)(0.98f*vh),clin); glColor4fv((GLfloat * )&frame_color); sprintf(clin,"Frame %.1f ms.", timeFrame); displaytext((int)(.75*tmax),(int)(0.98f*vh),clin); /* osg::notify(osg::NOTICE) << "Time of App "<sceneView->getRenderStage(); stage->getPrims(&primStats); } glColor3f(.9f,.9f,0.0f); sprintf(clin,"%d Prims %d Matrices %d nGsets %d nlights %d bins", primStats.nprims, primStats.nummat, primStats.numOpaque, primStats.nlights, primStats.nbins); displaytext(0,(int)(0.86f*vh),clin); strcpy(clin," "); for (i=0; i<15; i++) { if (i==0 || primStats.primtypes[i]) { strcat(clin, prtypes[i]); } } displaytext(0,(int)(0.82f*vh),clin); strcpy(clin,"GSet type: "); for (i=0; i<15; i++) { if (primStats.primtypes[i]) { sprintf(ctmp,"%5d", primStats.primtypes[i]); strcat(clin, ctmp); } } displaytext(0,(int)(0.80f*vh),clin); strcpy(clin,"Prims: "); for (i=0; i<15; i++) { if (primStats.numprimtypes[i]) { sprintf(ctmp,"%5d", primStats.numprimtypes[i]); strcat(clin, ctmp); } } displaytext(0,(int)(0.78f*vh),clin); strcpy(clin,"Triangles: "); for (i=0; i<15; i++) { if (primStats.primlens[i]) { sprintf(ctmp,"%5d", primStats.primlens[i]); strcat(clin, ctmp); } } displaytext(0,(int)(0.76f*vh),clin); strcpy(clin,"Vertices: "); for (i=0; i<15; i++) { if (primStats.primlens[i]) { sprintf(ctmp,"%5d", primStats.primverts[i]); strcat(clin, ctmp); } } displaytext(0,(int)(0.74f*vh),clin); } if (_printStats==4) { // yet more stats - read the depth complexity int wid=ww, ht=wh; // temporary local screen size - must change during this section if (wid>0 && ht>0) { const int blsize=16; char *clin=new char[wid/blsize+2]; // buffer to print dc char *ctext=new char[128]; // buffer to print details float mdc=0; GLubyte *buffer=new GLubyte[wid*ht]; if (buffer) { glPixelStorei(GL_PACK_ALIGNMENT, 1); // no extra bytes at ends of rows- easier to analyse glColor3f(.9f,.9f,0.0f); glReadPixels(0,0,wid,ht, GL_STENCIL_INDEX ,GL_UNSIGNED_BYTE, buffer); for (int j=0; j=0 && ii>=0) { dc+=buffer[ii+ (ht-jj-1)*wid]; nav++; } } } mdc+=dc; if (dcsetFrameNumber(_frameStamp->getFrameNumber()+1); _frameStamp->setReferenceTime(clockSeconds()); // application traverasal. times[2].timeApp=0.0f; // cull traverasal. times[2].timeCull=0.0f; // draw traverasal. times[2].timeDraw=0.0f; for(int i = 0; i < getNumViewports(); i++ ) { // application traverasal. times[2].timeApp+=app(i); // cull traverasal. times[2].timeCull+=cull(i); // draw traverasal. times[2].timeDraw+=draw(i); } if (_printStats>1) glFinish(); times[2].frameend=updateFrameTick(); // absolute time times[2].timeFrame=frameSeconds()*1000; if (_printStats) { // gwm output selected stats at this point - convert to a graph. showStats(); times[0]=times[1]; times[1]=times[2]; } glutSwapBuffers(); // moved after draw of stats & glFinish() to get accurate timing (excluding stat draw!) // cout << "Time elapsed "<<_timer.delta_s(_initialTick,_timer.tick())<1) glFinish(); #ifdef SGV_USE_RTFS fs->frame(); #endif } void Viewer::reshape(GLint w, GLint h) { ww = w; wh = h; // Propagate new window size to viewports for(ViewportList::iterator itr=_viewportList.begin(); itr!=_viewportList.end(); ++itr) { osgUtil::SceneView* sceneView = itr->sceneView.get(); int view[4] = { int(itr->viewport[0]*ww), int(itr->viewport[1]*wh), int(itr->viewport[2]*ww), int(itr->viewport[3]*wh) }; sceneView->setViewport(view[0], view[1], view[2], view[3]); osg::ref_ptr ea = new GLUTEventAdapter; ea->adaptResize(clockSeconds(), view[0], view[1], view[0]+view[2], view[1]+view[3]); if (itr->_cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled reshape "< ea = new GLUTEventAdapter; ea->adaptMouseMotion(clockSeconds(),x,y); if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled mouseMotion "<_buttonMask<<" x="<_mx<<" y="<_my< ea = new GLUTEventAdapter; ea->adaptMousePassiveMotion(clockSeconds(),x,y); // Switch viewport focus if no buttons are pressed if (ea->getButtonMask() == 0) { int focus = mapWindowXYToSceneView(x,y); if (focus >= 0 && focus != int(_focusedViewport)) setFocusedViewport(focus); } if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled mousePassiveMotion "<_buttonMask<<" x="<_mx<<" y="<_my< ea = new GLUTEventAdapter; ea->adaptMouse(clockSeconds(),button,state,x,y); // Switch viewport focus if button is pressed, and it is the only one unsigned mask = ea->getButtonMask(); if (state == GLUT_DOWN && (mask == osgUtil::GUIEventAdapter::LEFT_BUTTON || mask == osgUtil::GUIEventAdapter::MIDDLE_BUTTON || mask == osgUtil::GUIEventAdapter::RIGHT_BUTTON)) { int focus = mapWindowXYToSceneView(x,y); if (focus >= 0 && focus != int(_focusedViewport)) setFocusedViewport(focus); } if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled mouse "<_buttonMask<<" x="<_mx<<" y="<_my< ea = new GLUTEventAdapter; ea->adaptKeyboard(clockSeconds(),key,x,y); if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) return; if (key>='1' && key<='3') { int pos = key-'1'; selectCameraManipulator(pos); } osgUtil::SceneView* sceneView = getViewportSceneView(_focusedViewport); switch( key ) { case '7' : sceneView->setBackgroundColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); break; case '8' : sceneView->setBackgroundColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); break; case '9' : sceneView->setBackgroundColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); break; case '/' : if (sceneView->getLODBias()>0.5) sceneView->setLODBias(sceneView->getLODBias()/1.5f); break; case '*' : if (sceneView->getLODBias()<30) sceneView->setLODBias(sceneView->getLODBias()*1.5f); break; case '+' : #ifdef SGV_USE_RTFS frame_rate <<= 1; fs->stop(); fs->setUpdateRate( frame_rate ); fs->start(); #endif break; case '-' : #ifdef SGV_USE_RTFS frame_rate >>= 1; if( frame_rate < 1 ) frame_rate = 1; fs->stop(); fs->setUpdateRate( frame_rate ); fs->start(); #endif break; case 'd' : _useDisplayLists = !_useDisplayLists; if (_useDisplayLists) { // traverse the scene graph setting up all osg::GeoSet's so they will use // OpenGL display lists. osgUtil::DisplayListVisitor dlv(osgUtil::DisplayListVisitor::SWITCH_ON_DISPLAY_LISTS); sceneView->getSceneData()->accept(dlv); osg::notify(osg::NOTICE) << "Switched on use of OpenGL Display Lists."<getSceneData()->accept(dlv); osg::notify(osg::NOTICE) << "Switched off use of OpenGL Display Lists."<4) _printStats=0; if (_printStats==4) { // count depth complexity by incrementing the stencil buffer every // time a pixel is hit int nsten=0; // Number of stencil planes available glGetIntegerv(GL_STENCIL_BITS , &nsten); if (nsten>0) { glEnable(GL_STENCIL_TEST); glStencilOp(GL_INCR ,GL_INCR ,GL_INCR); } else {// skip this option _printStats++; } } break; case 's' : flat_shade = 1 - flat_shade ; if( flat_shade ) glShadeModel( GL_FLAT ); else glShadeModel( GL_SMOOTH ); break; case 'S' : { osg::notify(osg::NOTICE) << "Smoothing scene..."<getSceneData()->accept(sv); osg::notify(osg::NOTICE) << "Smoothed scene."<getSceneData()->accept(tsv); osg::notify(osg::NOTICE) << "Tri Striping scene scene."<getGlobalState()->setMode(GL_CULL_FACE,osg::StateAttribute::ON); else sceneView->getGlobalState()->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE_OFF); break; case 'l' : lighting = 1 - lighting ; if( lighting ) sceneView->getGlobalState()->setMode(GL_LIGHTING,osg::StateAttribute::ON); else sceneView->getGlobalState()->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_OFF); break; case 'L' : { osgUtil::SceneView::LightingMode lm= sceneView->getLightingMode(); switch(lm) { case(osgUtil::SceneView::HEADLIGHT) : lm = osgUtil::SceneView::SKY_LIGHT; break; case(osgUtil::SceneView::SKY_LIGHT) : lm = osgUtil::SceneView::NO_SCENEVIEW_LIGHT; break; case(osgUtil::SceneView::NO_SCENEVIEW_LIGHT) : lm = osgUtil::SceneView::HEADLIGHT; break; } sceneView->setLightingMode(lm); break; } case 't' : texture = 1 - texture; if (texture) { sceneView->getGlobalState()->setModeToInherit(GL_TEXTURE_2D); // sceneView->getGlobalState()->setAttributeToInherit(osg::StateAttribute::TEXTURE); } else { // use blank texture to override all local texture in scene graph. // thus causing them to all use the same texture attribute, hence // preventing a state attribute change due to unused textures. static osg::ref_ptr blank_texture = new osg::Texture; sceneView->getGlobalState()->setMode(GL_TEXTURE_2D,osg::StateAttribute::OVERRIDE_OFF); // sceneView->getGlobalState()->setAttribute(blank_texture.get(),true); } break; case 'T' : _two_sided_lighting = 1 - _two_sided_lighting; break; case 'w' : { polymode = (polymode+1)%3; osg::PolygonMode* polyModeObj = new osg::PolygonMode; polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,polymodes[polymode]); sceneView->getGlobalState()->setAttribute(polyModeObj); } break; case 'f' : fullscreen = !fullscreen; if (fullscreen) { _saved_ww = ww; _saved_wh = wh; glutFullScreen(); } else { //glutPositionWindow(wx,wy); glutReshapeWindow(_saved_ww,_saved_wh); } break; case 'o' : if (sceneView->getSceneData() && osgDB::writeNodeFile(*sceneView->getSceneData(), _saveFileName)) { osg::notify(osg::NOTICE) << "Saved scene to '"<<_saveFileName<<"'"<getCullVisitor()->setCullingMode((osgUtil::CullViewState::CullingMode) ((_smallFeatureCullingActive ? osgUtil::CullViewState::SMALL_FEATURE_CULLING : osgUtil::CullViewState::NO_CULLING) | (_viewFrustumCullingActive ? osgUtil::CullViewState::VIEW_FRUSTUM_CULLING : osgUtil::CullViewState::NO_CULLING))); if (_smallFeatureCullingActive) { osg::notify(osg::NOTICE) << "Small feature culling switched on "<getCullVisitor()->setCullingMode((osgUtil::CullViewState::CullingMode) ((_smallFeatureCullingActive ? osgUtil::CullViewState::SMALL_FEATURE_CULLING : osgUtil::CullViewState::NO_CULLING) | (_viewFrustumCullingActive ? osgUtil::CullViewState::VIEW_FRUSTUM_CULLING : osgUtil::CullViewState::NO_CULLING))); break; case 'P' : sceneView->setPrioritizeTextures(!sceneView->getPrioritizeTextures()); if (sceneView->getPrioritizeTextures()) { osg::notify(osg::NOTICE) << "Prioritize textures switched on "<projectWindowXYIntoObject(x,wh-y,near_point,far_point)) { osg::notify(osg::NOTICE) << "Failed to calculate intersection ray."< LineSegment = new osg::LineSegment; LineSegment->set(near_point,far_point); osg::notify(osg::NOTICE) << "start("<start()<<") end("<end()<<")"<getSceneData()->accept(iv); float endTime = clockSeconds(); osg::notify(osg::NOTICE) << "Time for interesection = "<<(endTime-startTime)*1000<<"ms"<_intersectPoint; osg::Vec3 in = hitr->_intersectNormal; osg::Geode* geode = hitr->_geode; osg::notify(osg::NOTICE) << " Itersection Point ("<_matrix) { osg::Vec3 ipEye = ip*(*(hitr->_matrix)); osg::Vec3 inEye = (in+ip)*(*(hitr->_matrix))-ipEye; inEye.normalize(); if (geode) osg::notify(osg::NOTICE) << "Geode '"<getName()<_geoset; osg::notify(osg::NOTICE) << " geoset ("<removeDrawable(gset)<<")"< ea = new GLUTEventAdapter; for(ViewportList::iterator itr=_viewportList.begin(); itr!=_viewportList.end(); ++itr) { itr->_cameraManipulator->home(*ea,*this); } updateFrameTick(); #ifdef SGV_USE_RTFS fs->start(); #endif glutMainLoop(); return true; } void Viewer::addViewport(osgUtil::SceneView* sv, float x, float y, float width, float height) { ViewportDef def; def.sceneView = sv; def.viewport[0] = x; def.viewport[1] = y; def.viewport[2] = width; def.viewport[3] = height; _viewportList.push_back(def); } /** * Adds a default SceneView referring to the passed scene graph root. */ void Viewer::addViewport(osg::Node* rootnode, float x, float y, float width, float height) { osgUtil::SceneView *sceneView = new osgUtil::SceneView; sceneView->setDefaults(); sceneView->setSceneData(rootnode); addViewport( sceneView, x, y, width, height ); } void Viewer::init(osg::Node* rootnode) { osg::notify(osg::WARN)<<"Warning - call to Viewer::init(osg::Node*) which is a deprecated method."<