void TileNode::merge(const TerrainTileModel* model, const RenderBindings& bindings) { // Add color passes: const SamplerBinding& color = bindings[SamplerBinding::COLOR]; if (color.isActive()) { for (TerrainTileImageLayerModelVector::const_iterator i = model->colorLayers().begin(); i != model->colorLayers().end(); ++i) { TerrainTileImageLayerModel* layer = i->get(); if (layer && layer->getTexture()) { RenderingPass* pass = _renderModel.getPass(layer->getImageLayer()->getUID()); if (!pass) { pass = &_renderModel.addPass(); pass->_layer = layer->getImageLayer(); pass->_imageLayer = layer->getImageLayer(); pass->_sourceUID = layer->getImageLayer()->getUID(); // This is a new pass that just showed up at this LOD // Since it just arrived at this LOD, make the parent the same as the color. if (bindings[SamplerBinding::COLOR_PARENT].isActive()) { pass->_samplers[SamplerBinding::COLOR_PARENT]._texture = layer->getTexture(); pass->_samplers[SamplerBinding::COLOR_PARENT]._matrix.makeIdentity(); } } pass->_samplers[SamplerBinding::COLOR]._texture = layer->getTexture(); pass->_samplers[SamplerBinding::COLOR]._matrix.makeIdentity(); // Handle an RTT image layer: if (layer->getImageLayer() && layer->getImageLayer()->createTextureSupported()) { // Check the texture's userdata for a Node. If there is one there, // render it to the texture using the Tile Rasterizer service. // TODO: consider hanging on to this texture and not applying it to // the live tile until the RTT is complete. (Prevents unsightly flashing) GeoNode* rttNode = dynamic_cast<GeoNode*>(layer->getTexture()->getUserData()); if (rttNode) { _context->getTileRasterizer()->push(rttNode->_node.get(), layer->getTexture(), rttNode->_extent); } } } } } // Elevation: const SamplerBinding& elevation = bindings[SamplerBinding::ELEVATION]; if (elevation.isActive() && model->elevationModel().valid() && model->elevationModel()->getTexture()) { osg::Texture* tex = model->elevationModel()->getTexture(); // always keep the elevation image around because we use it for bounding box computation: tex->setUnRefImageDataAfterApply(false); _renderModel._sharedSamplers[SamplerBinding::ELEVATION]._texture = tex; _renderModel._sharedSamplers[SamplerBinding::ELEVATION]._matrix.makeIdentity(); setElevationRaster(tex->getImage(0), osg::Matrixf::identity()); } // Normals: const SamplerBinding& normals = bindings[SamplerBinding::NORMAL]; if (normals.isActive() && model->normalModel().valid() && model->normalModel()->getTexture()) { osg::Texture* tex = model->normalModel()->getTexture(); // keep the normal map around because we might update it later in "ping" tex->setUnRefImageDataAfterApply(false); _renderModel._sharedSamplers[SamplerBinding::NORMAL]._texture = tex; _renderModel._sharedSamplers[SamplerBinding::NORMAL]._matrix.makeIdentity(); updateNormalMap(); } // Other Shared Layers: for (unsigned i = 0; i < model->sharedLayers().size(); ++i) { TerrainTileImageLayerModel* layerModel = model->sharedLayers().at(i); if (layerModel->getTexture()) { // locate the shared binding corresponding to this layer: UID uid = layerModel->getImageLayer()->getUID(); unsigned bindingIndex = INT_MAX; for(unsigned i=SamplerBinding::SHARED; i<bindings.size() && bindingIndex==INT_MAX; ++i) { if (bindings[i].isActive() && bindings[i].sourceUID().isSetTo(uid)) { bindingIndex = i; } } if (bindingIndex < INT_MAX) { osg::Texture* tex = layerModel->getTexture(); _renderModel._sharedSamplers[bindingIndex]._texture = tex; _renderModel._sharedSamplers[bindingIndex]._matrix.makeIdentity(); } } } // Patch Layers for (unsigned i = 0; i < model->patchLayers().size(); ++i) { TerrainTilePatchLayerModel* layerModel = model->patchLayers().at(i); } if (_childrenReady) { getSubTile(0)->refreshInheritedData(this, bindings); getSubTile(1)->refreshInheritedData(this, bindings); getSubTile(2)->refreshInheritedData(this, bindings); getSubTile(3)->refreshInheritedData(this, bindings); } }
TileNode* TileGroupFactory::createTileNode(TerrainTileModel* model, ProgressCallback* progress) { TileNode* tileNode = new TileNode(model); for(TerrainTileImageLayerModelVector::const_iterator i = model->colorLayers().begin(); i != model->colorLayers().end(); ++i) { const TerrainTileLayerModel* layer = i->get(); if ( layer->getTexture() ) { osg::StateSet* stateSet = tileNode->getOrCreateStateSet(); stateSet->setTextureAttribute( _renderBindings.color().unit(), layer->getTexture() ); // (note: sampler uniform is set at the top level by the engine) } if ( layer->getMatrix() ) { osg::StateSet* stateSet = tileNode->getOrCreateStateSet(); stateSet->addUniform( new osg::Uniform( _renderBindings.color().matrixName().c_str(), *(layer->getMatrix())) ); } } if ( model->elevationModel() ) { const TerrainTileElevationModel* em = model->elevationModel(); if ( em->getTexture() ) { osg::StateSet* stateSet = tileNode->getOrCreateStateSet(); stateSet->setTextureAttribute( _renderBindings.elevation().unit(), em->getTexture() ); osg::Matrixf elevMatrix; if ( em->getMatrix() ) elevMatrix = *(em->getMatrix()); stateSet->addUniform( new osg::Uniform( _renderBindings.elevation().matrixName().c_str(), elevMatrix )); // (note: sampler uniform is set at the top level by the engine) } } for(TerrainTileImageLayerModelVector::const_iterator i = model->sharedLayers().begin(); i != model->sharedLayers().end(); ++i) { const TerrainTileImageLayerModel* layerModel = i->get(); const ImageLayer* imageLayer = layerModel->getImageLayer(); if ( imageLayer ) { if ( layerModel->getTexture() ) { osg::StateSet* stateSet = tileNode->getOrCreateStateSet(); stateSet->setTextureAttribute( imageLayer->shareImageUnit().get(), layerModel->getTexture() ); //TODO: don't really need this if we set it up in the Engine // once at the top level when adding the layer. stateSet->addUniform( new osg::Uniform( imageLayer->shareSamplerName()->c_str(), imageLayer->shareImageUnit().get() )); } if ( layerModel->getMatrix() ) { osg::StateSet* stateSet = tileNode->getOrCreateStateSet(); stateSet->addUniform( new osg::Uniform( imageLayer->shareMatrixName()->c_str(), *(layerModel->getMatrix())) ); } } } return tileNode; }