基于DIRECTX的3D粒子系统构建(2)

来源:互联网 发布:克洛普 知乎 编辑:程序博客网 时间:2024/06/05 16:26

 

三、在DIRECTX9.0环境下粒子系统的实现

 

       这一节,笔者将会介绍在DIRECTX9.0环境下如何实现一个简单的粒子系统,并着重对Point Sprites粒子类型作详细说明。

1Point Sprites粒子结构

 

       首先来看一个Point Sprites粒子是如何定义的:

       //一个Point Sprites粒子的顶点结构

       typedef struct

{

       MyVector position; //位置

       D3DCOLOR color; //颜色

}POINTSPRITEVERTEX, *LPPOINTSPRITEVERTEX;

 

 

//一个Point Sprites的结构

typedef struct

 

{

 

    char *TexName; //贴图名称

 

    float size;     //大小

 

    POINTSPRITEVERTEX pointspritevertex; //顶点数据

 

    LPDIRECT3DVERTEXBUFFER9 lpVertexBuffer; //顶点填充BUFFER

 

    MY_MATRIX   TM;         //粒子的世界变换矩阵

 

}POINTSPRITE, *LPPOINTSPRITE;

 

 

 

 

 

2Point Sprites粒子的渲染状态

 

 

 

pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, true);

 

D3DRS_POINTSPRITEENABLE这个渲染状态,当设置为true时,贴图会完全贴上Point Sprites粒子;如果设置为false,那么,当粒子的顶点结构中有UV坐标时贴图才有效,并且根据不同粒子的UV坐标贴到不同的位置。

 

 

pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, true);

 

D3DRS_POINTSCALEENABLE这个渲染状态,当设定为true时,粒子的大小会受摄象机位置的影响,也就是有正确的透视关系,摄象机离这个粒子越远,粒子越小;如果设置为false,那么粒子将不受摄象机位置的影响,如果这时你设定粒子大小为3,那么这个粒子将始终占据3*3象素大小的屏幕面积。

 

 

pd3dDevice->SetRenderState(D3DRS_POINTSIZE, FtoDw(fScale));

 

D3DRS_POINTSIZE设定粒子的大小(视D3DRS_POINTSCALEENABLE设置的不同,有可能是屏幕大小也有可能是摄象机空间大小)。这个大小是从POINTSPRITESIZE变量获得。需要注意的是必须把变量转换为DWORD

 

 

 

pd3dDevice->SetRenderState(D3DRS_POINTSIZE_MIN, FtoDw(0.0f));

 

D3DRS_POINTSIZE_MIN设定粒子的最小大小,这里设为0,并同样转换为DWORD传入。

 

 

pd3dDevice->SetRenderState(D3DRS_POINTSIZE_MIN, FtoDw(10.0f));

 

D3DRS_POINTSIZE_MIN设定粒子的最大大小,这里设为10,并转换为DWORD传入。

 

 

D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C

 

这三个参数定义当摄象机移动时粒子的大小该如何变化。Direct3D采用以下公式计算粒子的最终显示大小:

 

 

其中:ViewportHeight是视口的高度,SIZED3DRS_POINTSIZE设定的大小,ABCD3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C这三个参数设定的大小,D是粒子离摄象机的距离。

 

这个大小的计算是曾经困扰笔者的一个难点,如果要详细了解这样设置的意义…….问微软的人去!

 

 

不过,对于简单的应用没那么麻烦,按下面的设置你能得到正确的效果:

// control the size of the particle relative to distance

pd3dDevice->SetRenderState(D3DRS_POINTSCALE_A, FtoDw(0.0f));

pd3dDevice->SetRenderState(D3DRS_POINTSCALE_B, FtoDw(0.0f));

pd3dDevice->SetRenderState(D3DRS_POINTSCALE_C, FtoDw(1.0f));

 

 

上面我们介绍了基本Point Sprites粒子的结构和渲染过程(部分翻译自《Introduction.to.3D.Game.Programming.with.DirectX.9.0》一书),可以说我们已经有了一些威力巨大的子弹,下面我们看看枪是怎么制作的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击