zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    LeetCode 链表题总结
    分布式系统 MIT 6.824 Lab 1: MapReduce 准备
    Consul 入门(二)
    Consul 入门
    IDEA批量修改变量快捷键
    Spring源码解析-JdbcTemplate
    SpringMVC源码解析-HTTP请求处理和分发
    SpringMVC源码解析-DispatcherServlet启动流程和初始化
    发现一个网站可以看英文版的harry potter小说,好东西分享一下哈
    TypeSrcript如何引入第三方库 如果加d.ts以及async await如何使用 demo,只有代码,文字后续补充
  • 原文地址:https://www.cnblogs.com/lizhengjin/p/1839876.html
Copyright © 2011-2022 走看看