glsl着色语言和osg的交互及模型矩阵的传递

void SceneView::updateUniforms()
{
    if (!_localStateSet)
    {
        _localStateSet = new osg::StateSet;
    }

    if (!_localStateSet) return;
   
    if ((_activeUniforms & FRAME_NUMBER_UNIFORM) && _frameStamp.valid())
    {
        osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_FrameNumber",osg::Uniform::INT);
        uniform->set(_frameStamp->getFrameNumber());       
    }
   
    if ((_activeUniforms & FRAME_TIME_UNIFORM) && _frameStamp.valid())
    {
        osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_FrameTime",osg::Uniform::FLOAT);
        uniform->set(static_cast<float>(_frameStamp->getReferenceTime()));
    }
   
    if ((_activeUniforms & DELTA_FRAME_TIME_UNIFORM) && _frameStamp.valid())
    {
        float delta_frame_time = (_previousFrameTime != 0.0) ? static_cast<float>(_frameStamp->getReferenceTime()-_previousFrameTime) : 0.0f;
        _previousFrameTime = _frameStamp->getReferenceTime();
       
        osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_DeltaFrameTime",osg::Uniform::FLOAT);
        uniform->set(delta_frame_time);
    }
   
    if ((_activeUniforms & SIMULATION_TIME_UNIFORM) && _frameStamp.valid())
    {
        osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_SimulationTime",osg::Uniform::FLOAT);
        uniform->set(static_cast<float>(_frameStamp->getSimulationTime()));
    }
   
    if ((_activeUniforms & DELTA_SIMULATION_TIME_UNIFORM) && _frameStamp.valid())
    {
        float delta_simulation_time = (_previousSimulationTime != 0.0) ? static_cast<float>(_frameStamp->getSimulationTime()-_previousSimulationTime) : 0.0f;
        _previousSimulationTime = _frameStamp->getSimulationTime();
       
        osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_DeltaSimulationTime",osg::Uniform::FLOAT);
        uniform->set(delta_simulation_time);
    }
   
    if (_activeUniforms & VIEW_MATRIX_UNIFORM)  //通过Uniform把漫游器矩阵传给着色器
    {
        osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_ViewMatrix",osg::Uniform::FLOAT_MAT4);
        uniform->set(getViewMatrix());
    }

    if (_activeUniforms & VIEW_MATRIX_INVERSE_UNIFORM)
    {
        osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_ViewMatrixInverse",osg::Uniform::FLOAT_MAT4);
        uniform->set(osg::Matrix::inverse(getViewMatrix()));
    }

}

 

//------------------

 

void CullVisitor::apply(Transform& node)//
{
    if (isCulled(node)) return;

    // push the culling mode.
    pushCurrentMask();

    // push the node's state.
    StateSet* node_state = node.getStateSet();
    if (node_state) pushStateSet(node_state);

    ref_ptr<RefMatrix> matrix = createOrReuseMatrix(*getModelViewMatrix());
    node.computeLocalToWorldMatrix(*matrix,this);//matrix转到世界坐标,模型视图矩阵和局部矩阵
    pushModelViewMatrix(matrix.get(), node.getReferenceFrame());
   
    handle_cull_callbacks_and_traverse(node);

    popModelViewMatrix();

    // pop the node's state off the render graph stack.   
    if (node_state) popStateSet();

    // pop the culling mode.
    popCurrentMask();
}

 

 

void CullVisitor::apply(Geode& node)
{
    if (isCulled(node)) return;

    // push the node's state.
    StateSet* node_state = node.getStateSet();
    if (node_state) pushStateSet(node_state);

    // traverse any call callbacks and traverse any children.
    handle_cull_callbacks_and_traverse(node);

    RefMatrix& matrix = *getModelViewMatrix();                               //得到当前的局部坐标矩阵和视图矩阵
    for(unsigned int i=0;i<node.getNumDrawables();++i)
    {
        Drawable* drawable = node.getDrawable(i);
        const BoundingBox &bb =drawable->getBound();

        if( drawable->getCullCallback() )
        {
            if( drawable->getCullCallback()->cull( this, drawable, &_renderInfo ) == true )
            continue;
        }
       
        //else
        {
            if (node.isCullingActive() && isCulled(bb)) continue;
        }


        if (_computeNearFar && bb.valid())
        {
            if (!updateCalculatedNearFar(matrix,*drawable,false)) continue;
        }

        // need to track how push/pops there are, so we can unravel the stack correctly.
        unsigned int numPopStateSetRequired = 0;

        // push the geoset's state on the geostate stack.   
        StateSet* stateset = drawable->getStateSet();
        if (stateset)
        {
            ++numPopStateSetRequired;
            pushStateSet(stateset);
        }

        CullingSet& cs = getCurrentCullingSet();
        if (!cs.getStateFrustumList().empty())
        {
            osg::CullingSet::StateFrustumList& sfl = cs.getStateFrustumList();
            for(osg::CullingSet::StateFrustumList::iterator itr = sfl.begin();
                itr != sfl.end();
                ++itr)
            {
                if (itr->second.contains(bb))
                {
                    ++numPopStateSetRequired;
                    pushStateSet(itr->first.get());
                }
            }
        }

        float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;
       
        if (osg::isNaN(depth))
        {
            osg::notify(osg::NOTICE)<<"CullVisitor::apply(Geode&) detected NaN,"<<std::endl
                                    <<"    depth="<<depth<<", center=("<<bb.center()<<"),"<<std::endl
                                    <<"    matrix="<<matrix<<std::endl;
        }
        else
        {       
            addDrawableAndDepth(drawable,&matrix,depth);//传进去矩阵
        }

        for(unsigned int i=0;i< numPopStateSetRequired; ++i)
        {
            popStateSet();
        }

    }

    // pop the node's state off the geostate stack.   
    if (node_state) popStateSet();

}

 

