//////////////////////////////////////////////////////////////////////////// // // OSG Problem Scaling To Multiple Cards Test Program // // June 30, 2011 // // Usage: ./osgMultiCardTest displayNumbers file // // // displayNumbers is a list of integer display numbers, // i.e: 0 1 2 3 // // file is an OSG loadable test data file, // typically .osg or .ive // // // Example: // ./osgMultiCardTest 0 testex.ive # display 0 only // ./osgMultiCardTest 0 1 testex.ive # display 0 and 1 // ./osgMultiCardTest 0 1 2 testex.ive # display 0,1,2 // ./osgMultiCardTest 0 1 2 3 testex.ive # display 0,1,2,3 // // Results: // Press the 'S' in the graphics window to get FPS displayed. // // Compile as any typical OSG program: // // For example, the following commands are used at NIST and use // the NIST specific OSG installation directories. // You should use commands appropriate for your site and your // local OSG installation. // // // // /usr/bin/c++ -c \ // -I/usr/local/HEV/external/osg/osg-2.x/installed/include \ // -o osgMultiCardTest.o osgMultiCardTest.cpp // // /usr/bin/c++ osgMultiCardTest.o \ // -L/usr/local/HEV/external/osg/osg-2.x/installed/lib64 \ // -losgViewer \ // -o osgMultiCardTest // // Set these OSG environment variables before running: // // export __GL_SYNC_TO_VBLANK=0 // export OSG_SERIALIZE_DRAW_DISPATCH=OFF // export OSG_THREADING=CullThreadPerCameraDrawThreadPerContext // // //////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include /* create a new window viewer is the OSG viewer object sn is the screen number name is an optional window name */ void newWindow(osgViewer::Viewer& viewer, unsigned int sn, char *name=NULL) { osg::ref_ptr traits = new osg::GraphicsContext::Traits; /* note about sn. How you use sn will depend on your system's X11 DISPLAY configuration. if screen "n" is X11 DISPLAY :0.n, use the first #if 0 below by changing it to #if 1 if screen "n" is X11 DISPLAY :n.0 use the #else below it, which is the current setting you can test your setup by typing the command: env DISPLAY=":0.1" xlogo or env DISPLAY=":1.0" xlogo choose the one that doesn't give an error if both give an error, how do you access your second screen? It needs to have a different X11 DISPLAY value than the first screen if neither give an error, you can choose either method see the osg::GraphicsContext::ScreenIdentifier documentation for more details */ #if 0 traits->screenNum = 0 ; traits->displayNum = sn ; #else traits->screenNum = sn ; traits->displayNum = 0 ; #endif // just create a window that will fit any display traits->x = 100 ; traits->y = 100 ; traits->width = 900 ; traits->height = 900 ; traits->windowDecoration = true; traits->doubleBuffer = true; traits->sharedContext = 0; // optionally label the windows to see if they are where they're supposed to be char foo[256] = "display-" ; strcat(foo,name) ; if (name) traits->windowName = foo ; // create an OpenGL graphics context osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); if (gc.valid()) { osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."< camera = new osg::Camera; camera->setGraphicsContext(gc.get()); camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); // running in double buffered mono GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); // does this make any difference to the problem at hand? // it shouldn't have any impact, but try it both ways to be sure. camera->setReadBuffer(buffer); // add the new camera to the viewer's list of cameras viewer.addSlave(camera.get()) ; } //////////////////////////////////////////////////////////////////////// // usage: $0 s ... // where s is one or more screen numbers -or- display numbers // see the comments in newWindow() for more details int main( int argc, char **argv ) { // create the viewer. osgViewer::Viewer viewer ; // lets us get the frame rate try different threading models viewer.addEventHandler(new osgViewer::StatsHandler) ; viewer.addEventHandler(new osgViewer::ThreadingHandler) ; // in case you want to specify the threading model in the code instead of using the environment variable //viewer.setThreadingModel( osgViewer::ViewerBase::SingleThreaded ); // boilerplate osg::DisplaySettings::instance()->setCompileContextsHint(true) ; // get hooks into X11 osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); if (!wsi) { osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."< loadedModel = osgDB::readNodeFile(argv[argc-1]); if (!loadedModel) { std::cout << argv[0] <<": No data loaded." << std::endl; return 1; } // stick it into the viewer viewer.setSceneData(loadedModel.get()); // create the windows viewer.realize(); // allow us to navigate if (!viewer.getCameraManipulator() && viewer.getCamera()->getAllowEventFocus()) { viewer.setCameraManipulator(new osgGA::TrackballManipulator()); } // more boilerplate viewer.setReleaseContextAtEndOfFrameHint(false); // create first graphics frame- it always takes longer than the others viewer.frame() ; // start the stop watch after we've drawn one frame double start = viewer.getViewerFrameStamp()->getReferenceTime() ; // run until escape pressed while (!viewer.done()) { viewer.frame() ; } osg::FrameStamp *fs = viewer.getViewerFrameStamp() ; // how'd we do? printf("%s: %d frames in %f seconds = %f frames/second\n",argv[0], fs->getFrameNumber(), fs->getReferenceTime(), fs->getFrameNumber()/fs->getReferenceTime()) ; return 0; }