D3D灵活顶点格式的一些总结

 D3D里面最基本的就是顶点了,虽说一直在用,可是却也是自己比较模糊的一个点,知道其中的意思,却不是很清楚,今天就总结一下,扫一下这个盲区:

 

 

D3D中的顶点缓冲区的声明:

LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL;    //顶点缓冲区对象

通常都是用LPDIRECT3DVERTEXBUFFER9 来声明顶点缓冲区,它其实就是IDirect3DVertexBuffer9的指针类型,这两个起到的效果是一样的。用LPDIRECT3DVERTEXBUFFER9 声明之后,只是镇定了一个缓冲区的指针,下面还需要开辟一个缓冲区给这个指针。

 

 

在开辟真正的内存之前,我们先看一下顶点格式的定义,D3D里面是采用的灵活顶点格式,这点大家应该都是知道的,下面就来总结一下这些灵活顶点格式都具体有哪些,有什么用处。

 

一般定义顶点结构的时候都是用一个结构体,当然用类去定义也可以,但是一般没有那个必要。

 

struct CUSTOMVERTEX

{

    FLOAT x, y, z, rhw;

    DWORD color;

};

在还需要定义一个宏,来向D3D说明一下,自己定义的顶点的格式到底有哪些。

 

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)  //顶点格式

上面这一句话的意思就是,定义的顶点结构包含:位置变换信息(D3DFVF_XYZRHW)和漫反射颜色信息(D3DFVF_DIFFUSE);

那么,一共都有哪些类型可以定义呢,都有什么样的用呢。

 


#defineDescriptionData order and type
D3DFVF_DIFFUSE让顶点信息包含漫反射颜色的信息,在希望顶点有颜色的时候使用,比如一般教程的开始都会画一个有颜色的三角形,那时必须要包含这个信息DWORD in ARGB order. See D3DCOLOR_ARGB.
D3DFVF_NORMAL让顶点包含法线信息,这个标志不能和  D3DFVF_XYZRHW 一块使用(为什么呢,请见下面)。法线信息,对于一个面来说就是和这个面相互垂直的一个向量(指向面的正面),而对于一个点来说,包含这个点的面是共面的的话,和面的法向量相同,如果不共面的话,是面的法向量的和向量。

类型是 :float, float, float


D3DFVF_PSIZE让顶点拥有这么一个特性:顶点的大小是一个像素点,并且大小不随相机的位置变化而变化。还没用过这个只是猜测。float
D3DFVF_SPECULAR让顶点拥有镜面反射颜色的信息。(和漫反射类似,不过这个的计算量很大)DWORD in ARGB order. See D3DCOLOR_ARGB.
D3DFVF_XYZ让顶点包含位置信息,这个和D3DFVF_XYZRHW不可共用,用D3DFVF_XYZ标志的顶点会参与D3D渲染时候的一系列的变换操作(包括世界矩阵的变换,取景变换等等。)float, float, float.
D3DFVF_XYZRHW同上面的参数有些类似,但是最大的区别是,用这个参数定义的顶点的位置,不会参与D3D的所有变换,也就意味着x,y坐标就是屏幕上的点的坐标,z暂时没有什么用处,可能是用于雾化那一块的,还没有测试。float, float, float, float.
D3DFVF_XYZB1 through D3DFVF_XYZB5Vertex 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这个数据和D3DFVF_XYZW相似,也是位置关系,但是它的作用是标志这个点已经经过了投影变换,所以D3D对其不再进行投影变换,猜测而已,具体还需验证。float, float, float, float

 

 

 

 

 

 

 

 

#defineDescription
D3DFVF_TEX0 - D3DFVF_TEX80--8层的纹理,让顶点具有纹理坐标的信息
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.

 

#defineDescription
D3DFVF_POSITION_MASKMask for position bits.
D3DFVF_RESERVED0, D3DFVF_RESERVED2Mask values for reserved bits in the FVF. Do not use.
D3DFVF_TEXCOUNT_MASKMask value for texture flag bits.

 

#define

 

 

Description

D3DFVF_LASTBETA_D3DCOLORThe 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_UBYTE4The 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_SHIFTThe 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.

 

在顶点结构体中没有RHW时,Direct3D将执行视、投影、世界等变换以及进行光线计算,之后你才能在窗口中得到你所绘制的物体。当顶点结构体中有RHW时,就像上面那段英文所述,告知Direct3D使用的顶点已经在屏幕坐标系中了,不再执行视图、投影、世界等变换和光线计算,因为D3DFVF_XYZRHW标志告诉它顶点已经经过了这些处理,并直接将顶点进行光栅操作,任何用SetTransform进行的转换都对其无效。不过这时的原点就在客户区的左上角了,其中x向右为正,y向下为正,而z的意义已经变为z-buffer的象素深度。

 

    值得注意的是,D3DFVF_XYZRHW和D3DFVF_XYZ、D3DFVF_NORMAL不能共存,因为后两个标志与前一个矛盾。在使用这种顶点时,系统需要顶点的位置已经经过变换了,也就是说x、y必须在屏幕坐标系中,z必须是z-buffer中的象素深度,取值范围:0.0-1.0,离观察者最近的地方为0.0,观察范围内最远可见的地方为1.0。(不过我测试的时候似乎z值不起作用。)引自:http://www.cppblog.com/lovedday/archive/2009/03/22/48507.html

 

在定义完顶点格式以后,就要开辟一块顶点缓冲区:

g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),

                                                  0, D3DFVF_CUSTOMVERTEX,

                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) 

 

开辟缓冲区后,就需要对这个缓冲区进行填写,那么填写的数据呢,也需要先指定出来:

 

CUSTOMVERTEX vertices[] =

    {

{ 100.0f, 400.0f, 0.5f, 1.0f, 0xffff0000, },

        { 300.0f,  50.0f, 0.5f, 1.0f, 0xff00ff00, }, 

        { 500.0f, 400.0f, 0.5f, 1.0f, 0xff0000ff, },

    };

然后将数据写入缓冲区:

VOID* pVertices;

    if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )

        return E_FAIL;

    memcpy( pVertices, vertices, sizeof(vertices) );

    g_pVB->Unlock();

 

这里写入的过程用的是Lock函数得到的缓冲区的地址,然后用memcpy函数将自己写好的数据写进去。到这里,顶点就算是创建好了。

 

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值