inline void CullVisitor::addDrawableAndDepth(osg::Drawable* drawable,osg::RefMatrix* matrix,float depth)
{
    if (_currentStateGraph->leaves_empty())
    {
        // this is first leaf to be added to StateGraph
        // and therefore should not already know to current render bin,
        // so need to add it.
        _currentRenderBin->addStateGraph(_currentStateGraph);
    }
    //_currentStateGraph->addLeaf(new RenderLeaf(drawable,matrix,depth));
    _currentStateGraph->addLeaf(createOrReuseRenderLeaf(drawable,_projectionStack.back().get(),matrix,depth));//生成渲染叶
}

 

 

inline RenderLeaf* CullVisitor::createOrReuseRenderLeaf(osg::Drawable* drawable,osg::RefMatrix* projection,osg::RefMatrix* matrix, float depth)
{
    // Skips any already reused renderleaf.
    while (_currentReuseRenderLeafIndex<_reuseRenderLeafList.size() &&
           _reuseRenderLeafList[_currentReuseRenderLeafIndex]->referenceCount()>1)
    {
        osg::notify(osg::NOTICE)<<"Warning:createOrReuseRenderLeaf() skipping multiply refrenced entry."<< std::endl;
        ++_currentReuseRenderLeafIndex;
    }

    // If still within list, element must be singularly referenced then return it to be reused.
    if (_currentReuseRenderLeafIndex<_reuseRenderLeafList.size())
    {
        RenderLeaf* renderleaf = _reuseRenderLeafList[_currentReuseRenderLeafIndex++].get();
        renderleaf->set(drawable,projection,matrix,depth);
        return renderleaf;
    }

    // Otherwise need to create new renderleaf.
    RenderLeaf* renderleaf = new RenderLeaf(drawable,projection,matrix,depth);//matrix传入到渲染叶
    _reuseRenderLeafList.push_back(renderleaf);
    ++_currentReuseRenderLeafIndex;
    return renderleaf;
}


}

 

 

void RenderLeaf::render(osg::RenderInfo& renderInfo,RenderLeaf* previous)
{
    osg::State& state = *renderInfo.getState();

    // don't draw this leaf if the abort rendering flag has been set.
    if (state.getAbortRendering())
    {
        //cout << "early abort"<<endl;
        return;
    }

    if (previous)
    {

        // apply matrices if required.
        state.applyProjectionMatrix(_projection.get());
        state.applyModelViewMatrix(_modelview.get());

        // apply state if required.
        StateGraph* prev_rg = previous->_parent;
        StateGraph* prev_rg_parent = prev_rg->_parent;
        StateGraph* rg = _parent;
        if (prev_rg_parent!=rg->_parent)
        {
            StateGraph::moveStateGraph(state,prev_rg_parent,rg->_parent);

            // send state changes and matrix changes to OpenGL.
            state.apply(rg->getStateSet());

        }
        else if (rg!=prev_rg)
        {

            // send state changes and matrix changes to OpenGL.
            state.apply(rg->getStateSet());

        }
       

        // draw the drawable
        _drawable->draw(renderInfo);
    }
    else
    {
        // apply matrices if required.
        state.applyProjectionMatrix(_projection.get());     //应用模型视图矩阵
        state.applyModelViewMatrix(_modelview.get());

        // apply state if required.
        StateGraph::moveStateGraph(state,NULL,_parent->_parent);

        state.apply(_parent->getStateSet());

        // draw the drawable
        _drawable->draw(renderInfo);
    }
   
    if (_dynamic)

 

 

    {
        state.decrementDynamicObjectCount();
    }
   
    // osg::notify(osg::NOTICE)<<"RenderLeaf "<<_drawable->getName()<<" "<<_depth<<std::endl;
}

 

 

 

 

你可能感兴趣的:(OS)