从概念上讲,顶点声明是对顶点直接内存访问(DMA)以及图形流水线的 tessellator 引擎进行编程的一种方法。顶点声明简要地表示了数据的布局及 tessellator 操作。为了解决Microsoft® DirectX® 8.x中顶点声明的复杂性和可扩展性,9.0版引入了用来表示顶点数据流的新格式。 顶点着色器和顶点声明不再是在CreateVertexShader的时候绑定在一起。对着色器的验证已经被分成两部分,一部分在顶点着色器创建时执行,另一部分在DrawPrimitive时执行。顶点着色器和顶点声明都由相应的对象表示。 Decls 不再用DWORD流表示。它们现在用一个D3DVERTEXELEMENT9结构的数组表示。数组中的每个元素描述一个顶点元素。 另外,为了解决API的可用性问题,9.0版增加了一个与SetVertexDeclaration调用等价的SetFVF调用。这是一个有用的函数,当调用这个函数时,新的FVF会取代当前的顶点声明,反之亦然。如果驱动程序是DirectX 8.0之前的版本(NumStream为0),那么对于那些不能被转换成弹性顶点格式(FVF)的顶点声明, SetVertexDeclaration可能会失败并返回错误码。SetFVF既能用于固定功能顶点流水线,又能用于可编程顶点流水线。在内部,系统会根据把FVF映射到DirectX 9.0中的Decl中定义的规则,把FVF码转换为顶点着色器声明。在编写顶点着色器函数中的DCL命令时,应该紧记这一点。因为这个转换的关系,所有后面的讨论将仅限于顶点声明。 D3DVERTEXELEMENT9结构 以下是D3DVERTEXELEMENT9结构中的域以及说明。 · Stream(数据流) - 数据流的编号,当前域会从该编号的数据流中读取。 · Offset(偏移量) - 偏移量,表示当前域从哪里开始读取,以字节为单位。 · Type(类型) - 输入数据的类型,以及数据在传入顶点着色器的寄存器时如何转换格式,也就是,float1,float2,short2n等等。输出的类型由方法决定,有些方法有隐式的输入类型。 · Method(方法) - 将由tessellator(或任何程序化的几何函数)对指定的输入执行的任何预定义操作。 o D3DDECLMETHOD_DEFAULT: 当使用tessellator时,这个元素被插值或复制到顶点处理器的输入寄存器中。这个操作的输入可以是任何类型。这个操作的输出类型与输入相同。 o D3DDECLMETHOD_PARTIALU: 计算rectangular patch(R-patch)上某一点在U方向上的正切值。这个操作的输入类型可以是D3DDECLTYPE_FLOAT[43],D3DDECLTYPE_D3DCOLOR,D3DDECLTYPE_UBYTE4,或D3DDECLTYPE_SHORT4。这个操作的输出类型总是D3DDECLTYPE_FLOAT3。 o D3DDECLMETHOD_PARTIALV: 计算R-patch上某一点在V方向上的正切值。这个操作的输入类型可以是D3DDECLTYPE_FLOAT[43],D3DDECLTYPE_D3DCOLOR,D3DDECLTYPE_UBYTE4,D3DDECLTYPE_SHORT4。这个操作的输出类型总是D3DDECLTYPE_FLOAT3。 o D3DDECLMETHOD_CROSSUV: 通过求两个正切值的叉积计算rect/tri patches(RT-patch)上某一点的法向。这个操作的输入类型可以是D3DDECLTYPE_FLOAT[43],D3DDECLTYPE_D3DCOLOR,D3DDECLTYPE_UBYTE4,或D3DDECLTYPE_SHORT4。这个操作的输出类型总是D3DDECLTYPE_FLOAT3。 o D3DDECLMETHOD_UV: 复制RT-patch上某一点的U,V值,产生一个二维浮点数。这个操作的输入类型必须被设为D3DDECLTYPE_UNUSED。这个操作的输出类型总是D3DDECLTYPE_FLOAT2。输入数据流和偏移量也没有用到(但必须被设为0)。 o D3DDECLMETHOD_LOOKUP: 查找一个位移贴图。输入类型可以是D3DDECLTYPE_FLOAT[234]。只有.x和.y成员被用于纹理贴图查找。这个操作的输出类型总是D3DDECLTYPE_FLOAT4。只有设备支持位移贴图时才能使用这个方法。这个方法只能和D3DDECLUSAGE_SAMPLE一起使用。 o D3DDECLMETHOD_LOOKUPPRESAMPLED: 查找一个预取样的位移贴图。输入类型、流索引值和流偏移量都没有用到(类型必须被设为D3DDECLTYPE_UNUSED,数据流和偏移量必须被设为0)。这个操作的输出类型总是D3DDECLTYPE_FLOAT4。只有设备支持位移贴图时才能使用这个方法。这个方法只能和D3DDECLUSAGE_SAMPLE一起使用。 · Semantic Type(语义类型) - 元素的用途。例如,是否是一个法向量?这对N-patches很有用,并能极大地增强各种数据布局和顶点着色器间的互操作性。TEXCOORDS语义可被用作用户定义的域(Microsoft® Direct3D®没有为这些域定义现成的语义)。一般来说语义是一种把顶点声明和顶点着色器绑定在一起的机制,但是在某种情况下,它们有特殊的解释。例如,N-patch tessellator用一个含有NORMAL和POSITION语义的元素来设置tessellation。 以下这些都是允许的。 语义,用途索引
UsageIndex 与Usage连用用来指定一个顶点元素的语义。现在用户可以指定Usage为D3DDECLUSAGE_POSITION以及UsageIndex = 1,而不是像Microsoft DirectX® 8.x中那样使用D3DVSDE_POSITION2。 一个Decl指定tessellator引擎(或者万一没有使用tessellator引擎的话,就直接是顶点处理引擎,)的输入和输出,顶点元素中的类型域指定输入到decl的数据类型。输出类型由方法隐式决定。 顶点着色器中有如下形式的前缀{semantic, semantic index, register number}。运行库会把声明的语义与着色器的语义信息进行匹配,这样就把输入寄存器和数据流中的字节偏移量配成一对。 把 FVF 映射到 DirectX 9.0 的 Decl FVF D3DVSDT_FLOAT4 D3DVSDT_UBYTE4 D3DDECLUSAGE_BLENDWEIGHT D3DDECLUSAGE_BLENDINDICES D3DVSDT_FLOAT4 D3DVSDT_D3DCOLOR D3DDECLUSAGE_BLENDWEIGHT D3DDECLUSAGE_BLENDINDICES D3DDECLTYPE_FLOAT4 D3DDECLTYPE_FLOAT1 D3DDECLUSAGE_BLENDWEIGHT D3DDECLUSAGE_BLENDINDICES D3DDECLTYPE_FLOATn D3DDECLUSAGE_BLENDWEIGHT D3DDECLTYPE_FLOAT(n-1) D3DDECLTYPE_UBYTE4 D3DDECLUSAGE_BLENDWEIGHT D3DDECLUSAGE_BLENDINDICES D3DDECLTYPE_FLOAT(n-1) D3DDECLTYPE_D3DCOLOR D3DDECLUSAGE_BLENDWEIGHT D3DDECLUSAGE_BLENDINDICES
(D3DUSAGE_POSITIONT, 0)顶点元素的存在用来告诉设备输入的顶点数据已经经过了顶点处理(和FVF中设置了D3DFVF_XYZRHW位相似)。在绘制时,如果当前设置的顶点声明中的某一元素具有(D3DUSAGE_POSITIONT, 0)语义,那么整个顶点处理会被略过(就和FVF中设置了D3DFVF_XYZRHW位相似)。 使用(D3DDECLUSAGE_POSITIONT, 0)的顶点声明有一些限制: · 此类声明中只能使用数据流零。 · 顶点元素必须以偏移量递增的方式存储。 · 数据流中的偏移量必须对齐到 DWORD 。 · 一对相同的(用途,用途索引)只能出现一次。 · 只能使用D3DDECLMETHOD_DEFAULT方法。 · 其余顶点元素不能具有(D3DDECLUSAGE_POSITION, 0)语义。 此外,此类声明还有一些与驱动程序版本有关的限制。这些限制的存在是因为Direct3D直接把此类声明传送给驱动程序而没有做任何转换。 DirectX 9.0 之前的驱动程序 · 输入的声明必须可以被翻译成一个有效的 FVF (顶点元素及其数据类型具有相同的顺序)。 · 纹理坐标间不允许有间隔。这意味着如果有一个 (D3DDECLUSAGE_TEXCOORD, n) 顶点元素,那么同时也应该有一个 (D3DDECLUSAGE_TEXCOORD, n-1) 顶点元素。 不支持 3.0 版本像素着色器的 DirectX 9.0 驱动程序 · 输入的声明必须可以被翻译成一个有效的 FVF (顶点元素及其数据类型具有相同的顺序)。 · 纹理坐标间不允许有间隔。 支持 3.0 版本像素着色器的 DirectX 9.0 驱动程序 允许更通用的声明。 · 顶点元素的顺序可以任意排列,可以使用任何数据类型。 · 如果设备设置了 D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET 能力位,那么多个顶点元素可以在共享相同的数据流偏移量的同时具有不同的类型。 未使用 D3DDECLUSAGE_POSITIONT 的顶点声明 运行库会在创建声明时进行验证。以下是一些通用的规则,用来判断声明的合法性。 · 数据流中所有的顶点元素必须是连续的,并按偏移量排序。 · 数据流偏移量必须对齐到 DWORD 。 · 一对相同的(用途,用途索引)只能出现一次。 · 如果设置了 D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET 能力位,那么顶点元素可以: o 多个顶点元素可以共享数据流中相同的偏移量。 o 它们可以是不同的类型,从而有不同的大小。 o 它们可以任意地重叠。例如,一个元素在数据流中的起始位置可以同时位于另一个元素的中间。 o 顶点元素的数据流偏移量的顺序可以是任意的。 · 顶点元素的数量不能大于 64 。 · UsageIndex 应该在 [0-15] 范围内。 · 用于 DrawPrimitive API 的声明,不应该包含除了 D3DDECLMETHOD_DEFAULT, D3DDECLMETHOD_LOOKUPPRESAMPLED 或 D3DDECLMETHOD_LOOKUP 之外的顶点元素。 · 包含 D3DDECLMETHOD_LOOKUP 或 LOOKUPPRESAMPLED 的顶点声明,应该只用于可编程顶点流水线。 · 用于 DrawRectPatch/DrawTriPatch API 的声明,不能包含 D3DDECLMETHOD_LOOKUPPRESAMPLED 或 D3DDECLMETHOD_LOOKUP 顶点元素。 · 声明只能有一个使用 D3DDECLMETHOD_LOOKUP 或 D3DDECLMETHOD_LOOKUPPRESAMPLED 方法的元素。 · 使用了 D3DDECLMETHOD_LOOKUP 或 D3DDECLMETHOD_LOOKUPPRESAMPLED 的声明不应该使用 D3DDECLMETHOD_DEFAULT 之外的元素,因为位移贴图只对 N-patches 进行。 · 使用了 D3DDECLMETHOD_LOOKUP 或 D3DDECLMETHOD_LOOKUPPRESAMPLED 的顶点元素只能和 (D3DDECLUSAGE_SAMPLE, n) 一起使用,反之亦然。 · 如果一个使用了 D3DDECLMETHOD_LOOKUP 方法的顶点元素的数据流索引和偏移量与现有的顶点元素相同,那么该顶点元素也应该具有相同的数据类型。 · 使用了 D3DDECLMETHOD_LOOKUP 方法的顶点元素应该具有 D3DDECLTYPE_FLOAT2/3/4 数据类型。 · 使用了 D3DDECLMETHOD_CROSSUV, D3DDECLMETHOD_PARTIALU 和 D3DDECLMETHOD_PARTIALV 的顶点元素应该具有兼容的数据类型。 · 使用了 D3DDECLMETHOD_UV 或 D3DDECLMETHOD_LOOKUPPRESAMPLED 的顶点元素的类型必须是 D3DDECLTYPE_UNUSED ,数据流索引和偏移量必须为 0 。 · 使用了 D3DDECLMETHOD_UV, D3DDECLMETHOD_PARTIALU 和 D3DDECLMETHOD_PARTIALV 方法的声明只能用于 DrawRectPath 。 · 用途 D3DDECLUSAGE_TESSFACTOR 只能和数据类型 D3DDECLTYPE_FLOAT1 及用途索引 0 一起使用。 · 把一个声明用于 tessellation ( DrawRectPatch , DrawTriPatch, N-patches )时,数据类型必须小于或等于 D3DDECLTYPE_SHORT4 。 · 如果声明包含的方法需要特定的设备能力(例如,位移贴图, RT-patches ),那么只有当设备支持这些能力时才能创建。 · 用于绘制点和线的顶点声明,不能使用除了 D3DDECLMETHOD_DEFAULT 之外的方法。 · 可以创建哪些声明还取决于驱动程序的能力。 用于可编程顶点流水线 · 在绘制时 Direct3D 会在当前顶点声明和当前顶点着色器函数中查找相同的“用途 – 用途索引”组合。如果找到,那么着色器函数 DCL 中的寄存器会被用作顶点元素的目的寄存器。 · 如果当前顶点声明中的某个顶点元素的用途未能在当前顶点着色器中找到,那么该顶点元素就被忽略。 · 当使用版本 2.0 以下的顶点着色器时,在着色器代码中用到的所有语义,必须存在于在绘制时与之绑定的声明中。当使用版本 2.0 及以上的顶点着色器时,不存在这种限制,这使应用程序可以把同一个顶点着色器和不同的顶点声明一起使用。当顶点着色器根据静态条件读取输入数据时,这是有用的。因为这个原因而未被初始化的顶点着色器寄存器会包含未定义的值。 当在一个DirectX 8.x驱动程序上使用硬件顶点处理时,还有其它的限制: · 顶点元素不能重叠或共享相同的偏移量。 · 只能使用 DirectX 8.x 驱动程序能够理解的数据类型。 如果提供的声明无法被转换为DirectX 8.x风格的声明,那么CreateVertexDeclaration可能会失败。对混合模式设备来说,这种失败会发生在Draw*时刻,因为只有这时候才能知道着色器是被用于硬件还是软件顶点处理。 用于固定功能顶点流水线 只能使用符合以下规则的声明: · 顶点元素之间不能有间隔(固定功能流水线使用了 DirectX 8.x 声明,而 SKIP 在 DirectX 8.x 声明中是不允许的) · 必须指定 (D3DDECLUSAGE_POSITION, 0) 语义,并且具有 D3DDECLTYPE_FLOAT3 数据类型。 · 使用了 D3DDECLMETHOD_UV 方法的顶点元素必须指定 D3DDECLUSAGE_TEXCOORD 或 D3DDECLUSAGE_BLENDWEIGHT 用途。 · 使用了 D3DDECLMETHOD_PARTIALU, D3DDECLMETHOD_PARTIALV 或 D3DDECLMETHOD_CROSSUV 的顶点元素只能和这些用途一起使用: D3DDECLUSAGE_POSITION, D3DDECLUSAGE_NORMAL, D3DDECLUSAGE_BLENDWIEGHT 或 D3DDECLUSAGE_TEXCOORD ,并且输入类型必须是 D3DDECLTYPE_FLOAT3 。 当声明和DirectX 8.x驱动程序的硬件顶点处理一起使用时,Direct3D运行库会根据以下规则把它转换为DirectX 8.x风格的声明。 · 顶点元素不能共享数据流中相同的偏移量,并且不能重叠。 · 数据类型必须小于或等于 D3DDECLTYPE_SHORT4 。 · 只允许以下这些方法: D3DDECLMETHOD_DEFAULT, D3DDECLMETHOD_CROSSUV, D3DDECLMETHOD_UV 。 · 根据 把DirectX 9.0声明映射到DirectX 8.x声明 把 Usage 和 UsageIndex 转换到寄存器值。 · 把DirectX 9.0声明映射到DirectX 8.x声明 列出了哪些 DirectX 9.0 语义可以被转换到 DirectX 8.x 风格的声明。 · 如果声明中有 n 个顶点元素,其中元素 0 - m (m < n) 可以映射到 FVF ( 把DirectX 9.0声明映射到FVF位 中描述的元素),但元素 m+1 不可以,那么: o 如果 m+2 到 n-1 之间的任何一个顶点元素可以映射到 FVF/dx8decl ,那么声明就是无效的。 o 根据 把DirectX 9.0声明映射到FVF位 ,对元素 0 到 m 进行转换(由 DirectX 8.0 运行库和旧的驱动程序,以及 DirectX 9.0 驱动程序执行)。 m+1, m+2 直到 n-1 被映射到连续的 texcoord (k), texcoord(k+1) , k 为元素 0 – m 之间的 texcoord (的数量)。 o 映射后的 texcoord 的数据类型会是 float[1234] ,取代当前元素原来的数据类型(但大小是相同的)。因此即使现有的数据类型没有被包括在 把DirectX 9.0声明映射到FVF位 中,也没有关系。 o 如果 k 到达 8 ,那么声明对 FVF/dx8decl 来说就是无效的。 o 如果存在任何到 texcoord 的映射,那么除了 DEFAULT 方法,整个声明不能包含使用(纹理)生成方法的元素,否则声明对 FVF/dx8decl 来说就是无效的。 把 DirectX 9.0 声明映射到 DirectX 8.x 声明 DirectX 9.0 用途
· 只能使用数据流 0 (显然可以从 MaxStreams 设备能力中看出)。 · 顶点元素的顺序应该和 FVF 位的顺序相同。 · 不允许纹理坐标间有间隔。 · 对所有 DirectX 8.0 之前的驱动程序来说,任何没有在 把DirectX 9.0声明映射到FVF位 中描述的顶点元素不能被转换为有效的 FVF 码。因此无法在这些驱动程序中使用。 · 如果设备没有设置以下这些能力位: D3DPTEXTURECAPS_PROJECTED 或 D3DPTEXTURECAPS_CUBEMAP ,那么使用了 D3DDECLUSAGE_TEXCOORD 的顶点元素只能用 D3DDECLTYPE_FLOAT2 。 把 DirectX 9.0 声明映射到 FVF 位 数据类型
顶点声明可以被用来描述ProcessVertices的输出。此类声明应该遵循以下规则。 · 只能而且必须使用数据流 0 。 · 顶点元素不能共享相同的偏移量或相互重叠。 · 只允许使用 D3DDECLMETHOD_DEFAULT 方法。 · 只能使用 D3DDECLTYPE_FLOATn 或 D3DDECLTYPE_D3DCOLOR 数据类型。 · 使用 (D3DDECLUSAGE_POSITION, 0) 或 (D3DDECLUSAGE_POSITIONT, 0) 的顶点元素不是必需的。 · 使用 (D3DDECLUSAGE_POSITION, 0) 和 (D3DDECLUSAGE_POSITIONT, 0) 的顶点元素不能在同一个声明中出现。 · 当使用此类声明时,当前顶点着色器的必须是 3.0 及以上版本。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sck5711/archive/2009/03/29/4034294.aspx |
顶点声明
最新推荐文章于 2021-07-18 12:33:50 发布