查看: 1485|回复: 3

osgmemorytest例子

[复制链接]

该用户从未签到

发表于 2013-6-7 23:25:56 | 显示全部楼层 |阅读模式
本帖最后由 gisthink 于 2013-6-7 23:29 编辑

第一次在osgchina中写东西。之前的老家是http://blog.csdn.net/yungis
osgmemorytest这个例子也从一帧入手。
eventTraversal();
updateTraversal();
renderingTraversals();
事件回调、更新回调、渲染。
OpenGL是状态机,调整好各个状态,然后绘制几何体。OSG中同理,renderingTraversals中根据每个StateSet绘制Drawable。无论是加载的模型还是自己绘制的几何体,最后都是Drawable。

renderingTraversals中最主要的还进行了剔除(CullVisitor),这里不多说,主要说OSG中OpenGL的状态的执行。

进入renderingTraversals函数内部,找到(*itr)->runOperations();(对于单线程来说),这句话进行了场景的绘制工作。顺着这个藤一直摸下去,为了思路清晰,列出序号:
1、调用了GraphicsContext::runOperations();
2、在GraphicsContext::runOperations()中找到(*(camera->getRenderer()))(this);
3、跟到了Renderer中的void Renderer:perator () (osg::GraphicsContext* context)
{  
if (_graphicsThreadDoesCull)
    {
        cull_draw();
    }
    else
    {
        draw();
    }
}。
4、在Renderer的draw方法中找到了 sceneView->draw();
5、如果不需要立体显示,在 sceneView->draw();中会找到_renderStage->drawPreRenderStages(_renderInfo,previous);
_renderStage->draw(_renderInfo,previous);
6、然后执行了RenderStage中的drawInner
7、RenderBin::draw(renderInfo,previous);
8、drawImplementation(renderInfo,previous);
9、RenderLeaf* rl = dw_itr->get();     rl->render(renderInfo,previous);
10、state.apply(rg->getStateSet());_drawable->draw(renderInfo);最终实现绘制
好复杂的一条路了,对于多线程而言与以上的步骤有些不同,但大体差不多。

几个重要的类,GraphicsContext--Renderer--SceneView--RenderStage(RenderBin)--RenderLeaf--Drawable。

最终的实现都在具体的Drawable中,就像上面说的,无论是加载的模型还是自己绘制的几何体,最后都是Drawable。这样最终会调用可用的Drawable实现绘制。
以上这么一条复杂的路线,要重点说的是第10步中的state.apply(rg->getStateSet());

下面从这个调用说起,State存储了OpenGL需要的所有的状态,是OSG与OpenGL状态的接口,进入这个函数中看看做了什么。
在这个函数中找到了applyAttributeList(_attributeMap,dstate->getAttributeList());这么一句话,深入下去。循环调用了applyAttribute这个函数,而传递的就是StateAttribute,这就是OSG中某个状态属性,在applyAttribute中找到了attribute->apply(*this);状态属性执行了apply把State传入进去。进入StateAttribute中的apply,不禁大失所望,什么也没有??

StateAttribute是基类,打开API文档,看看继承StateAttribute的状态属性吧,有几十个之多,我们重点找几个看看。
Fog,进入Fog的Fog::apply(State& state),在这里看见了OpenGL函数,glFogi以及一系列的设置。
PolygonOffset,进入PolygonOffset的PolygonOffset::apply(State&),在这里看见了glPolygonOffset执行多边形偏移。
Texture2D,进入Texture2D::apply(State& state),在这里看见了glTexImage2D。
...
attribute->apply(*this)这么短短的一句话,就执行了所有状态属性的设置。
这篇文章的标题是osgmemorytest,怎么绕了这么多?下面回到osgmemorytest例子中。

定义了好多的基类,MemoryTest、GLObject、GLMemoryTest。
有用的是ContextTest,osg::ref_ptr<osg::GraphicsContext> window = osg::GraphicsContext::createGraphicsContext(traits.get());创建了GraphicsContext,根据pbuffer来决定是PixelBuffer还是Window。
StateAttributeObject中执行了_attribute->apply(*renderInfo.getState());看到这里就知道了为什么上面说了那么多,都是在说这个类的作用。
TextureTest中最终都调用了StateAttributeObject。
FboTest中也调用了StateAttributeObject。
DrawableObject调用了_drawable->draw(renderInfo);
GeometryTest调用了DrawableObject中的函数。

从以上几个类的功能来说,不难看出他们所作的事情,1、创建窗口;2、设置状态;3、绘制;
因此整个的例子大体上描绘了OSG渲染的一个过程,而main函数中所做的就是创建窗口、设置状态、绘制。打印出contexts数目,objects applied次数已经执行所用的实际。

该用户从未签到

 楼主| 发表于 2013-6-7 23:31:16 | 显示全部楼层
发错地方了。

该用户从未签到

发表于 2013-6-8 07:59:08 | 显示全部楼层
已经移到教程区了

该用户从未签到

发表于 2013-6-9 09:28:28 | 显示全部楼层
顶一下LZ
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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