Esempio n. 1
0
void
TileNode::merge(const TerrainTileModel* model, const RenderBindings& bindings)
{
    bool newElevationData = false;

    const SamplerBinding& color = bindings[SamplerBinding::COLOR];
    if (color.isActive())
    {
        for(TerrainTileColorLayerModelVector::const_iterator i = model->colorLayers().begin();
            i != model->colorLayers().end();
            ++i)
        {
            TerrainTileImageLayerModel* model = dynamic_cast<TerrainTileImageLayerModel*>(i->get());
            if (model)
            {
                if (model->getTexture())
                {
                    RenderingPass* pass = _renderModel.getPass(model->getImageLayer()->getUID());
                    if (!pass)
                    {
                        pass = &_renderModel.addPass();
                        pass->setLayer(model->getLayer());

                        // 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 = model->getTexture();
                            pass->samplers()[SamplerBinding::COLOR_PARENT]._matrix.makeIdentity();
                        }
                    }
                    pass->samplers()[SamplerBinding::COLOR]._texture = model->getTexture();
                    pass->samplers()[SamplerBinding::COLOR]._matrix = *model->getMatrix();

                    // Handle an RTT image layer:
                    if (model->getImageLayer() && model->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*>(model->getTexture()->getUserData());
                        if (rttNode)
                        {
                            _context->getTileRasterizer()->push(rttNode->_node.get(), model->getTexture(), rttNode->_extent);
                        }
                    }
                }
            }

            else // non-image color layer (like splatting, e.g.)
            {
                TerrainTileColorLayerModel* model = i->get();
                if (model && model->getLayer())
                {
                    RenderingPass* pass = _renderModel.getPass(model->getLayer()->getUID());
                    if (!pass)
                    {
                        pass = &_renderModel.addPass();
                        pass->setLayer(model->getLayer());
                    }
                }
            }
        }
    }

    // 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());

        newElevationData = true;
    } 

    // 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()[i].get();
        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()[i].get();
    }

    if (_childrenReady)
    {
        getSubTile(0)->refreshInheritedData(this, bindings);
        getSubTile(1)->refreshInheritedData(this, bindings);
        getSubTile(2)->refreshInheritedData(this, bindings);
        getSubTile(3)->refreshInheritedData(this, bindings);
    }

    if (newElevationData)
    {
        _context->getEngine()->getTerrain()->notifyTileAdded(getKey(), this);
    }
}
Esempio n. 2
0
// invoke runs in the background pager thread.
void
LoadTileData::invoke()
{
    osg::ref_ptr<TileNode> tilenode;
    if ( _tilenode.lock(tilenode) )
    {
        // Assemble all the components necessary to display this tile
        _model = _context->getEngine()->createTileModel(
            _context->getMapFrame(),
            tilenode->getTileKey(),
            0L ); // progress

        // Prep the stateset for merging (and for GL pre-compile).
        if ( _model.valid() )
        {
            const RenderBindings& bindings = _context->getRenderBindings();

            osg::StateSet* stateSet = getStateSet();

            // Insert all the color layers into a new MPTexture state attribute,
            // which exists to facilitate GL pre-compilation.
            if ( _model->colorLayers().size() > 0 )
            {
                const SamplerBinding* colorBinding = SamplerBinding::findUsage(bindings, SamplerBinding::COLOR);
                if ( colorBinding )
                {
                    osg::ref_ptr<MPTexture> mptex = new MPTexture();

                    for(TerrainTileImageLayerModelVector::iterator i = _model->colorLayers().begin();
                        i != _model->colorLayers().end();
                        ++i)
                    {
                        TerrainTileImageLayerModel* layerModel = i->get();
                        if ( layerModel && layerModel->getTexture() )
                        {
                            mptex->setLayer( layerModel->getImageLayer(), layerModel->getTexture(), layerModel->getOrder() );
                        }
                    }

                    if ( !mptex->getPasses().empty() )
                    {
                        stateSet->setTextureAttribute(
                            colorBinding->unit(),
                            mptex );
                    }
                }
            }

            // Insert the elevation texture and an identity matrix:
            if ( _model->elevationModel().valid() && _model->elevationModel()->getTexture())
            {
                const SamplerBinding* binding = SamplerBinding::findUsage(bindings, SamplerBinding::ELEVATION);
                if ( binding )
                {                
                    stateSet->setTextureAttribute(
                        binding->unit(),
                        _model->elevationModel()->getTexture() );

                    stateSet->removeUniform(binding->matrixName());

                    stateSet->addUniform( _context->getOrCreateMatrixUniform(
                        binding->matrixName(),
                        osg::Matrixf::identity() ) );    
                }
            }
            
            // Insert the normal texture and an identity matrix:
            if ( _model->normalModel().valid() && _model->normalModel()->getTexture() )
            {
                const SamplerBinding* binding = SamplerBinding::findUsage(bindings, SamplerBinding::NORMAL);
                if ( binding )
                {
                    stateSet->setTextureAttribute(
                        binding->unit(),
                        _model->normalModel()->getTexture() );

                    stateSet->removeUniform(binding->matrixName());

                    stateSet->addUniform( _context->getOrCreateMatrixUniform(
                        binding->matrixName(),
                        osg::Matrixf::identity() ) );
                }
            }

            // Process any shared image layers, each of which should have its
            // own sampler binding point
            for(TerrainTileImageLayerModelVector::iterator i = _model->sharedLayers().begin();
                i != _model->sharedLayers().end();
                ++i)
            {
                TerrainTileImageLayerModel* layerModel = i->get();
                if ( layerModel->getTexture() )
                {
                    const SamplerBinding* binding = SamplerBinding::findUID(bindings, layerModel->getImageLayer()->getUID());
                    if ( binding )
                    {
                        stateSet->setTextureAttribute(
                            binding->unit(),
                            layerModel->getTexture() );

                        stateSet->removeUniform(binding->matrixName());

                        stateSet->addUniform( _context->getOrCreateMatrixUniform(
                            binding->matrixName(),
                            osg::Matrixf::identity() ) );
                    }
                }
            }
        }
    }
}