2.2.1缓冲区资源-索引缓冲区
我们将看到的第二种缓冲区类型是索引缓冲区。索引缓冲区提供了通过引用存储在顶点缓冲区中的顶点数据来定义基元的非常有用的能力。或多或少,索引缓冲区提供指向顶点列表的索引列表。根据所需的基元类型(如点、线和三角形),将形成适当大小的索引组,以定义该基元由哪些顶点组成。图2.10直观地描述了该操作。
索引缓冲区的使用可以潜在地显著减少需要定义的顶点的总数。由于每个相邻基元定义都可以引用与其相邻基元相同的顶点数据,因此共享的顶点不需要在顶点缓冲区中重复。此外,这种顶点共享允许多个基本体使用顶点着色器的同一输出顶点。我们将在第3章“渲染管道”中更详细地讨论顶点着色器,但目前,我们只需要了解,在顶点通过顶点着色器运行后,结果可以缓存并由多个基本体重用。这可能会减少给定模型所需的顶点着色器处理量。
使用索引缓冲区
由于索引缓冲区指定了要在基元设置操作中使用的顶点,因此您必须提前知道将使用的基元拓扑,否则您将不知道将索引放入哪个顺序。这通常是通过选择渲染算法和几何加载例程提前很好地确定的。在准备执行绘制操作的管道配置期间,所需的索引缓冲区被绑定到输入装配程序阶段,在那里它将用于生成管道的输入原语。由于这些缓冲区具有非常特定的用途,因此它们通常不会绑定到其他位置的管道。该绑定位置如图2.11所示。
创建索引缓冲区
创建索引缓冲区时,我们遵循标准的缓冲区创建过程,并填充D3D11_buffer_DESC结构。索引缓冲区的描述结构在不同的缓冲区之间不会经常更改,因为这种类型的数据通常会在内容创建程序中定义一次,然后按原样导出。索引缓冲区索引通常在应用程序启动阶段后不会更改。但是,如果某些新算法确实需要动态更新索引缓冲区,也可以使用本章“顶点缓冲区”部分中讨论的动态更新属性来创建它。这可以用于“顶点缓冲区”一节中讨论的绘制调用减少方案,其中多组几何体被动态分组到一组顶点和索引缓冲区中。清单2.7提供了一个典型的创建序列。
ID3DllBuffer* CreateIndexBuffer( UINT size,bool dynamic,D3D11_SUBRES0URCE_DATA* pData)
{
D3D11_BUFFER_DESC desc;
desc.ByteWidth = size;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
deSC.BindFlagS = D3D11_BIND_INDEX_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 buffer with the specified configuration
ID3DllBuffer* pBuffer = 0;
HRESULT hr = g_pDevice->CreateBuffer( &desc, pData, &pBuffer );
if ( FAILED( hr ) )
{
// Handle the error here...
return( 0 );
}
return( pBuffer );
}
要指定的第一项是缓冲区的大小(以字节为单位)。从代码列表中可以看出,索引缓冲区总是使用D3D11_BIND_index_buffer绑定标志创建的。当需要静态索引缓冲区时,使用标志指定为D3D11_usage_IMMUTABLE,不设置任何CPU访问标志。在这种情况下,缓冲区的预期内容必须提供给具有D3D11_SUBRES0URCE_DATA结构的创建调用。如果需要动态缓冲区,我们将选择D3D11_USAGE_dynamic以及D3D11_CPU_ACCESS_WRITE CPU访问标志。
资源视图要求
索引缓冲区直接绑定到输入装配程序阶段,而不需要资源视图的帮助。因此,不需要创建资源视图来使用索引缓冲区。