固定函数顶点处理 (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 时,除非 Direct3D 生成此数据,否则 IDirect3DDevice9::P rocessVertices 不会覆盖目标缓冲区中的颜色和纹理坐标信息。 启用照明时会生成漫射颜色,即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共享未转换的纹理坐标,要求可能会更少。

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

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

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

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

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

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

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

顶点缓冲区