Practical Rendering and Computation with Direct3D 11学习笔记(2.2.1)

来源:互联网 发布:网络机顶盒哪家强 编辑:程序博客网 时间:2024/06/16 05:53

2.2.1缓冲资源

2.2.1.1Buffer 资源概述

         Buffer resource 提供了一维线性内存块以供Direct3D 11使用。一些不同的配置被用来改变缓冲区的行为,但是他们们有一些共有的线性设计。如图2.2.1.1所示


如图所示buffer的大小按照字节测量,根据buffer的类型和每个buffer类型的构成,组成buffer的元素拥有不同的大小。倍增的元素个数给出了buffer的大小。这种简单的类数组的设计结构提供了非常多的可用buffer类型,一些可能最初在C++程序中被使用,然而另一些最初附加到管线后可能将被HLSL着色程序使用。

2.2.1.2顶点缓冲概述

       顶点缓冲的目的是储存那些最终将被组装成顶点并且通过渲染管线发送的数据。最简单的顶点缓冲组成是一个顶点结构数组,每个顶点包含元素,例如position(位置), normal vector(法线向量), 和 texture coordinates(纹理坐标),那些顶点元素必须符合合适的格式和类型规范。然而,无论什么期望的顶点通用信息,对于一个特定的渲染算法情况下都能被包装在一个允许自定义输入数据的顶点结构。除了以上所述类型,还包括更加复杂的组成,例如,在相同时间使用超过一个顶点缓冲区,这允许顶点数据从多缓冲区分离,例如顶点position(位置)能储存在一个缓冲区,顶点normal vector(法线向量)储存在另一个缓冲区。综上所述,程序可以在需要的时候选择增加顶点数据,而不是为所有的场景选用一个大的整体缓冲区。这种技术被用来在渲染操作的时候减少带宽。
       在Instance rendering中一个或更多顶点缓冲区提供一个逐顶点数据,而且一个额外的顶点缓冲区提供涿实例数据代替逐顶点数据。在第一个缓冲区被声明的模型然后作为一系列渲染,而在第二个缓冲区涿实例数据应用到每一个实例中。如图2.2.2.2描述了这些不同的顶点提交组成。每一个实例数据能包含一个世界变换,颜色渐变,或者无论什么各种实例之间的什么不同。这种设置允许多个对象在一个Draw调用中渲染,这样减少了总体CPU在渲染操作中的开销。
       
      如图所示每一个顶点缓冲区的类型允许通用的缓冲区设计。每个缓冲区由一维一样大小的元素数组组成。在相同的缓冲区单独数据元素大小一直和其他元素相同,尽管多缓冲区拥有不同大小元素。
     

2.2.1.3 顶点缓区使用

      综上所述,顶点缓冲区的主要目的是为管线提供逐顶点信息,或者直接,在多缓冲区配置,或者通过实例化。有鉴于此,把一个顶点缓冲区绑定到管线的主要地方是IA阶段(输入装配阶段),在哪里作为管线的入口点。除了IA阶段(输入装配阶段)顶点缓冲区还能依附于SO阶段(流输出阶段)允许渲染管线把定点数据输入到缓冲区,如此数据被随后的渲染传送。顶点缓冲区能绑定位置原理如图2.2.2.3所示。


2.2.1.4 创建顶点缓冲区

      正如在资源创建章节所述,每一个资源能绑定到的管线位置类型,为了允许资源绑定到那里都应在创建的时候设置一个对应的绑定标志。如此的话,一个顶点缓冲区必须一直设置D3D11_BIND_VERTEX_BUFFER绑定标志。如果它被用于流输出管线数据,它也能选择地包含D3D11_BIND_STREAM_OUTPUT绑定标志。
      对于顶点缓冲区除了绑定标志以外我们要关心的是缓冲区的使用场景。根据顶点缓冲区内容是否频繁地变动,是否变动位置来自CPU或者GPU,需要不同的使用标识。例如,如果数据将静态的加载到缓冲区,缓冲区资源应该用D3D11-USAGE_IMMUTABLE使用标志创建。如此,被创建的缓冲区将通过D3D11_SUBRESOURCE_DATA参数创建方法初始化顶点数据并且数据将不会再被修改,这样类型的顶点缓冲区例子被用来保存静态地形网格内容。
       然而,如果缓冲区被CPU频繁地更新,缓冲区应该使用D3D11_USAGE_DYNAMIC,而且和一个CPU写标志以便CPU访问标志参数。一个顶点缓冲区类型使用例子当顶点变换呈现在CPU而不是在GPU上。那些更新将被复制到每一帧缓冲区资源。这是一个通用技术被用来压缩许多Draw调用把所有模型数据送入到相同参考帧,通常是世界空间或者视图空间。任然三个类型将被创建一个缓冲区,将被GPU使用流输出功能更新。在这种情况下,D3D11_USAGE_DEFAULT将被使用。一个简单的缓冲区创建过程如下:

/ / I n i t i a l i z e thedevice using i t . . .
ID3DllDevice* g_pDevice = 0;
ID3DllBuffer* CreateVertexBuffer( UINT size,
bool dynamic,
bool streamout,
D3D11_SUBRES0URCE_DATA* pData )
{
D3D11_BUFFER_DESC desc;
desc.ByteWidth = size;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
// Select the
appropriatebinding locations based onthepassedinflags
if ( streamout )
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_0UTPUT;
else
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
// Select the appropriate usage and CPU access flags based on the passed
// in flags
if ( dynamic )
{
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
}
else
{
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.CPUAccessFlags = 0;
}
// Create the bufferwiththe specified configuration
ID3D11Buffer* pBuffer = 0;
HRESULT hr = g_pDevice->CreateBuffer( &desc, pData, &pBuffer );
if ( FAILED( hr ) )
{
// Handle the error here...
return( 0 );
}
return( pBuffer );



0 0
原创粉丝点击