osgEarth 2.1.1
|
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 <osgUtil/Optimizer> 00022 #include <osgDB/ReadFile> 00023 #include <osgViewer/Viewer> 00024 00025 #include <osg/Material> 00026 #include <osg/Geode> 00027 #include <osg/BlendFunc> 00028 #include <osg/Depth> 00029 #include <osg/Projection> 00030 #include <osg/AutoTransform> 00031 #include <osg/Geometry> 00032 #include <osg/Image> 00033 #include <osg/CullFace> 00034 00035 #include <osgTerrain/TerrainTile> 00036 #include <osgTerrain/GeometryTechnique> 00037 00038 #include <osgDB/WriteFile> 00039 00040 #include <osgText/Text> 00041 00042 #include <iostream> 00043 00044 using namespace osg; 00045 using namespace osgDB; 00046 using namespace osgTerrain; 00047 00048 osg::Image* makeRGBA(osg::Image* image) 00049 { 00050 osg::Image* result = new osg::Image; 00051 result->allocateImage(image->s(), image->t(), image->r(), GL_RGBA, GL_UNSIGNED_BYTE); 00052 00053 if (image->getPixelFormat() == GL_LUMINANCE) 00054 { 00055 for (int r = 0; r < image->t(); ++r) 00056 { 00057 for (int c = 0; c < image->s(); ++c) 00058 { 00059 unsigned char val = *image->data(c, r); 00060 result->data(c,r)[0] = val; 00061 result->data(c,r)[1] = val; 00062 result->data(c,r)[2] = val; 00063 result->data(c,r)[3] = val; 00064 } 00065 } 00066 } 00067 00068 return result; 00069 } 00070 00071 osg::Node* createClouds(double maxRange) 00072 { 00073 //Try to read from the WorldWind server 00074 osg::ref_ptr<osg::Image> image = osgDB::readImageFile("http://worldwind25.arc.nasa.gov/GlobalClouds/GlobalClouds.aspx?.jpg"); 00075 if (image.valid()) 00076 { 00077 OE_NOTICE << "Read clouds from WorldWind server" << std::endl; 00078 } 00079 else 00080 { 00081 //Just try to load clouds.jpg from the data directory. 00082 //Note: You must append the osgearth\data folder to your OSG_FILE_PATH 00083 //or just copy the clouds.jpg where current osg data is. 00084 image = osgDB::readImageFile("clouds.jpg"); 00085 } 00086 00087 if (!image.valid()) 00088 { 00089 OE_NOTICE << "Could not read clouds image " << std::endl; 00090 return NULL; 00091 } 00092 00093 //Convert the black and white data to RGBA 00094 image = makeRGBA(image.get()); 00095 double min_lon = -180.0; 00096 double min_lat = -90.0; 00097 double max_lon = 180.0; 00098 double max_lat = 90; 00099 00100 osgTerrain::TerrainTile* tile = new osgTerrain::TerrainTile(); 00101 00102 osgTerrain::Locator* locator = new osgTerrain::Locator(); 00103 locator->setCoordinateSystemType( osgTerrain::Locator::GEOCENTRIC ); 00104 00105 locator->setTransformAsExtents( 00106 osg::DegreesToRadians( min_lon ), 00107 osg::DegreesToRadians( min_lat ), 00108 osg::DegreesToRadians( max_lon ), 00109 osg::DegreesToRadians( max_lat )); 00110 00111 osg::HeightField *hf = new osg::HeightField(); 00112 hf->allocate(64,64); 00113 for(unsigned int i=0; i<hf->getHeightList().size(); i++ ) hf->getHeightList()[i] = 0.0; 00114 00115 hf->setOrigin( osg::Vec3d( min_lon, min_lat, 0.0 ) ); 00116 hf->setXInterval( (max_lon - min_lon)/(double)(hf->getNumColumns()-1) ); 00117 hf->setYInterval( (max_lat - min_lat)/(double)(hf->getNumRows()-1) ); 00118 hf->setBorderWidth( 0 ); 00119 00120 osgTerrain::HeightFieldLayer* hf_layer = new osgTerrain::HeightFieldLayer(); 00121 hf_layer->setLocator( locator ); 00122 hf_layer->setHeightField( hf ); 00123 00124 osgTerrain::ImageLayer* img_layer = new osgTerrain::ImageLayer( image.get() ); 00125 img_layer->setLocator( locator ); 00126 tile->setColorLayer( 0, img_layer ); 00127 00128 tile->setLocator( locator ); 00129 tile->setTerrainTechnique( new osgTerrain::GeometryTechnique() ); 00130 tile->setElevationLayer( hf_layer ); 00131 tile->setRequiresNormals( true ); 00132 00133 tile->getOrCreateStateSet()->setAttributeAndModes(new CullFace(CullFace::BACK), StateAttribute::ON); 00134 tile->getOrCreateStateSet()->setMode(GL_LIGHTING, StateAttribute::OFF); 00135 00136 double scale = 1.01; 00137 osg::MatrixTransform* mt = new osg::MatrixTransform; 00138 mt->setMatrix(osg::Matrixd::scale(scale, scale, scale)); 00139 mt->addChild(tile); 00140 00141 osg::LOD *lod = new LOD; 00142 lod->addChild(mt, maxRange, FLT_MAX); 00143 00144 return lod; 00145 } 00146 00147 int main(int argc, char** argv) 00148 { 00149 osg::ArgumentParser arguments(&argc,argv); 00150 00151 // construct the viewer. 00152 osgViewer::Viewer viewer(arguments); 00153 00154 osg::Group* group = new osg::Group; 00155 00156 osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments); 00157 if (loadedModel.valid()) 00158 { 00159 group->addChild(loadedModel.get()); 00160 } 00161 00162 group->addChild(createClouds(osg::WGS_84_RADIUS_EQUATOR * 2.0)); 00163 00164 // set the scene to render 00165 viewer.setSceneData(group); 00166 00167 // run the viewers frame loop 00168 return viewer.run(); 00169 }