/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial applications, * as long as this copyright notice is maintained. * * This application 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void createScene(osgViewer::Viewer* viewer) { osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); if (!wsi) { osg::notify(osg::NOTICE) << "Error, no WindowingSystemInterface available, cannot create windows." << std::endl; return; } unsigned int screenWidth; unsigned int screenHeight; wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), screenWidth, screenHeight); osg::ref_ptr mOsgExternalDepth = new osg::Texture2D; mOsgExternalDepth->setSourceFormat(GL_DEPTH_COMPONENT); mOsgExternalDepth->setSourceType(GL_FLOAT); mOsgExternalDepth->setInternalFormat(GL_DEPTH_COMPONENT32F); mOsgExternalDepth->setTextureWidth(screenWidth); mOsgExternalDepth->setTextureHeight(screenHeight); mOsgExternalDepth->setResizeNonPowerOfTwoHint(false); mOsgExternalDepth->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST); mOsgExternalDepth->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST); mOsgExternalDepth->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE); mOsgExternalDepth->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE); osg::ref_ptr mainCamera = viewer->getCamera(); osg::ref_ptr mOsgExternalColor = new osg::Texture2D; mOsgExternalColor->setInternalFormat(GL_RGBA16F_ARB); mOsgExternalColor->setSourceFormat(GL_RGBA); mOsgExternalColor->setSourceType(GL_FLOAT); mOsgExternalColor->setTextureWidth(screenWidth); mOsgExternalColor->setTextureHeight(screenHeight); mOsgExternalColor->setResizeNonPowerOfTwoHint(false); mOsgExternalColor->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST); mOsgExternalColor->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST); mOsgExternalColor->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE); mOsgExternalColor->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE); // Uncomment this to reproduce //mainCamera->attach(osg::Camera::COLOR_BUFFER, (osg::Texture*)mOsgExternalColor); mainCamera->attach(osg::Camera::DEPTH_BUFFER, (osg::Texture*)mOsgExternalDepth); const std::map map = mainCamera->getBufferAttachmentMap(); std::map::const_iterator itr = map.find(osg::Camera::DEPTH_BUFFER); if (itr != map.end()) { const osg::Camera::Attachment att = itr->second; } osg::ref_ptr camera = new osg::Camera; camera->setProjectionMatrix(osg::Matrixd::ortho2D(0, screenWidth, 0, screenHeight)); camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); camera->setViewMatrix(osg::Matrixd::identity()); camera->setClearMask(GL_DEPTH_BUFFER_BIT); camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setAllowEventFocus(false); viewer->getSceneData()->asGroup()->addChild(camera); osg::ref_ptr quad = osg::createTexturedQuadGeometry(osg::Vec3(0, 0, 0), osg::Vec3(screenWidth / 2, 0, 0), osg::Vec3(0, screenHeight / 2, 0)); quad->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, mOsgExternalDepth); const std::string vertShader = ""\ "void main() "\ "{ "\ " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; "\ " gl_TexCoord[0] = gl_TextureMatrix[0] *gl_MultiTexCoord0;"\ "}"; const std::string fragShader = ""\ "uniform sampler2D texture0; "\ "void main() "\ "{ "\ " float d = texture2D( texture0, gl_TexCoord[0].xy ).x; "\ " gl_FragColor = vec4(d, d, d, 1); "\ "}"; osg::ref_ptr vert = new osg::Shader(osg::Shader::VERTEX, vertShader); osg::ref_ptr frag = new osg::Shader(osg::Shader::FRAGMENT, fragShader); osg::ref_ptr program = new osg::Program; program->addShader(vert); program->addShader(frag); quad->getOrCreateStateSet()->setAttributeAndModes(program); quad->getOrCreateStateSet()->addUniform(new osg::Uniform(osg::Uniform::SAMPLER_2D, "texture0", 0)); osg::ref_ptr quadColor = osg::createTexturedQuadGeometry(osg::Vec3(screenWidth / 2, 0, 0), osg::Vec3(screenWidth / 2, 0, 0), osg::Vec3(0, screenHeight / 2, 0)); quadColor->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); quadColor->getOrCreateStateSet()->setTextureAttributeAndModes(0, mOsgExternalColor); camera->addChild(quadColor); camera->addChild(quad); } int main(int argc, char** argv) { // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); arguments.getApplicationUsage()->addCommandLineOption("--image ","Load an image and render it on a quad"); arguments.getApplicationUsage()->addCommandLineOption("--dem ","Load an image/DEM and render it on a HeightField"); arguments.getApplicationUsage()->addCommandLineOption("--login ","Provide authentication information for http file access."); arguments.getApplicationUsage()->addCommandLineOption("-p ","Play specified camera path animation file, previously saved with 'z' key."); arguments.getApplicationUsage()->addCommandLineOption("--speed ","Speed factor for animation playing (1 == normal speed)."); arguments.getApplicationUsage()->addCommandLineOption("--device ","add named device to the viewer"); arguments.getApplicationUsage()->addCommandLineOption("--stats","print out load and compile timing stats"); osgViewer::Viewer viewer(arguments); unsigned int helpType = 0; if ((helpType = arguments.readHelpType())) { arguments.getApplicationUsage()->write(std::cout, helpType); return 1; } // report any errors if they have occurred when parsing the program arguments. if (arguments.errors()) { arguments.writeErrorMessages(std::cout); return 1; } if (arguments.argc()<=1) { arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); return 1; } bool printStats = arguments.read("--stats"); std::string url, username, password; while(arguments.read("--login",url, username, password)) { osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( url, new osgDB::AuthenticationDetails(username, password) ); } std::string device; while(arguments.read("--device", device)) { osg::ref_ptr dev = osgDB::readRefFile(device); if (dev.valid()) { viewer.addDevice(dev); } } // set up the camera manipulators. { osg::ref_ptr 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() ); keyswitchManipulator->addMatrixManipulator( '5', "Orbit", new osgGA::OrbitManipulator() ); keyswitchManipulator->addMatrixManipulator( '6', "FirstPerson", new osgGA::FirstPersonManipulator() ); keyswitchManipulator->addMatrixManipulator( '7', "Spherical", new osgGA::SphericalManipulator() ); std::string pathfile; double animationSpeed = 1.0; while(arguments.read("--speed",animationSpeed) ) {} char keyForAnimationPath = '8'; while (arguments.read("-p",pathfile)) { osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile); if (apm && !apm->getAnimationPath()->empty()) { apm->setTimeScale(animationSpeed); unsigned int num = keyswitchManipulator->getNumMatrixManipulators(); keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm ); keyswitchManipulator->selectMatrixManipulator(num); ++keyForAnimationPath; } } viewer.setCameraManipulator( keyswitchManipulator.get() ); } // add the state manipulator viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); // add the thread model handler viewer.addEventHandler(new osgViewer::ThreadingHandler); // add the window size toggle handler viewer.addEventHandler(new osgViewer::WindowSizeHandler); // add the stats handler viewer.addEventHandler(new osgViewer::StatsHandler); // add the help handler viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage())); // add the record camera path handler viewer.addEventHandler(new osgViewer::RecordCameraPathHandler); // add the LOD Scale handler viewer.addEventHandler(new osgViewer::LODScaleHandler); // add the screen capture handler viewer.addEventHandler(new osgViewer::ScreenCaptureHandler); osg::ElapsedTime elapsedTime; // load the data osg::ref_ptr loadedModel = osgDB::readRefNodeFiles(arguments); if (!loadedModel) { std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; return 1; } if (printStats) { double loadTime = elapsedTime.elapsedTime_m(); std::cout<<"Load time "<collectStats("compile", true); } // any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized(); // report any errors if they have occurred when parsing the program arguments. if (arguments.errors()) { arguments.writeErrorMessages(std::cout); return 1; } // optimize the scene graph, remove redundant nodes and state etc. osgUtil::Optimizer optimizer; optimizer.optimize(loadedModel); osg::ref_ptr root = new osg::Group; root->addChild(loadedModel); viewer.setSceneData(root); createScene(&viewer); viewer.realize(); return viewer.run(); }