osgEarth 2.1.1

/home/cube/sources/osgearth/src/applications/osgearth_ocean/osgearth_ocean.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003 * Copyright 2008-2010 Pelican Mapping
00004 * http://osgearth.org
00005 *
00006 * osgEarth is free software; you can redistribute it and/or modify
00007 * it under the terms of the GNU Lesser General Public License as published by
00008 * the Free Software Foundation; either version 2 of the License, or
00009 * (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU Lesser General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU Lesser General Public License
00017 * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018 */
00019 #include <osgEarth/Notify>
00020 
00021 #include <osgDB/ReadFile>
00022 #include <osgGA/StateSetManipulator>
00023 #include <osgViewer/Viewer>
00024 #include <osgViewer/ViewerEventHandlers>
00025 
00026 #include <osgEarth/MapNode>
00027 #include <osgEarthUtil/EarthManipulator>
00028 #include <osgEarthUtil/OceanSurfaceNode>
00029 #include <osgEarthUtil/Controls>
00030 
00031 class MyGraphicsContext {
00032     public:
00033         MyGraphicsContext()
00034         {
00035             osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
00036             traits->x = 0;
00037             traits->y = 0;
00038             traits->width = 1;
00039             traits->height = 1;
00040             traits->windowDecoration = false;
00041             traits->doubleBuffer = false;
00042             traits->sharedContext = 0;
00043             traits->pbuffer = true;
00044 
00045             _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
00046 
00047             if (!_gc)
00048             {
00049                 traits->pbuffer = false;
00050                 _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
00051             }
00052 
00053             if (_gc.valid()) 
00054             {
00055                 _gc->realize();
00056                 _gc->makeCurrent();
00057             }
00058         }
00059         
00060         bool valid() const { return _gc.valid() && _gc->isRealized(); }
00061         
00062     private:
00063         osg::ref_ptr<osg::GraphicsContext> _gc;
00064 };
00065 
00066 // build an on-screen menu
00067 static osg::Node* createMenu( osgViewer::View* view )
00068 {
00069     using namespace osgEarth::Util::Controls;
00070 
00071     ControlCanvas* canvas = ControlCanvas::get( view );
00072 
00073     Grid* grid = new Grid();
00074     grid->setBackColor( 0, 0, 0, 0.5 );
00075     grid->setMargin( 5 );
00076     grid->setChildSpacing( 3 );
00077     grid->setVertAlign( Control::ALIGN_BOTTOM );
00078     int row = 0;
00079 
00080     grid->setControl( 1, row++, new LabelControl( "Ocean Demo", 18.0f, osg::Vec4(1,1,0,1) ) );
00081     grid->setControl( 1, row++, new LabelControl( "Zoom in to the coastline to see ocean effects.", 14.0f, osg::Vec4(.6,.6,.6,1) ) );
00082 
00083     grid->setControl( 0, row  , new LabelControl( "e" ) );
00084     grid->setControl( 1, row++, new LabelControl( "toggle ocean effects" ) );
00085     grid->setControl( 0, row  , new LabelControl( "m" ) );
00086     grid->setControl( 1, row++, new LabelControl( "toggle MSL adjustment" ) );
00087     grid->setControl( 0, row  , new LabelControl( "h/H" ) );
00088     grid->setControl( 1, row++, new LabelControl( "inc/dec wave height" ) );
00089     grid->setControl( 0, row  , new LabelControl( "p/P" ) );
00090     grid->setControl( 1, row++, new LabelControl( "inc/dec wave period" ) );
00091     grid->setControl( 0, row  , new LabelControl( "c/C" ) );
00092     grid->setControl( 1, row++, new LabelControl( "inc/dec ocean modulation color" ) );
00093     grid->setControl( 0, row  , new LabelControl( "a/A" ) );
00094     grid->setControl( 1, row++, new LabelControl( "inc/dec shimmer effect period" ) );
00095     grid->setControl( 0, row  , new LabelControl( "j/J" ) );
00096     grid->setControl( 1, row++, new LabelControl( "inc/dec surface image size" ) );
00097     grid->setControl( 0, row  , new LabelControl( "i" ) );
00098     grid->setControl( 1, row++, new LabelControl( "toggle ocean mask inversion" ) );
00099     grid->setControl( 0, row  , new LabelControl( "w" ) );
00100     grid->setControl( 1, row++, new LabelControl( "toggle wireframe mode" ) );
00101 
00102     canvas->addControl( grid );
00103     return canvas;
00104 }
00105 
00106 // An event handler that will print out the elevation at the clicked point
00107 struct MyEventHandler : public osgGA::GUIEventHandler 
00108 {
00109     MyEventHandler( osgEarth::Util::OceanSurfaceNode* ocean )
00110         :_ocean(ocean) { }
00111 
00112     bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
00113     {
00114         if ( ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN )
00115         {
00116             switch (ea.getKey())
00117             {
00118             case 'h':
00119                 {
00120                     _ocean->setWaveHeight( _ocean->getWaveHeight() * 1.1 );
00121                 }
00122                 break;
00123             case 'H':
00124                 {
00125                     _ocean->setWaveHeight( _ocean->getWaveHeight() * 0.9 );
00126                 }
00127                 break;
00128             case 'p':
00129                 {
00130                     _ocean->setPeriod( _ocean->getPeriod() * 1.1 );
00131                 }
00132                 break;
00133             case 'P':
00134                 {
00135                     _ocean->setPeriod( _ocean->getPeriod() * 0.9 );
00136                 }
00137                 break;
00138             case 'e':
00139                 {
00140                     _ocean->setEnabled( !_ocean->getEnabled() );
00141                 }
00142             case 'i':
00143                 {
00144                     _ocean->setInvertMask( !_ocean->getInvertMask() );
00145                 }
00146                 break;
00147             case 'C':
00148                 {
00149                     osg::Vec4f color = _ocean->getModulationColor();
00150                     color.a() = osg::clampBelow( color.a() + 0.1f, 1.0f );
00151                     _ocean->setModulationColor( color );                        
00152                 }
00153                 break;
00154             case 'c':
00155                 {
00156                     osg::Vec4f color = _ocean->getModulationColor();
00157                     color.a() = osg::clampAbove( color.a() - 0.1f, 0.0f );
00158                     _ocean->setModulationColor( color );                        
00159                 }
00160                 break;
00161             case 'A':
00162                 { 
00163                     _ocean->setOceanAnimationPeriod(_ocean->getOceanAnimationPeriod() + 0.25);
00164                 }
00165                 break;
00166             case 'a':
00167                 { 
00168                     _ocean->setOceanAnimationPeriod(_ocean->getOceanAnimationPeriod() - 0.25);
00169                 }
00170                 break;
00171             case 'J':
00172                 {
00173                     _ocean->setOceanSurfaceImageSizeRadians( _ocean->getOceanSurfaceImageSizeRadians() * 1.5f);
00174                 }
00175                 break;
00176             case 'j':
00177                 {
00178                     _ocean->setOceanSurfaceImageSizeRadians( _ocean->getOceanSurfaceImageSizeRadians() * 0.5f);
00179                 }
00180                 break;
00181                         case 'm':
00182                                 {
00183                                         _ocean->setAdjustToMSL( !_ocean->getAdjustToMSL());
00184                                 }
00185                                 break;
00186             }
00187         }
00188         return false;
00189     }
00190 
00191     osg::ref_ptr< osgEarth::Util::OceanSurfaceNode > _ocean;
00192 };
00193 
00194 typedef std::vector< osg::ref_ptr< osg::Image > > ImageList;
00195 
00196 osg::Image* make3DImage(const ImageList& images)
00197 {
00198     MyGraphicsContext gc;
00199     osg::notify(osg::NOTICE) << "Made graphic context " << std::endl;
00200     /*for (unsigned int i = 0; i < images.size(); ++i)
00201     {
00202         images[i]->scaleImage(256, 256, 1);
00203         osg::notify(osg::NOTICE) << "Scaled image " << i << std::endl;
00204     }*/
00205 
00206     osg::Image* image3D = new osg::Image;
00207     image3D->allocateImage(images[0]->s(), images[0]->t(), images.size(),
00208                            images[0]->getPixelFormat(), images[0]->getDataType());
00209     
00210     for (unsigned int i = 0; i < images.size(); ++i)
00211     {
00212         image3D->copySubImage(0, 0, i, images[i].get());
00213     }
00214     image3D->setInternalTextureFormat(images[0]->getInternalTextureFormat());
00215     return image3D;
00216 }
00217 
00218 
00219 int usage( const std::string& msg )
00220 {
00221     OE_NOTICE
00222         << msg << std::endl
00223         << "USAGE: osgearth_ocean [--mask-layer <layername>] [--invert-mask] <earthfile>" << std::endl
00224         << "(note: <layername> defaults to \"ocean\")" << std::endl;
00225     return -1;
00226 }
00227 
00228 
00229 int main(int argc, char** argv)
00230 {
00231     osg::ArgumentParser arguments(&argc,argv);
00232 
00233     std::string maskLayerName = "ocean";
00234     while( arguments.read("--mask-layer", maskLayerName) );
00235 
00236     bool invertMask = arguments.isOption("--invert-mask");
00237 
00238     osg::Group* group = new osg::Group;
00239 
00240     osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);   
00241     if ( !loadedModel.valid() )
00242         return usage( "Failed to load an earth file." );
00243 
00244     osgEarth::Util::OceanSurfaceNode* ocean = new osgEarth::Util::OceanSurfaceNode();
00245 
00246     if ( !maskLayerName.empty() )
00247     {
00248         osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( loadedModel.get() );
00249         if ( mapNode )
00250         {
00251             osgEarth::MapFrame mapf( mapNode->getMap() );
00252             ocean->setOceanMaskImageLayer( mapf.getImageLayerByName( maskLayerName ) );
00253         }
00254     }
00255 
00256     ocean->setInvertMask( !invertMask );
00257 
00258     // install some water-surface images for an interesting shimmering effect:
00259     ImageList waterImages;
00260     waterImages.push_back( osgDB::readImageFile("../data/watersurface1.png") );
00261     waterImages.push_back( osgDB::readImageFile("../data/watersurface2.png") );
00262     waterImages.push_back( osgDB::readImageFile("../data/watersurface3.png") );
00263     waterImages.push_back( osgDB::readImageFile("../data/watersurface4.png") );
00264 
00265     osg::ref_ptr<osg::Image> waterImage = make3DImage(waterImages);    
00266     ocean->setOceanSurfaceImage( waterImage.get() );
00267 
00268     // Find the MapNode and add the ocean as a terrain decorator.
00269     osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( loadedModel.get() );
00270     mapNode->addTerrainDecorator( ocean );
00271 
00272     // assemble the rest of the scene graph and go
00273     osgViewer::Viewer viewer(arguments);
00274 
00275     group->addChild( loadedModel.get() );
00276     group->addChild( createMenu(&viewer) );
00277     viewer.setSceneData(group);
00278     
00279     viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() );
00280 
00281     viewer.addEventHandler(new MyEventHandler(ocean));
00282     viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
00283     viewer.addEventHandler(new osgViewer::StatsHandler);
00284 
00285     return viewer.run();
00286 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines