Practical Rendering and Computation with Direct3D 11
+ -

3.3.1输入装配程序管道输入

2024-06-18 6 0

在将数据传递到管道中之前,输入装配程序必须连接到适当的资源以获取输入几何数据。该数据由顶点数据和顶点索引数据组成,这两个数据都以缓冲资源的形式提供给管道。以下两部分描述如何将这些缓冲区资源绑定到输入装配程序。

顶点缓冲阶段

输入装配程序的主要职责是正确地装配顶点以供进一步使用,它需要从应用程序访问顶点数据。该数据存储在一个或多个顶点缓冲区资源中,并且可以以各种不同的布局进行组织。从概念上讲,我们可以将输入装配程序视为具有几个输入槽,这些槽可以填充顶点缓冲区资源。图3.5显示了这种可视化。

1123077774

每个槽都可以填充一个顶点缓冲区资源,该资源包含一个完整顶点的一个或多个属性。例如,一个顶点缓冲区可以包含顶点的位置数据,而第二个顶点缓冲区时可以包含所有法向量数据。还可以在结构阵列中的单个顶点缓冲器内提供所有顶点数据。开发人员可以选择如何最好地组织输入数据。目前有16个输入插槽可供应用程序配置,这为所需的顶点数据提供了相当灵活的存储选项。通过单独存储各个属性,可以动态决定特定渲染需要哪些顶点组件。这可以通过消除顶点中未使用的属性,潜在地减少读取顶点数据所需的带宽。我们将在本章后面讨论如何在多个缓冲区中存储各种数据的细节。

为了将顶点缓冲区绑定到输入装配程序阶段,我们使用设备上下文接口。正如我们在第1章中看到的,设备上下文是完整管道的主要接口。使用ID3D11 DeviceContext::IASetVertexBuffers方法将多个顶点缓冲区绑定到输入装配程序的过程如清单3.2所示。在调用IASetVertexBuffers方法之前,列表中声明的每个变量都将填充相应的缓冲区引用、步长和偏移量。

以下代码展示了如何将多个顶点缓冲区绑定到输入装配程序阶段。

UINT StartSlot;
UINT NumBuffers;
ID3DllBuffer* aBuffers[D3D11_IA_VERTEX_INPUT_RES0URCE_SL0T_C0UNT];
UINTa Strides[D3Dll_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
UINTa 0ffsets[D3Dll_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];

//Fill  in all data here...
pContext->IASetVertexBuffers(StartSlot,NumBuffers,aBuffers,aStrides,aOffsets);

函数如下:

void ID3D11DeviceContext::IASetVertexBuffers(
  [in]           UINT         StartSlot,
  [in]           UINT         NumBuffers,
  [in, optional] ID3D11Buffer * const *ppVertexBuffers,
  [in, optional] const UINT   *pStrides,
  [in, optional] const UINT   *pOffsets
);

在StartSlot和NumBuffers参数中指定要开始绑定到的第一个输入装配程序顶点缓冲区槽的索引,以及应绑定的后续缓冲区槽数。顶点缓冲区资源指针的列表必须装配到一个连续的数组中,并在ppVertexBuffers参数中传递。最后两个参数pStrides和pOffsets允许应用程序指定每个顶点缓冲区的每个顶点步长,以及开始使用每个顶点缓冲区时到所需位置的偏移。这些数组元素中的每一个都将在StartSlot索引处开始使用,并将用于填充NumBuff的插槽数量。这意味着数组的大小和填充必须适当,否则函数将访问无效的内存位置。此外,要将顶点缓冲区绑定到输入装配程序,缓冲区不能绑定到管道中的另一个位置进行写入。这是一个合理的要求,因为它会导致看似不可预测的结果,同时读取和写入缓冲区。

顶点缓冲区阶段

当单独获取时,顶点数据由输入装配程序按照其在顶点缓冲区中出现的顺序进行解释。这意味着,如果顶点数据用于渲染三角形,则前三个顶点定义第一个三角形,然后是下一个三角形的下三个顶点,依此类推。如果两个相邻三角形实际引用同一顶点,则这可能导致重复的顶点数据。事实上,通常情况是这样的——大多数三角形网格都有大量的相邻三角形。当在顶点缓冲区中多次指定单个顶点数据时,可能会浪费大量内存。这种低效率可以通过使用索引缓冲区来消除。索引缓冲区用于通过向顶点缓冲区提供索引偏移来定义每个基元的顶点顺序。在这种情况下,每个顶点可以指定一次,然后指向它的索引可以用于它所属的任何三角形。使用索引渲染时,三角形中要使用的三个顶点由索引缓冲区中的三个连续索引指定。

若要使用索引渲染,应用程序必须将索引缓冲区绑定到输入装配程序。只有一个槽可用于绑定索引缓冲区,并且仅在一个索引绘制调用期间使用,以指定用于生成基元的顶点的顺序。若要将索引缓冲区绑定到输入装配程序,应用程序必须使用ID3DllDeviceContext::IASetIndexBuffer方法。清单3.3演示了如何执行此绑定操作。该方法提供了三个简单的参数:指向索引缓冲区的指针、索引存储的格式(16位或32位无符号整数),以及索引缓冲区中开始构建基元的偏移量。

ID3DllBuffer* pBuffer = 0;
UINT offset = 0;
// Set pBuffer to the desired index buffer reference here, and
// set the offset to an appropriate location in the buffer.
m_pContext->IASetIndexBuffer( pBuffer, DXGI_FORMAT_R32_UINT, offset );

函数声明:

void ID3D11DeviceContext::IASetIndexBuffer(
  [in, optional] ID3D11Buffer *pIndexBuffer,
  [in]           DXGI_FORMAT  Format,
  [in]           UINT         Offset
);

一旦顶点或索引缓冲区绑定到管道,就可以通过将NULL指针值设置到相应的输入槽来解除绑定。记住这一点很重要,尤其是在重新配置绘制调用之间的管道时。如果在以前的绘制调用中使用了多顶点缓冲区配置,而新的绘制调用使用的顶点缓冲区较少,则应使用NULL填充未使用的槽,以解除未使用缓冲区的绑定。这就是为什么顶点缓冲区绑定方法总是使用一个大小为顶点缓冲区最大数量的数组,并在填充所需配置之前将其初始化为NULL值。

0 篇笔记 写笔记

作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!