コード例 #1
0
void
RexTerrainEngineNode::traverse(osg::NodeVisitor& nv)
{
    if ( nv.getVisitorType() == nv.CULL_VISITOR )
    {
        // Inform the registry of the current frame so that Tiles have access
        // to the information.
        if ( _liveTiles.valid() && nv.getFrameStamp() )
        {
            _liveTiles->setTraversalFrame( nv.getFrameStamp()->getFrameNumber() );
        }
    }

#if 0
    static int c = 0;
    if ( ++c % 60 == 0 )
    {
        OE_NOTICE << LC << "Live = " << _liveTiles->size() << ", Dead = " << _deadTiles->size() << std::endl;
        _liveTiles->run( CheckForOrphans() );
    }
#endif
    
    if ( nv.getVisitorType() == nv.CULL_VISITOR && _loader.valid() ) // ensures that postInitialize has run
    {
        osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv);

        this->getEngineContext()->startCull( cv );
        
        TerrainCuller culler;
        culler.setFrameStamp(new osg::FrameStamp(*nv.getFrameStamp()));
        culler.setDatabaseRequestHandler(nv.getDatabaseRequestHandler());
        culler.pushReferenceViewPoint(cv->getReferenceViewPoint());
        culler.pushViewport(cv->getViewport());
        culler.pushProjectionMatrix(cv->getProjectionMatrix());
        culler.pushModelViewMatrix(cv->getModelViewMatrix(), cv->getCurrentCamera()->getReferenceFrame());
        culler._camera = cv->getCurrentCamera();
        culler._context = this->getEngineContext();
        culler.setup(*_update_mapf, this->getEngineContext()->getRenderBindings(), getSurfaceStateSet());

        // Assemble the terrain drawable:
        _terrain->accept(culler);

        // If we're using geometry pooling, optimize the drawable for shared state:
        if (getEngineContext()->getGeometryPool()->isEnabled())
        {
            culler._terrain.sortDrawCommands();
        }

        // The common stateset for the terrain:
        cv->pushStateSet(_terrain->getOrCreateStateSet());

        // Push all the layers to draw on to the cull visitor,
        // keeping track of render order.
        LayerDrawable* lastLayer = 0L;
        unsigned order = 0;
        bool surfaceStateSetPushed = false;

//        OE_INFO << "CULL:\n";

        for(LayerDrawableList::iterator i = culler._terrain.layers().begin();
            i != culler._terrain.layers().end();
            ++i)
        {
            if (!i->get()->_tiles.empty())
            {
                lastLayer = i->get();
                lastLayer->_order = -1;

                // if this is a RENDERTYPE_TILE, we need to activate the default surface state set.
                if (lastLayer->_layer && lastLayer->_layer->getRenderType() == Layer::RENDERTYPE_TILE)
                {
                    lastLayer->_order = order++;

                    if (!surfaceStateSetPushed)
                        cv->pushStateSet(getSurfaceStateSet());
                    surfaceStateSetPushed = true;
                }
                else if (surfaceStateSetPushed)
                {
                    cv->popStateSet();
                    surfaceStateSetPushed = false;
                }                    

//                OE_INFO << "   Apply: " << (lastLayer->_layer ? lastLayer->_layer->getName() : "-1") << std::endl;

                cv->apply(*lastLayer);
            }
        }

        // The last layer to render must clear up the OSG state,
        // otherwise it will be corrupt and can lead to crashing.
        if (lastLayer)
        {
            lastLayer->_clearOsgState = true;
        }
                
        if (surfaceStateSetPushed)
        {
            cv->popStateSet();
            surfaceStateSetPushed = false;
        }

        // pop the common terrain state set
        cv->popStateSet();

        this->getEngineContext()->endCull( cv );

        // traverse all the other children (geometry pool, loader/unloader, etc.)
        for (unsigned i = 0; i<getNumChildren(); ++i)
        {
            if (getChild(i) != _terrain.get())
                getChild(i)->accept(nv);
        }
    }

    //else
    {
        TerrainEngineNode::traverse( nv );
    }
}
コード例 #2
0
void
RexTerrainEngineNode::traverse(osg::NodeVisitor& nv)
{
    if (nv.getVisitorType() == nv.UPDATE_VISITOR)
    {
        if (_renderModelUpdateRequired)
        {
            UpdateRenderModels visitor(_mapFrame);
            _terrain->accept(visitor);
            _renderModelUpdateRequired = false;
        }
        TerrainEngineNode::traverse( nv );
    }
    
    else if ( nv.getVisitorType() == nv.CULL_VISITOR )
    {
        // Inform the registry of the current frame so that Tiles have access
        // to the information.
        if ( _liveTiles.valid() && nv.getFrameStamp() )
        {
            _liveTiles->setTraversalFrame( nv.getFrameStamp()->getFrameNumber() );
        }

        osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv);

        getEngineContext()->startCull( cv );
        
        TerrainCuller culler;
        culler.setFrameStamp(new osg::FrameStamp(*nv.getFrameStamp()));
        culler.setDatabaseRequestHandler(nv.getDatabaseRequestHandler());
        culler.pushReferenceViewPoint(cv->getReferenceViewPoint());
        culler.pushViewport(cv->getViewport());
        culler.pushProjectionMatrix(cv->getProjectionMatrix());
        culler.pushModelViewMatrix(cv->getModelViewMatrix(), cv->getCurrentCamera()->getReferenceFrame());
        culler._camera = cv->getCurrentCamera();
        culler._context = this->getEngineContext();

        // Prepare the culler with the set of renderable layers:
        culler.setup(_mapFrame, this->getEngineContext()->getRenderBindings());

        // Assemble the terrain drawable:
        _terrain->accept(culler);

        // If we're using geometry pooling, optimize the drawable for shared state:
        if (getEngineContext()->getGeometryPool()->isEnabled())
        {
            culler._terrain.sortDrawCommands();
        }

        // The common stateset for the terrain:
        cv->pushStateSet(_terrain->getOrCreateStateSet());

        // Push all the layers to draw on to the cull visitor,
        // keeping track of render order.
        LayerDrawable* lastLayer = 0L;
        unsigned order = 0;
        bool surfaceStateSetPushed = false;

        //OE_INFO << "CULL\n";

        for(LayerDrawableList::iterator i = culler._terrain.layers().begin();
            i != culler._terrain.layers().end();
            ++i)
        {
            if (!i->get()->_tiles.empty())
            {
                lastLayer = i->get();
                lastLayer->_order = -1;

                // if this is a RENDERTYPE_TILE, we need to activate the default surface state set.
                if (lastLayer->_renderType == Layer::RENDERTYPE_TILE)
                {
                    lastLayer->_order = order++;

                    if (!surfaceStateSetPushed)
                        cv->pushStateSet(getSurfaceStateSet());
                    surfaceStateSetPushed = true;
                }
                else if (surfaceStateSetPushed)
                {
                    cv->popStateSet();
                    surfaceStateSetPushed = false;
                }                    

                //OE_INFO << "   Apply: " << (lastLayer->_layer ? lastLayer->_layer->getName() : "-1") << "; tiles=" << lastLayer->_tiles.size() << std::endl;

                cv->apply(*lastLayer);
            }
        }

        // The last layer to render must clear up the OSG state,
        // otherwise it will be corrupt and can lead to crashing.
        if (lastLayer)
        {
            lastLayer->_clearOsgState = true;
        }
                
        if (surfaceStateSetPushed)
        {
            cv->popStateSet();
            surfaceStateSetPushed = false;
        }

        // pop the common terrain state set
        cv->popStateSet();

        this->getEngineContext()->endCull( cv );

        // If the culler found any orphaned data, we need to update the render model
        // during the next update cycle.
        if (culler._orphanedPassesDetected > 0u)
        {
            _renderModelUpdateRequired = true;
            OE_INFO << LC << "Detected " << culler._orphanedPassesDetected << " orphaned rendering passes\n";
        }

        // we don't call this b/c we don't want _terrain
        //TerrainEngineNode::traverse(nv);

        // traverse all the other children (geometry pool, loader/unloader, etc.)
        _geometryPool->accept(nv);
        _loader->accept(nv);
        _unloader->accept(nv);
        _releaser->accept(nv);
        _rasterizer->accept(nv);
    }

    else
    {
        TerrainEngineNode::traverse( nv );
    }
}