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

博客主要探讨了RenderStage::runCameraSetUp和RenderStage::copyTexture函数的工作内容,介绍了RTT技术及FBO帧缓存实现渲染到纹理的步骤。还阐述了RenderStage::drawInner和RenderBin::draw函数,最后回顾了osg::State类的功能,它是OSG与OpenGL的主要接口。

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

电子书开始主要介绍了要解决的问题。抄一抄。首先,我们要解决的问题是RenderStage::runCameraSetUp和RenderStage::copyTexture这两个函数的工作内容。事实上也是对“什么是渲染目标实现方式”进行讨论。

渲染到纹理。RTT技术意味着我们可以将后台实时绘制得到的场景图像直接作为另一个场景中对象的纹理,从而实现更加丰富的场景表达效果。

在viewer::eventTraversal函数中调用camera::getRenderTargetImplementation()进行纹理烘培,即RTT,

 

可知,要用FBO帧缓存的方式,步骤

1,首先创建一个渲染纹理RenderTexture,例如FBO对象,像素缓存对象等。

2,设置它为图形设备的渲染目标Render Target

3,将渲染纹理绑定到一个纹理或者图片对象上

4,此时图形设备的渲染将在后台进行,其结果直接体现在所绑定的纹理对象上。

注意的是,FRAME_BUFFER表示帧缓存,可以适用于较广泛的硬件平台上;而FRAME_BUFFER_OBJECT表示FBO对象,它可以用来实现离屏渲染的工作,其渲染结果不会体现在图形窗口上。

如下即可将纹理对象texture与场景绘制的帧缓存绑定在一起。我们既可以将texture的内容保存成图片,作为场景的截图;也可以将纹理绑定到某个物体,实现纹理烘焙的效果。

 

可见,绑定到摄像机的实际纹理或者图片,在Camera类中均使用Camera::Attachment结构体来保存。

而RenderStage::runCameraSetUp则反复遍历名为Camera::BufferAttachmentMap的映射表,检索并设置那些与颜色缓存COLOR_BUFFER,深度缓存(DEPTH_BUFFER)等相对应的Attachment对象;

 

设置宽高深(取较大值)

 

出于最简的目的,所以_image没有设置,跳过

 

这里_texture是有效的,根据纹理类型,设置纹理的大小,

可见,并没有达到电子书上说的,遍历Camera::BufferAttachmentMap 的 映射表。

那么,真相只有一个,代码不会骗人。

试试

跟进去

在这里开始创建fbo

 

是否多重采样

设置颜色缓冲区连接

从这里可以看到,跳过去了,为啥呢?因为不满足条件

再回头看看

再调整

这次满足条件了

depthAttached = false;stencilAttached=false;colorAttached = true;

如果没有深度,则添加深度

 

以上就是RenderStage::runCameraSetUp()的过程,是用来绑定实际纹理或者图片的。

接下来是RenderStage::copyTextue().负责针对FRAME_BUFFER渲染目标,拷贝场景图象到Attach图像中。

所以i也要改,否则,判断语句过不去

 

 

 

如果希望使用fbo实现纹理烘焙或者场景截图的话,不可以将场景主摄像机setRenderTargetImplement直接设置为相应的枚举量,那样将无法正常地看到场景。(因为主摄像机对应的渲染台已经将场景绘制的结果绑定到FBO上了)。如下图

正确的方法时在场景中增加一个Camera节点,设置渲染目标实现方式为FBO方式;并通过Camera::setRenderOrder设定它的渲染顺序,设置为PRE_RENDER可以保证这个摄像机在主场景之前执行绘制(它创建了一个前序渲染台,存入RenderStage::_preRenderList列表),从而实现渲染到纹理的效果。

 

 

接下来就是进行整个场景绘制的重点部分RenderStage::drawInner()

 

 

很明显 RenderBin::draw()是重点,后面展开。

 

下面进行重点RenderBin::draw()

这个函数很简单,要么调用RenderBin::drawimplementation(),要么就是自定义绘制回调

 

当然,没这么简单,肯定要风雨欲来,重点要开始了。

电子书上又回顾了下基本知识,先抄抄,加深印象。

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

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

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

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

对于第二点,OpenGL渲染状态堆栈的处理,实际上就是对于OSG状态树StateGraph的遍历处理。而各种OpenGL模式的开关设定,(即glEnable和glDisable)实际上是通过State::applyMode函数完成。

顶点坐标,法线坐标与各种顶点和索引数组的设置(即glVertexPointer,glNormalPointer等)也是由State类的相关函数setVertexPointer等实现。

 

各种渲染属性的OpenGL处理函数,State类将使用applyAttribute()函数,进而调用不同渲染属性对象的StateAttribute::apply(State&)函数,实现多种多样的渲染特性。

 

最后给出了一个结论,由于第25天会详细讲,所以这里只是抄一抄,加深下印象。osg::State类是OSG与OpenGL的主要接口,场景状态树的遍历树和整合者,也是各种渲染状态,以及顶点值的处理途径。由于OSG的顶点坐标和索引信息是由osg::Geometry类负责保护的,那么,负责将Geometry对象的数据传递给State对象的,就是渲染叶的叶节点RenderLeaf了,它通过执行自己所包含的Drawable几何体对象的Drawable::draw函数,实现几何体的实际绘制;而在Geometry类的绘制过程中,则将自己记录的数据信息传递给State对象,由它负责完成顶点的载入和处理工作。

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

 

确实一头雾水,明天看代码再说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值