Example #1
0
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);
    }
}
Example #2
0
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;
}