坐标系与基本图元(1)
Direct3D基本图元
图元(primitives)是Direct3D中定义的基本图形表示,它是组成一个单一实体的一组顶点。最简单的图元是三维坐标系中多个点的集合,称为点列表(point list)。通常,图元是多边形(polygon),一个多边形是由至少三条边组成的封闭图形。最简单的多边形是三角形,Direct3D使用三角形来构成大多数其他多边形,这是因为三角形的三个顶点肯定是共面的,而渲染不共面的顶点效率比较低。通过组合三角形可以形成更大、更复杂的多边形和网格(mesh)。
Direct3D定义了6中基本图元。
Defines the primitives supported by Direct3D.
typedef enum D3DPRIMITIVETYPE{ D3DPT_POINTLIST = 1, D3DPT_LINELIST = 2, D3DPT_LINESTRIP = 3, D3DPT_TRIANGLELIST = 4, D3DPT_TRIANGLESTRIP = 5, D3DPT_TRIANGLEFAN = 6, D3DPT_FORCE_DWORD = 0x7fffffff,} D3DPRIMITIVETYPE, *LPD3DPRIMITIVETYPE;
Constants
- D3DPT_POINTLIST
- Renders the vertices as a collection of isolated points. This value is unsupported for indexed primitives.
- D3DPT_LINELIST
- Renders the vertices as a list of isolated straight line segments.
- D3DPT_LINESTRIP
- Renders the vertices as a single polyline.
- D3DPT_TRIANGLELIST
Renders the specified vertices as a sequence of isolated triangles. Each group of three vertices defines a separate triangle.
- Back-face culling is affected by the current winding-order render state.
- D3DPT_TRIANGLESTRIP
- Renders the vertices as a triangle strip. The backface-culling flag is automatically flipped on even-numbered triangles.
- D3DPT_TRIANGLEFAN
- Renders the vertices as a triangle fan.
- D3DPT_FORCE_DWORD
- Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.
Remarks
Using Triangle Strips (Direct3D 9) or Triangle Fans (Direct3D 9) is often more efficient than using triangle lists because fewer vertices are duplicated.
顶点集合(point list)(或称为点列表)表示将要绘制的图形是一组独立的集合,在程序中可以使用点列表表示天空中的星星,或者点画线等。对点列表图元同样可以应用纹理和材质,只不过材质或纹理的颜色只在画点的位置显示,而在点之外的任何地方都不显示。
IDirect3DDevice9的DrawPrimitive()是Direct3D的图元绘制方法,该方法的声明如下:
Renders a sequence of nonindexed, geometric primitives of the specified type from the current set of data input streams.
HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);
Parameters
- PrimitiveType
- [in] Member of the D3DPRIMITIVETYPE enumerated type, describing the type of primitive to render.
- StartVertex
- [in] Index of the first vertex to load. Beginning at StartVertex the correct number of vertices will be read out of the vertex buffer.
- PrimitiveCount
- [in] Number of primitives to render. The maximum number of primitives allowed is determined by checking the MaxPrimitiveCount member of the D3DCAPS9 structure. PrimitiveCount is the number of primitives as determined by the primitive type. If it is a line list, each primitive has two vertices. If it is a triangle list, each primitive has three vertices.
Return Values
If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.
Remarks
When converting a legacy application to Direct3D 9, you must add a call to either IDirect3DDevice9::SetFVF to use the fixed function pipeline, or IDirect3DDevice9::SetVertexDeclaration to use a vertex shader before you make any Draw calls.
线段集合(line list)(或称线段列表)表示一组相互独立的直线段。线段集合可用于在三维场景中绘制下雨等效果,应用程序通过填充一组顶点创建一个线段集合。注意,顶点个数必须是大于等于2的偶数。可以将材质或纹理添加到线段集合中,默认情况下,材质或纹理的颜色沿线段变化而绘制,并不是线段上某一点的颜色。
线段条带(line strip)是由一组相互连线的线段构成的图元。可以使用线段条带创建不封闭的多边形,封闭多边形是指最后一个顶点与第一个顶点间用线段连接起来的多边形。如果使用线段条带创建多边形,该多边形有可能不共面,即不在一个平面内。
一个三角形集合(triangle list)是一系列独立的三角形。它们可以彼此相邻,也可以不相邻。一个三角形集合的顶点数至少是3,并且它的顶点总数必须能被3整除。使用三角形集合创建的对象,其构成部件是不相交的。例如,在三维游戏中创建一面墙的方法就是具体指定一系列小的互不相连的三角形。然后给这些三角形加上看上去发光的材质和纹理,使墙上的每个三角形看上去都发光。因为三角形间可能存在间隙,当玩家盯着游戏中的场景时,可能发现墙后面的场景变得部分可见。
三角形条带(triangle strips)是一系列相互连接的三角形。因为这些三角形是相互连接的,所以应用程序没有为每个三角形指定它的三个顶点。大多数三维场景中的对象都是由三角形条带构成的,这是因为三角形条带可以高效利用内存和运行时间画出复杂的对象。
三角形扇(triangle fans)与三角形条带很相似,不同之处是,三角形扇形共享一个顶点。
使用顶点缓冲区绘制图形
在Direct3D中,顶点缓冲区(vertex buffer)是Direct3D用来保存顶点数据的内存缓冲区,由IDirect3DVertexBuffer9接口对象表示。顶点缓冲区可以保存任何类型的顶点数据,并可以对其中的顶点数据进行坐标变换、光照处理、裁剪等操作,顶点缓冲区中的顶点数据表示要输出到屏幕上显示的图形。
根据图形显示的需要,顶点缓冲区中的顶点可以包含顶点坐标、颜色、法线方向、纹理坐标等属性,至于顶点数据具体包含哪些属性,可以使用灵活顶点格式(Flexible Vertex Format, FVF)进行描述。
Flexible Vertex Format Constants, or FVF codes, are used to describe the contents of vertices interleaved in a single data stream that will be processed by the fixed-function pipeline.
Vertex Data Flags
The following flags describe a vertex format. For information regarding vertex formats, see Fixed Function FVF Codes (Direct3D 9).
#define | Description | Data order and type |
---|---|---|
D3DFVF_DIFFUSE | Vertex format includes a diffuse color component. | DWORD in ARGB order. See D3DCOLOR_ARGB. |
D3DFVF_NORMAL | Vertex format includes a vertex normal vector. This flag cannot be used with the D3DFVF_XYZRHW flag. | float, float, float |
D3DFVF_PSIZE | Vertex format specified in point size. This size is expressed in camera space units for vertices that are not transformed and lit, and in device-space units for transformed and lit vertices. | float |
D3DFVF_SPECULAR | Vertex format includes a specular color component. | DWORD in ARGB order. See D3DCOLOR_ARGB. |
D3DFVF_XYZ | Vertex format includes the position of an untransformed vertex. This flag cannot be used with the D3DFVF_XYZRHW flag. | float, float, float. |
D3DFVF_XYZRHW | Vertex format includes the position of a transformed vertex. This flag cannot be used with the D3DFVF_XYZ or D3DFVF_NORMAL flags. | float, float, float, float. |
D3DFVF_XYZB1 through D3DFVF_XYZB5 | Vertex format contains position data, and a corresponding number of weighting (beta) values to use for multimatrix vertex blending operations. Currently, Direct3D can blend with up to three weighting values and four blending matrices. For more information about using blending matrices, see Indexed Vertex Blending (Direct3D 9). | 1, 2, or 3 floats. When D3DFVF_LASTBETA_UBYTE4 is used, the last blending weight is treated as a DWORD. |
D3DFVF_XYZW | Vertex format contains transformed and clipped (x, y, z, w) data. ProcessVertices does not invoke the clipper, instead outputting data in clip coordinates. This constant is designed for, and can only be used with, the programmable vertex pipeline. | float, float, float, float |
Texture Flags
The following flags describe texture flags used by the fixed-function pipeline.
#define | Description |
---|---|
D3DFVF_TEX0 - D3DFVF_TEX8 | Number of texture coordinate sets for this vertex. The actual values for these flags are not sequential. |
D3DFVF_TEXCOORDSIZEN(coordIndex) | Define a texture coordinate data set. n indicates the dimension of the texture coordinates. coordIndex indicates texture coordinate index number. See D3DFVF_TEXCOORDSIZEN and Texture coordinates and Texture Stages. |
Mask Flags
The following flags describe mask flags used by the fixed-function pipeline.
#define | Description |
---|---|
D3DFVF_POSITION_MASK | Mask for position bits. |
D3DFVF_RESERVED0, D3DFVF_RESERVED2 | Mask values for reserved bits in the FVF. Do not use. |
D3DFVF_TEXCOUNT_MASK | Mask value for texture flag bits. |
Miscellaneous Flags
The following flags describe a variety of flags used by the fixed-function pipeline.
#define | Description |
---|---|
D3DFVF_LASTBETA_D3DCOLOR | The last beta field in the vertex position data will be of type D3DCOLOR. The data in the beta fields are used with matrix palette skinning to specify matrix indices. |
D3DFVF_LASTBETA_UBYTE4 | The last beta field in the vertex position data will be of type UBYTE4. The data in the beta fields are used with matrix palette skinning to specify matrix indices.
// Given the following vertex data definition: struct VERTEXPOSITION{ float pos[3]; union { float beta[5]; struct { float weights[4]; DWORD MatrixIndices; // Used as UBYTEs } }}; Given the FVF is declared as: D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4. Weight and MatrixIndices are included in beta[5], where D3DFVF_LASTBETA_UBYTE4 says to interpret the last DWORD in beta[5] as type UBYTE4. |
D3DFVF_TEXCOUNT_SHIFT | The number of bits by which to shift an integer value that identifies the number of texture coordinates for a vertex. This value might be used as shown below.
DWORD dwNumTextures = 1; // Vertex has only one set of coordinates. // Shift the value for use when creating a // flexible vertex format (FVF) combination.dwFVF = dwNumTextures << D3DFVF_TEXCOUNT_SHIFT; // Now, create an FVF combination using the shifted value. |
Examples
The following examples show other common flag combinations.
// Untransformed vertex for lit, untextured, Gouraud-shaded content.dwFVF = ( D3DFVF_XYZ | D3DFVF_DIFFUSE );
// Untransformed vertex for unlit, untextured, Gouraud-shaded // content with diffuse material color specified per vertex.dwFVF = ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE );
// Untransformed vertex for light-map-based lighting.dwFVF = ( D3DFVF_XYZ | D3DFVF_TEX2 );
// Transformed vertex for light-map-based lighting with shared rhw.dwFVF = ( D3DFVF_XYZRHW | D3DFVF_TEX2 );
// Heavyweight vertex for unlit, colored content with two // sets of texture coordinates.dwFVF = ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX2 );