查看: 1272|回复: 5

分析渲染过程中的一个函数有疑问,讨论一下

[复制链接]

该用户从未签到

发表于 2010-9-29 20:39:15 | 显示全部楼层 |阅读模式
void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
{
    osg::State& state = *renderInfo.getState();
    // osg::notify(osg::NOTICE)<<"begin RenderBin::drawImplementation "<<className()<<" sortMode "<<getSortMode()<<std::endl;

    unsigned int numToPop = (previous ? StateGraph::numToPop(previous->_parent) : 0);
    if (numToPop>1) --numToPop;
    unsigned int insertStateSetPosition = state.getStateSetStackSize() - numToPop;
    if (_stateset.valid())
    {
        state.insertStateSet(insertStateSetPosition, _stateset.get());
    }

    // draw first set of draw bins.
    RenderBinList::iterator rbitr;
    for(rbitr = _bins.begin();
        rbitr!=_bins.end() && rbitr->first<0;
        ++rbitr)
    {
        rbitr->second->draw(renderInfo,previous);
    }
    // draw fine grained ordering.
    for(RenderLeafList::iterator rlitr= _renderLeafList.begin();
        rlitr!= _renderLeafList.end();
        ++rlitr)
    {
        RenderLeaf* rl = *rlitr;
        rl->render(renderInfo,previous);
        previous = rl;
    }

    bool draw_forward = true; //(_sortMode!=SORT_BY_STATE) || (state.getFrameStamp()->getFrameNumber() % 2)==0;
    // draw coarse grained ordering.
    if (draw_forward)
    {
        for(StateGraphList::iterator oitr=_stateGraphList.begin();
            oitr!=_stateGraphList.end();
            ++oitr)
        {
            for(StateGraph:eafList::iterator dw_itr = (*oitr)->_leaves.begin();
                dw_itr != (*oitr)->_leaves.end();
                ++dw_itr)
            {
                RenderLeaf* rl = dw_itr->get();
                rl->render(renderInfo,previous);
                previous = rl;
            }
        }
    }
    else
    {
        for(StateGraphList::reverse_iterator oitr=_stateGraphList.rbegin();
            oitr!=_stateGraphList.rend();
            ++oitr)
        {
            for(StateGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
                dw_itr != (*oitr)->_leaves.end();
                ++dw_itr)
            {
                RenderLeaf* rl = dw_itr->get();
                rl->render(renderInfo,previous);
                previous = rl;
            }
        }
    }
    // draw post bins.
    for(;
        rbitr!=_bins.end();
        ++rbitr)
    {
        rbitr->second->draw(renderInfo,previous);
    }
    if (_stateset.valid())
    {
        state.removeStateSet(insertStateSetPosition);
        // state.apply();
    }

    // osg::notify(osg::NOTICE)<<"end RenderBin::drawImplementation "<<className()<<std::endl;
}

该用户从未签到

 楼主| 发表于 2010-9-29 20:57:03 | 显示全部楼层
bool draw_forward = true; //(_sortMode!=SORT_BY_STATE) || (state.getFrameStamp()->getFrameNumber() % 2)==0;
    // draw coarse grained ordering.
    if (draw_forward)
    {
        for(StateGraphList::iterator oitr=_stateGraphList.begin();
            oitr!=_stateGraphList.end();
            ++oitr)
        {
            for(StateGraph:eafList::iterator dw_itr = (*oitr)->_leaves.begin();
                dw_itr != (*oitr)->_leaves.end();
                ++dw_itr)
            {
                RenderLeaf* rl = dw_itr->get();
                rl->render(renderInfo,previous);
                previous = rl;
            }
        }
    }
    else
    {
        for(StateGraphList::reverse_iterator oitr=_stateGraphList.rbegin();
            oitr!=_stateGraphList.rend();
            ++oitr)
        {
            for(StateGraph:eafList::iterator dw_itr = (*oitr)->_leaves.begin();
                dw_itr != (*oitr)->_leaves.end();
                ++dw_itr)
            {
                RenderLeaf* rl = dw_itr->get();
                rl->render(renderInfo,previous);
                previous = rl;
            }
        }
    }

