void OceanSurfaceContainer::rebuild() { this->removeChildren( 0, this->getNumChildren() ); if ( _parentMapNode.valid() ) { const MapOptions& parentMapOptions = _parentMapNode->getMap()->getMapOptions(); const MapNodeOptions& parentMapNodeOptions = _parentMapNode->getMapNodeOptions(); // set up the map to "match" the parent map: MapOptions mo; mo.coordSysType() = parentMapOptions.coordSysType(); mo.profile() = _parentMapNode->getMap()->getProfile()->toProfileOptions(); // new data model for the ocean: Map* oceanMap = new Map( mo ); // ditto with the map node options: MapNodeOptions mno; if ( mno.enableLighting().isSet() ) mno.enableLighting() = *mno.enableLighting(); QuadTreeTerrainEngineOptions to; to.heightFieldSkirtRatio() = 0.0; // don't want to see skirts to.clusterCulling() = false; // want to see underwater to.enableBlending() = true; // gotsta blend with the main node mno.setTerrainOptions( to ); // make the ocean's map node: MapNode* oceanMapNode = new MapNode( oceanMap, mno ); // install a custom compositor. Must do this before adding any image layers. oceanMapNode->setCompositorTechnique( new OceanCompositor() ); // install an "elevation proxy" layer that reads elevation tiles from the // parent map and turns them into encoded images for our shader to use. ImageLayerOptions epo( "ocean-proxy" ); epo.cachePolicy() = CachePolicy::NO_CACHE; epo.maxLevel() = *_options.maxLOD(); oceanMap->addImageLayer( new ElevationProxyImageLayer(_parentMapNode->getMap(), epo) ); this->addChild( oceanMapNode ); // set up the options uniforms. osg::StateSet* ss = this->getOrCreateStateSet(); _seaLevel = new osg::Uniform(osg::Uniform::FLOAT, "ocean_seaLevel"); ss->addUniform( _seaLevel.get() ); _lowFeather = new osg::Uniform(osg::Uniform::FLOAT, "ocean_lowFeather"); ss->addUniform( _lowFeather.get() ); _highFeather = new osg::Uniform(osg::Uniform::FLOAT, "ocean_highFeather"); ss->addUniform( _highFeather.get() ); _baseColor = new osg::Uniform(osg::Uniform::FLOAT_VEC4, "ocean_baseColor"); ss->addUniform( _baseColor.get() ); // trick to prevent z-fighting.. ss->setAttributeAndModes( new osg::Depth(osg::Depth::LEQUAL, 0.0, 1.0, false) ); ss->setRenderBinDetails( 15, "RenderBin" ); // load up a surface texture ss->getOrCreateUniform( "ocean_has_tex1", osg::Uniform::BOOL )->set( false ); if ( _options.textureURI().isSet() ) { //TODO: enable cache support here: osg::Image* image = _options.textureURI()->getImage(); if ( image ) { osg::Texture2D* tex = new osg::Texture2D( image ); tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR ); tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); tex->setWrap ( osg::Texture::WRAP_S, osg::Texture::REPEAT ); tex->setWrap ( osg::Texture::WRAP_T, osg::Texture::REPEAT ); ss->setTextureAttributeAndModes( 1, tex, 1 ); ss->getOrCreateUniform( "ocean_tex1", osg::Uniform::SAMPLER_2D )->set( 1 ); ss->getOrCreateUniform( "ocean_has_tex1", osg::Uniform::BOOL )->set( true ); } } // remove backface culling so we can see underwater // (use OVERRIDE since the terrain engine sets back face culling.) ss->setAttributeAndModes( new osg::CullFace(), osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE ); apply( _options ); } }