调试最长的一帧(第25天)

本文围绕OSG渲染展开,介绍了从渲染元、状态节点到osg状态机的总体框架,分析了渲染叶与状态机、几何体等之间的关系。阐述了osg::State类的重要功能,它是OSG与OpenGL的主要接口。还梳理了OSG渲染流程,最后提及渲染叶的作用及后续调试内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前已经到了单线程渲染的尾声了,先看看总体框架,看看还是否忘记了。

 

昨天,看到的第24天内容结尾,有点懵逼,下面这个图以前看的也有点懵,直到这两者都看了后,突然有点明白了,从渲染元和状态节点起始,由osg状态机为中转核心。

 

在看电子书之前,先在源码把这张图上的这些找到,观其大略。再对照下电子书,看看自己的思路有什么问题。

可见,moveStateGraph在状态节点中与状态机之间搭建了桥梁。

渲染元与渲染叶之间,RenderLeaft::render()是在 RenderBin::drawImplementation()内实现的。

再看看渲染叶和状态机之间

这时候发现不只是渲染叶和状态机之间用state::apply(const stateSet*)联系,状态节点StageGraph和osg状态机的联系StateGraph::moveStateGraph也在里面调用了,可以推测出,实质的核心在osg状态机,调用的核心在RenderLeaft::render()

接下来看看渲染叶和几何之间,可知也是在RenderLeaft::render()里面。

 

接下来看看几何体和状态机之间的关系。通过setvertexPointer联系

 

下一步进行蓝色箭头部分,osg状态机与顶点/索引数据等的关联

接下来看看osg状态机和渲染模式数据glEnable(。。。)通过State::applyMode()

 

osg状态机和渲染属性数据(AlphaFunc/...),使用State::applyAttribute

渲染属性数据与渲染属性对象通过StateAttribute::apply(State&)联系

现在,再把第24天结尾抄的懵逼的内容,再抄一遍,加深印象,看看是否依然蒙蔽。

osg::State类的几点重要功能。

1,保存OpenGL的所有状态、模式、属性参数、顶点和索引数据

2,提供了对OpenGL状态堆栈的处理机制,对即将进入渲染管线的数据进行优化。

3,允许用户直接查询各种OpenGL状态的当前值。

对于第二点,关于OpenGL渲染状态堆栈的处理,实际上就是对于OSG状态树StateGraph的遍历处理。而对于各种OpenGL模式的开关设定(即glEnable和glDisable)实际上是通过State::applyMode()函数完成;顶点坐标,法线坐标以及各种顶点和索引数组的设置(即glVertexPointer,glNormalPointer等)也是由State类的相关函数,如setVertexPointer等实现的。各种渲染属性的OpenGL处理函数繁多而繁杂,此时State类将使用applyAttribute函数,实现各种各样的渲染特性。

由此可见,osg::State类是OSG与OpenGL的主要接口,场景状态树的遍历者和整合者,也是各种渲染状态,以及顶点值的处理途径。osg的顶点坐标和索引信息是由osg::Geometry类负责保存的,那么负责将Geometry对象的数据传递给State对象的,就是渲染树的叶节点RenderLeaft了。它通过执行自己送包含的Drawable::draw函数,实现几何体的实际绘制;而在Geometry类的绘制过程中,则将自己记录的数据信息传递给State对象,由它负责完成顶点的载入和处理工作。

而渲染树在其中的作用,就是抽取每个渲染树节点RenderBin中的渲染叶RenderLeaf对象,交由osg::State整合它在状态树中继承的全部渲染状态,并将几何体数据传递给OpenGL管线,完成绘制的工作。

现在看看上面的觉得有心得了,继续看第25天的接下来的内容。

 

继续抄。

图中浅蓝色的箭头表示状态机对象中保存的各种OpenGL状态,即渲染属性的数据(如:alpha检测,纹理,雾效等),模式数据(种种使用glEnable/glDisable开启或关闭的模式),以及顶点坐标、法线坐标、颜色坐标、纹理坐标,以及数据索引的数据。这些OpenGL编程中经常使用的概念在OSG中经常用到的概念在OSG中被良好的封装起来,而osg::State类就是它们的具体实现者。

如果我们需要创建新的派生自Drawable的对象,(就像osgText中苏实现的)或者自己创建一种新的渲染属性(派生自StateAttribute),那么图中同样介绍了一些值得注意和借鉴的地方:Drawable几何体对象的具体实现在于drawImplement函数(实际上通过draw函数间接调用的),;而渲染属性的具体函数为StateAttribute::apply(State&),所有的渲染属性都重写了这一函数,以实现自己的功能。

osg渲染流程大致如下

1,渲染树的作用是遍历各个渲染元RenderBin,并按照指定的顺序执行其中各个渲染叶的渲染函数RenderLeaf::render()

2,状态树保存了从根节点到当前渲染叶的路径,遍历这条路径并收集所有的渲染属性数据(StateGraph::moveStateGrpah),即可获得当前渲染叶渲染所需的所有OpenGL状态数据

3,渲染叶的渲染函数负责向状态机(osg::State)传递渲染状态数据,进而由渲染属性类本身完成参数在OpenGL中的注册和加载工作;渲染叶还负责调用几何体Drawable的绘制函数,传递顶点和索引数据并完成场景的绘制工作。

 

下面具体跟踪代码了

 

 

 

 

大致流程如上,

 

 

为了仍然能够调试到断点,main函数恢复

继续抄一抄。渲染叶RenderLeaft是OSG渲染后台中几何体Drawable对象的唯一管理者;而节点树的构建、开关、变换和LOD等节点类型的应用,渲染状态的设置等工作,最终都要归结到几何体的渲染上来。而这里的RenderLeaf::render()函数主要负责获取之前保存的Drawable指针,投影矩阵,模型视点矩阵,深度值等(传递这些信息的是CullVisitor::addDrawableAndDepth函数),并将它们传递给负责渲染状态处理的State类,以及执行Drawable::draw函数。

 

还有个state::apply,是26天的内容,以后再调试吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值