翻译《real-time 3d terrain engines using C++ and DX9 》(8)

 
渲染队列(the render queue)
    维护一个像我们这样的渲染管线最重要的一个方面就是控制那些程序所要求的昂贵的状态改变(state changes)开销。一个“状态改变”就是指示显卡去切换它正在处理的模型和纹理所要作的所有事情。这些很耗时的状态改变包括激活顶点和像素shaders,还有改变D3DX的渲染状态和纹理采样器。使用D3DX的效果文件(effect file)使得这个问题更加困难,因为效果文件可以包含许多的状态改变。这些渲染状态可能在多个效果文件中被设置很多次,导致同样的渲染状态值被一遍又一遍的设置。
 
    我们可以对我们显卡驱动处理这些冗余的状态改变有一点信心,因为这些直接的管理已经超出了我们的控制范围。然而,我们可以直接控制效果文件中“技术”(techniques)来确保整个渲染状态的集合,包括顶点和像素shaders,在一个给定的场景中使用不超过一次。而且,我们也可以扩展我们的管理到模型,顶点缓冲,索引缓冲和模型的激活。如果我们将这些状态改变按耗费给予优先值,我们就可以控制他们被送到显示硬件中去渲染的顺序。
    这个可以使用渲染队列实现,可以在我们代码库的cRendderQueue找到。这个队列有点像一个我们要渲染的物体的执行表(execution list)。我们把这些对象提交到渲染队列而不是直接渲染到屏幕。一旦所有的物体都被放到这个队列,我们就可以按照他们的耗费来排序,然后渲染整个场景。这里的技巧是设计一个表示队列一项的方法让它们能够容易被排序。
    渲染的基本元素是几何体,材质和渲染方法。这三个东西,带有一些基本的参数比如转换矩阵,就是现实一个对象需要的全部。因为很幸运的有了这个,我们已经有了一个代表我们资源对象cModelResource,cSurfaceMaterial cEffectFile的很渐渐的表示。事实上,我们的资源管理器每个对象赋予了一个16位的索引代表他们在一个已经飞配的对象池中的位置。使用这些索引值,我们可以用一个3字(three-word)的值来代表渲染队列中的元素。
    假定我们强制给这些字一个顺序。了解到激活一个效果文件(包含了顶点和像素shader)是一个非常昂贵的操作,我们把cEffectFile的索引放在我们三字集合的最高位部分。集合体改变是接下来昂贵的,因为他们包含索引缓冲和多个可能的顶点流。记住这个,我们将cModelResource的索引作为第二个字的值,然后近似的把cSurfaceMaterial索引放在最低的字。
    这个构造优先值的过程为我们的渲染队列创建了一个48位有序的索引。如果我们以这些对象的48位值来排序他们,我们可以确保所有在相同的cEffectFile中的对象在表中都是成组的。在每个组中,所有使用相同cModelResource的几何体也是成组的,最后,在一个几何组中所有使用相同cSurfaceMaterial的对象也是成组的。这个有序的列表现在代表了一个渲染场景所需要的状态改变资源的更高效的数量。
    cRenderEntry 的代码在这个思想的基础上用一个20字节的值来代表渲染队列的每一个任务。这笔我们48位的例子大得多,然而提供了我们可以用来排序我们渲染操作的更多信息。cRenderEntry提供了12字节的值用来排序,另外的8字节包含一个回调指针(callback pointer)和用户定义参数。这使得一个调用可以提交一个对象渲染并且提供一个当实际渲染将要发生时将被触发的回调函数。cRenderEntry 集中了所有的对象,按优先级对他们排序,然后通过触发提供的回调函数一个接一个的渲染他们。
 
    用来排序cRenderEntry对象的12字节的值包含了我们例子中相同的基本信息,几何体,材质和渲染方法。cRenderEntry扩展这个来包含用来标识每个资源特殊用法的额外参数。例如,渲染方法在队列中不只是用cEffectFile资源的所以字值,还包括用来描述所使用的效果通道(pass)的额外信息。使用这个数据,我们既是按效果文件来排序,也是按效果文件中每个独立的通道。
    查看cRenderQueuecRenderEntry的类定义是熟悉我们将要用来处理我们渲染管线的优先队列的最好办法。一个值得注意的是那些最后用来执行最终渲染的那些回调函数的标志的集合。当渲染队列处理这个列表,它一直跟踪那个当前正在使用的资源。当它遇见了表中的一个新资源,回调函数就被传递,同时回调函数带有一个标志来通知用户去激活新资源。下面的4.7cRenderQueuecRenderEntry类的一些重要的代码,接下来的4.8展示了我们的一个对象,cModel,使用渲染队列来提交他自己以渲染,然后调用回调函数在适合的时间执行实际的模型光栅化。
  
 
ps:好吧,到这里为止,一章终于结束了,断了很久,居然写了一年。。。我还是强调下,翻译是个很幸苦的事情,即时我还是在不保证翻译质量的情况下,所以有什么错误大家多包涵,这次的代码先不贴了,换了电脑,找起来麻烦,看球先,下次补上。
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页