固定函数顶点处理 (Direct3D 9)

在固定函数顶点管道中,处理顶点缓冲区中的顶点将应用设备的当前转换矩阵。 还可以应用顶点作,例如照明、生成剪辑标志和更新盘区。 使用固定函数顶点处理时,修改目标顶点缓冲区中的元素由 D3DPV_DONOTCOPYDATA 标志控制。 此标志仅适用于固定函数顶点处理。 IDirect3DDevice9 接口公开 IDirect3DDevice9::P rocessVertices 方法来处理顶点。 通过调用 IDirect3DDevice9::P rocessVertices 方法,将顶点着色器中的顶点从顶点着色器处理到输入数据流集,从而生成单个交错顶点数据流到目标顶点缓冲区。 该方法接受五个参数,这些参数描述方法面向的顶点的位置和数量、目标顶点缓冲区和处理选项。 调用后,目标缓冲区包含已处理的顶点数据。

第一个、第二个和第三个参数(SrcStartIndex、DestIndex 和 VertexCount)反映要加载的第一个顶点的索引、要放置顶点的目标缓冲区中的索引,以及要分别处理和放置在目标缓冲区中的顶点总数。 第四个参数 pDestBuffer 应设置为将接收源顶点的顶点缓冲区对象的 IDirect3DVertexBuffer9 接口的地址。 SrcStartIndex 参数指定方法应从其开始处理顶点的索引。

最终参数 Flags 确定方法的特殊处理选项。 对于默认顶点处理,可以将此参数设置为 0,或者将 D3DPV_DONOTCOPYDATA 在某些情况下优化处理。 还可以将D3DPV_DONOTCOPYDATA值与适用于目标缓冲区的一个或多个 D3DLOCK 值组合在一起。 将标志设置为 0 时,目标顶点缓冲区顶点格式的顶点组件仍会从顶点着色器复制或设置为 0。 但是,使用D3DPV_DONOTCOPYDATA时,IDirect3DDevice9::P rocessVertices 不会覆盖目标缓冲区中的颜色和纹理坐标信息,除非 Direct3D 生成此数据。 启用照明时,将生成漫射颜色,即D3DRS_LIGHTING设置为 true 。 启用照明并启用反射时,将生成反射颜色,即D3DRS_SPECULARENABLE和D3DRS_LIGHTING设置为 true 。 启用雾后,还会生成反射颜色。 启用纹理转换或纹理生成时,将生成纹理坐标。 IDirect3DDevice9::P rocessVertices 使用当前呈现状态来确定应执行哪些顶点处理。

目标顶点缓冲区的 FVF 使用情况设置

IDirect3DDevice9::P rocessVertices 方法需要目标顶点缓冲区 D3DFVF 的特定设置。 FVF 使用设置必须与顶点处理的当前设置兼容。

对于固定函数顶点处理,IDirect3DDevice9::P rocessVertices 需要以下 FVF 设置:

  • 位置类型始终 D3DFVF_XYZRHW;因此,通过D3DFVF_XYZB5 D3DFVF_XYZ和D3DFVF_XYZB1无效。
  • 不得设置 D3DFVF_NORMAL、D3DFVF_RESERVED0和D3DFVF_RESERVED2标志。
  • 如果以下条件的 OR作返回 true,则必须设置 D3DFVF_DIFFUSE 标志:
    • 已启用照明;也就是说,D3DRS_LIGHTING TRUE
    • 照明已禁用,输入顶点流中存在漫射颜色,并且未设置 D3DPV_DONOTCOPYDATA
  • 如果以下条件的 OR作返回 true,则必须设置 D3DFVF_SPECULAR 标志:
    • 已启用照明并启用反射颜色;也就是说,D3DRS_SPECULARENABLE TRUE
    • 照明已禁用,输入顶点流中存在反射颜色,并且未设置 D3DPV_DONOTCOPYDATA
    • 已启用顶点雾;也就是说,D3DRS_FOGVERTEXMODE未设置为D3DFOG_NONE。

此外,必须采用以下方式设置纹理坐标计数:

  • 如果对所有活动纹理阶段禁用纹理转换和纹理生成,并且未设置 D3DPV_DONOTCOPYDATA,则需要输出纹理坐标的数量和类型与输入顶点纹理坐标的坐标匹配。 如果设置了D3DPV_DONOTCOPYDATA并禁用纹理转换和纹理生成,则忽略输出纹理坐标。
  • 如果为任何活动纹理阶段启用了纹理转换或纹理生成,则输出顶点可能需要包含比输入顶点更多的纹理坐标集。 这是因为纹理坐标的扩散,这些坐标是由纹理生成或纹理转换派生的。 请注意,纹理坐标的类似激增发生在 IDirect3DDevice9::D rawPrimitive 调用期间,但对应用程序程序员不可见。 在这种情况下,Direct3D 将生成一组新的纹理坐标。 新纹理坐标集是通过单步执行纹理阶段和分析纹理生成、纹理转换和纹理坐标索引的设置来派生的,以确定该阶段是否需要一组唯一的纹理坐标。 每次需要新集时,都会按递增顺序进行分配。 请注意,最大和典型要求是每个阶段一个集,尽管由于通过D3DTSS_TEXCOORDINDEX共享非转换纹理坐标,它可能更少。

因此,对于每个纹理阶段,如果纹理绑定到该阶段并且以下任何条件都为 true,则会生成一组新的纹理坐标:

  • 为该阶段启用纹理生成。
  • 为该阶段启用纹理转换。
  • 非转换输入纹理坐标首次通过D3DTSS_TEXCOORDINDEX进行引用。

当 Direct3D 生成纹理坐标时,应用程序需要执行以下作:

  1. 使用具有适当 FVF 用法的目标顶点缓冲区。
  2. 根据后处理纹理坐标的位置,重新编程纹理阶段的D3DTSS_TEXCOORDINDEX。 请注意,在后续 IDirect3DDevice9::D rawPrimitiveIDirect3DDevice9::D rawIndexedPrimitive 调用中使用处理顶点缓冲区时,会发生D3DTSS_TEXCOORDINDEX设置的重新编程。

最后,必须采用以下方式设置纹理坐标维度(D3DFVF_TEX0 到D3DFVF_TEX8):

  • 对于每个纹理坐标集,如果禁用纹理转换和纹理生成,则输出纹理坐标维度必须与输入匹配。 如果启用了纹理转换,则输出维度必须与D3DTTFF_COUNT1、D3DTTFF_COUNT2、D3DTTFF_COUNT3或D3DTTFF_COUNT4设置定义的计数匹配。 如果禁用纹理转换并启用纹理生成,则输出维度必须与纹理生成模式的设置匹配;目前所有模式都生成三个浮点值。

IDirect3DDevice9::P rocessVertices 由于目标顶点缓冲区 FVF 代码不兼容而失败时,预期代码将打印到调试输出(仅调试生成)。

顶点缓冲区