其中有两个问题
1:bool draw_forward = true;是个局部变量,而且不发生变话,这样的话,这句代码好像没用?
2:_stateGraphList在sort()函数里面clear()了,也就是_stateGraphList永远为空,这样的话,
上面的代码即不是永远不可能执行?而且加断点也是从来不进的

各位讨论一下

该用户从未签到

 楼主| 发表于 2010-9-29 21:05:28 | 显示全部楼层
void RenderBin::copyLeavesFromStateGraphListToRenderLeafList()
{
    _renderLeafList.clear();

    int totalsize=0;
    StateGraphList::iterator itr;
    for(itr=_stateGraphList.begin();
        itr!=_stateGraphList.end();
        ++itr)
    {
        totalsize += (*itr)->_leaves.size();
    }

    _renderLeafList.reserve(totalsize);
   
    bool detectedNaN = false;
        
    // first copy all the leaves from the render graphs into the leaf list.
    for(itr=_stateGraphList.begin();
        itr!=_stateGraphList.end();
        ++itr)
    {
        for(StateGraph:eafList::iterator dw_itr = (*itr)->_leaves.begin();
            dw_itr != (*itr)->_leaves.end();
            ++dw_itr)
        {
            if (!osg::isNaN((*dw_itr)->_depth))
            {
                _renderLeafList.push_back(dw_itr->get());
            }
            else
            {
                detectedNaN = true;
            }
        }
    }
   
    if (detectedNaN) osg::notify(osg::NOTICE)<<"Warning: RenderBin::copyLeavesFromStateGraphListToRenderLeafList() detected NaN depth values, database may be corrupted."<<std::endl;
   
    // empty the render graph list to prevent it being drawn along side the render leaf list (see drawImplementation.)
    _stateGraphList.clear();
}

最后一行_stateGraphList.clear();
_stateGraphList.被clear()

该用户从未签到

发表于 2010-9-30 08:52:59 | 显示全部楼层
首先,copyLeavesFromStateGraphListToRenderLeafList()不一定总是被执行的,例如默认的sortByState()就不会执行这一操作。因此drawImplementation()的时候_stateGraphList不一定为空,_renderLeafList也不一定非空。

sortBackToFront()的意义在于绘制需要Blend的对象(也就是您设置了TRANSPARENT_BIN的对象),因此它需要按照深度排序的结果重建新的_renderLeafList队列并渲染,而不是使用_stateGraphList中默认顺序渲染的。

draw_forward的确会使得后面分支代码永远不会被执行。如果您有心了解这个看似“无用”的判断的起源,不妨用SVN工具查一查以前的reversion版本的log日志:6071中OSG添加了“颠倒渲染顺序”的功能,目的是“make it more likely that OpenGL objects will still be in video ram”(抱歉我没有深究这句话的意思);然而6074中,“Disabled the alternating directions ... as it was interferring with anaglyphic stereo”,这样就很明白了,这个功能对于立体显示有影响,并且暂时消除不了这一干扰。

既然无法彻底解决问题就只能回避,此时马上删除旧的程序并不是一个聪明的做法,因为我们不能确定它是否会在什么时候焕发青春,因此才会留下这样一个令您疑惑的地方

感谢楼主的探索精神,希望以后能更多地看到这样的帖子~~

该用户从未签到

 楼主| 发表于 2010-9-30 13:13:01 | 显示全部楼层
多谢王税,这下明白了,最近公司正分析osg引擎和ogre,以后多交流

该用户从未签到

发表于 2010-9-30 15:59:29 | 显示全部楼层
如果一小部分分析的成果能够被共享出来,那么对于广大学习者无疑是一件值得庆幸的事情
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表