void TerrainEngineNode::updateImageUniforms() { // don't bother if this is a hurting old card if ( !Registry::instance()->getCapabilities().supportsGLSL() ) return; // update the layer uniform arrays: osg::StateSet* stateSet = this->getOrCreateStateSet(); // get a copy of the image layer stack: MapFrame mapf( _map.get(), Map::IMAGE_LAYERS ); _imageLayerController->_layerVisibleUniform.detach(); _imageLayerController->_layerOpacityUniform.detach(); _imageLayerController->_layerRangeUniform.detach(); if ( mapf.imageLayers().size() > 0 ) { // the "enabled" uniform is fixed size. this is handy to account for layers that are in flux...i.e., their source // layer count has changed, but the shader has not yet caught up. In the future we might use this to disable // "ghost" layers that used to exist at a given index, but no longer do. _imageLayerController->_layerVisibleUniform.attach( "osgearth_ImageLayerVisible", osg::Uniform::BOOL, stateSet, mapf.imageLayers().size() ); _imageLayerController->_layerOpacityUniform.attach( "osgearth_ImageLayerOpacity", osg::Uniform::FLOAT, stateSet, mapf.imageLayers().size() ); _imageLayerController->_layerRangeUniform.attach ( "osgearth_ImageLayerRange", osg::Uniform::FLOAT, stateSet, 2 * mapf.imageLayers().size() ); for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i ) { ImageLayer* layer = i->get(); int index = (int)(i - mapf.imageLayers().begin()); _imageLayerController->_layerVisibleUniform.setElement( index, layer->getVisible() ); _imageLayerController->_layerOpacityUniform.setElement( index, layer->getOpacity() ); _imageLayerController->_layerRangeUniform.setElement( (2*index), layer->getMinVisibleRange() ); _imageLayerController->_layerRangeUniform.setElement( (2*index)+1, layer->getMaxVisibleRange() ); } // set the remainder of the layers to disabled for( int j=mapf.imageLayers().size(); j<_imageLayerController->_layerVisibleUniform.getNumElements(); ++j) { _imageLayerController->_layerVisibleUniform.setElement( j, false ); } } dirty(); }
void addLayerItem( Grid* grid, int layerIndex, int numLayers, Layer* layer, bool isActive ) { int gridCol = 0; int gridRow = grid->getNumRows(); VisibleLayer* visibleLayer = dynamic_cast<VisibleLayer*>(layer); // only show layers that derive from VisibleLayer if (!visibleLayer) return; ImageLayer* imageLayer = dynamic_cast<ImageLayer*>(layer); // don't show hidden coverage layers if (imageLayer && imageLayer->isCoverage() && !imageLayer->getVisible()) return; ElevationLayer* elevationLayer = dynamic_cast<ElevationLayer*>(layer); // a checkbox to toggle the layer's visibility: if (visibleLayer && layer->getEnabled() && !(imageLayer && imageLayer->isCoverage())) { CheckBoxControl* visibility = new CheckBoxControl( visibleLayer->getVisible() ); visibility->addEventHandler( new ToggleLayerVisibility(visibleLayer) ); grid->setControl( gridCol, gridRow, visibility ); } gridCol++; // the layer name LabelControl* name = new LabelControl( layer->getName() ); if (!layer->getEnabled()) name->setForeColor(osg::Vec4f(1,1,1,0.35)); grid->setControl( gridCol, gridRow, name ); gridCol++; // layer type std::string typeName = typeid(*layer).name(); typeName = typeName.substr(typeName.find_last_of(":")+1); LabelControl* typeLabel = new LabelControl(typeName, osg::Vec4(.5,.7,.5,1)); grid->setControl( gridCol, gridRow, typeLabel ); gridCol++; // status indicator LabelControl* statusLabel = layer->getStatus().isError() ? new LabelControl("[error]", osg::Vec4(1,0,0,1)) : !layer->getEnabled()? new LabelControl("[disabled]", osg::Vec4(1,1,1,0.35)) : new LabelControl("[ok]", osg::Vec4(0,1,0,1)) ; grid->setControl( gridCol, gridRow, statusLabel ); gridCol++; if (visibleLayer && !elevationLayer && visibleLayer->getEnabled()) { // an opacity slider HSliderControl* opacity = new HSliderControl( 0.0f, 1.0f, visibleLayer->getOpacity() ); opacity->setWidth( 125 ); opacity->setHeight( 12 ); opacity->addEventHandler( new LayerOpacityHandler(visibleLayer) ); grid->setControl( gridCol, gridRow, opacity ); } gridCol++; // zoom button if (layer->getExtent().isValid()) { LabelControl* zoomButton = new LabelControl("GO", 14); zoomButton->setBackColor( .4,.4,.4,1 ); zoomButton->setActiveColor( .8,0,0,1 ); zoomButton->addEventHandler( new ZoomLayerHandler(layer) ); grid->setControl( gridCol, gridRow, zoomButton ); } gridCol++; // move buttons if ( layerIndex < numLayers-1 && isActive ) { LabelControl* upButton = new LabelControl( "UP", 14 ); upButton->setBackColor( .4,.4,.4,1 ); upButton->setActiveColor( .8,0,0,1 ); upButton->addEventHandler( new MoveLayerHandler( layer, layerIndex+1 ) ); grid->setControl( gridCol, gridRow, upButton ); } gridCol++; if ( layerIndex > 0 && isActive) { LabelControl* upButton = new LabelControl( "DOWN", 14 ); upButton->setBackColor( .4,.4,.4,1 ); upButton->setActiveColor( .8,0,0,1 ); upButton->addEventHandler( new MoveLayerHandler( layer, layerIndex-1 ) ); grid->setControl( gridCol, gridRow, upButton ); } gridCol++; // add/remove button: LabelControl* addRemove = new LabelControl( isActive? "REMOVE" : "ADD", 14 ); addRemove->setHorizAlign( Control::ALIGN_CENTER ); addRemove->setBackColor( .4,.4,.4,1 ); addRemove->setActiveColor( .8,0,0,1 ); addRemove->addEventHandler( new RemoveLayerHandler(layer) ); grid->setControl( gridCol, gridRow, addRemove ); gridCol++; // enable/disable button LabelControl* enableDisable = new LabelControl(layer->getEnabled() ? "DISABLE" : "ENABLE", 14); enableDisable->setHorizAlign( Control::ALIGN_CENTER ); enableDisable->setBackColor( .4,.4,.4,1 ); enableDisable->setActiveColor( .8,0,0,1 ); enableDisable->addEventHandler( new EnableDisableHandler(layer) ); grid->setControl( gridCol, gridRow, enableDisable ); gridCol++; if (layer->getStatus().isError()) { grid->setControl(gridCol, gridRow, new LabelControl(layer->getStatus().message(), osg::Vec4(1,.2,.2,1))); } }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); // Which filter? bool useHSL = arguments.read("--hsl"); bool useRGB = arguments.read("--rgb"); bool useCMYK = arguments.read("--cmyk"); bool useBC = arguments.read("--bc"); bool useGamma = arguments.read("--gamma"); bool useChromaKey = arguments.read("--chromakey"); if ( !useHSL && !useRGB && !useCMYK && !useBC && !useGamma && !useChromaKey ) { return usage( "Please select one of the filter options!" ); } osgViewer::Viewer viewer(arguments); viewer.setCameraManipulator( new EarthManipulator() ); // load an earth file osg::Node* node = MapNodeHelper().load(arguments, &viewer); if ( !node ) return usage( "Unable to load map from earth file!" ); viewer.setSceneData( node ); //Create the control panel Container* box = createControlPanel(&viewer); osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( node ); if ( node ) { if (mapNode->getMap()->getNumImageLayers() == 0) { return usage("Please provide a map with at least one image layer."); } // attach color filter to each layer. unsigned numLayers = mapNode->getMap()->getNumImageLayers(); for( unsigned i=0; i<numLayers; ++i ) { ImageLayer* layer = mapNode->getMap()->getImageLayerAt( i ); if ( layer->getEnabled() && layer->getVisible() ) { if ( useHSL ) { HSLColorFilter* filter = new HSLColorFilter(); layer->addColorFilter( filter ); HSL::addControls( filter, box, i ); } else if ( useRGB ) { RGBColorFilter* filter = new RGBColorFilter(); layer->addColorFilter( filter ); RGB::addControls( filter, box, i ); } else if ( useCMYK ) { CMYKColorFilter* filter = new CMYKColorFilter(); layer->addColorFilter( filter ); CMYK::addControls( filter, box, i ); } else if ( useBC ) { BrightnessContrastColorFilter* filter = new BrightnessContrastColorFilter(); layer->addColorFilter( filter ); BC::addControls( filter, box, i ); } else if ( useGamma ) { GammaColorFilter* filter = new GammaColorFilter(); layer->addColorFilter( filter ); GAMMA::addControls( filter, box, i ); } else if ( useChromaKey ) { ChromaKeyColorFilter* filter = new ChromaKeyColorFilter(); layer->addColorFilter( filter ); CHROMAKEY::addControls( filter, box , i ); } } } } return viewer.run(); }
/** Packages image and elevation layers as a TMS. */ int TMSExporter::exportTMS(MapNode* mapNode, const std::string& path, std::vector< osgEarth::Bounds >& bounds, const std::string& outEarth, bool overwrite, const std::string& extension) { if ( !mapNode ) { _errorMessage = "Invalid MapNode"; if (_progress.valid()) _progress->onCompleted(); return 0; } // folder to which to write the TMS archive. std::string rootFolder = path; osg::ref_ptr<osgDB::Options> options = new osgDB::Options(_dbOptions); // create a folder for the output osgDB::makeDirectory(rootFolder); if ( !osgDB::fileExists(rootFolder) ) { _errorMessage = "Failed to create root output folder"; if (_progress.valid()) _progress->onCompleted(); return 0; } Map* map = mapNode->getMap(); // new map for an output earth file if necessary. osg::ref_ptr<Map> outMap = 0L; if ( !outEarth.empty() ) { // copy the options from the source map first outMap = new Map(map->getInitialMapOptions()); } // establish the output path of the earth file, if applicable: std::string outEarthName = osgDB::getSimpleFileName(outEarth); if (outEarthName.length() > 0 && osgEarth::toLower(osgDB::getFileExtension(outEarthName)) != "earth") outEarthName += ".earth"; std::string outEarthFile = osgDB::concatPaths(rootFolder, outEarthName); // semaphore and tasks collection for multithreading osgEarth::Threading::MultiEvent semaphore; osgEarth::TaskRequestVector tasks; int taskCount = 0; // package any image layers that are enabled and visible ImageLayerVector imageLayers; map->getImageLayers( imageLayers ); unsigned imageCount = 0; for( ImageLayerVector::iterator i = imageLayers.begin(); i != imageLayers.end(); ++i, ++imageCount ) { ImageLayer* layer = i->get(); if ( layer->getEnabled() && layer->getVisible() ) { std::string layerFolder = toLegalFileName( layer->getName() ); if ( layerFolder.empty() ) layerFolder = Stringify() << "image_layer_" << imageCount; ParallelTask<PackageLayer>* task = new ParallelTask<PackageLayer>( &semaphore ); task->init(map, layer, options, rootFolder, layerFolder, true, overwrite, _keepEmpties, _maxLevel, extension, bounds); task->setProgressCallback(new PackageLayerProgressCallback(this)); tasks.push_back(task); taskCount++; } } // package any elevation layers that are enabled and visible ElevationLayerVector elevationLayers; map->getElevationLayers( elevationLayers ); int elevCount = 0; for( ElevationLayerVector::iterator i = elevationLayers.begin(); i != elevationLayers.end(); ++i, ++elevCount ) { ElevationLayer* layer = i->get(); if ( layer->getEnabled() && layer->getVisible() ) { std::string layerFolder = toLegalFileName( layer->getName() ); if ( layerFolder.empty() ) layerFolder = Stringify() << "elevation_layer_" << elevCount; ParallelTask<PackageLayer>* task = new ParallelTask<PackageLayer>( &semaphore ); task->init(map, layer, options, rootFolder, layerFolder, true, overwrite, _keepEmpties, _maxLevel, extension, bounds); task->setProgressCallback(new PackageLayerProgressCallback(this)); tasks.push_back(task); taskCount++; } } // Run all the tasks in parallel _totalTasks = taskCount; _completedTasks = 0; semaphore.reset( _totalTasks ); for( TaskRequestVector::iterator i = tasks.begin(); i != tasks.end(); ++i ) _taskService->add( i->get() ); // Wait for them to complete semaphore.wait(); // Add successfully packaged layers to the new map object and // write out the .earth file (if requested) if (outMap.valid()) { for( TaskRequestVector::iterator i = tasks.begin(); i != tasks.end(); ++i ) { PackageLayer* p = dynamic_cast<PackageLayer*>(i->get()); if (p) { if (p->_packageResult.ok) { TMSOptions tms; tms.url() = URI(osgDB::concatPaths(p->_layerFolder, "tms.xml"), outEarthFile ); if (p->_imageLayer.valid()) { ImageLayerOptions layerOptions( p->_imageLayer->getName(), tms ); layerOptions.mergeConfig( p->_imageLayer->getInitialOptions().getConfig(true) ); layerOptions.cachePolicy() = CachePolicy::NO_CACHE; outMap->addImageLayer( new ImageLayer(layerOptions) ); } else { ElevationLayerOptions layerOptions( p->_elevationLayer->getName(), tms ); layerOptions.mergeConfig( p->_elevationLayer->getInitialOptions().getConfig(true) ); layerOptions.cachePolicy() = CachePolicy::NO_CACHE; outMap->addElevationLayer( new ElevationLayer(layerOptions) ); } } else { OE_WARN << LC << p->_packageResult.message << std::endl; } } } } if ( outMap.valid() ) { MapNodeOptions outNodeOptions = mapNode->getMapNodeOptions(); osg::ref_ptr<MapNode> outMapNode = new MapNode(outMap.get(), outNodeOptions); if ( !osgDB::writeNodeFile(*outMapNode.get(), outEarthFile) ) { OE_WARN << LC << "Error writing earth file to \"" << outEarthFile << "\"" << std::endl; } else { OE_NOTICE << LC << "Wrote earth file to \"" << outEarthFile << "\"" << std::endl; } } // Mark the progress callback as completed if (_progress.valid()) _progress->onCompleted(); return elevCount + imageCount; }