用DirectX实现粒子系统(二)
引言
上一篇讲了点精灵的理论部分,这篇看一下如何在DX程序中使用点精灵。
定义顶点格式
为了简化程序,我们使用LT(Lit and transformed format)顶点格式,也就是不需要额外的光照和变换。
// 点精灵对应的顶点
struct POINTVERTEX
{
float x, y, z ; // 位置
D3DCOLOR color; // 颜色
};
// 点的格式是经过光照和变换的,无需设置光照和变换矩阵
#define D3DFVF_POINTVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
struct POINTVERTEX
{
float x, y, z ; // 位置
D3DCOLOR color; // 颜色
};
// 点的格式是经过光照和变换的,无需设置光照和变换矩阵
#define D3DFVF_POINTVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
创建顶点及顶点缓冲区
这里首先创建九个顶点,每行三个,三行的颜色分别是红绿蓝。然后创建一个顶点缓冲区,最后将顶点拷贝的顶点缓冲区中。
HRESULT CreateVertex() { POINTVERTEX points[] = { {-5.0f, 5.0f, 0.0f, 0xffff0000}, { 0.0f, 5.0f, 0.0f, 0xffff0000}, { 5.0f, 5.0f, 0.0f, 0xffff0000}, {-5.0f, 0.0f, 0.0f, 0xff00ff00}, { 0.0f, 0.0f, 0.0f, 0xff00ff00}, { 5.0f, 0.0f, 0.0f, 0xff00ff00}, {-5.0f, -5.0f, 0.0f, 0xff0000ff}, { 0.0f, -5.0f, 0.0f, 0xff0000ff}, { 5.0f, -5.0f, 0.0f, 0xff0000ff} } ; // 创建 Vertex buffer if (FAILED(g_pd3dDevice->CreateVertexBuffer( NUM_VERTEX *sizeof(POINTVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY | D3DUSAGE_POINTS, D3DFVF_POINTVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL))) { return E_FAIL ; } // 拷贝顶点到Vertex buffer中 VOID* pVertices; if( FAILED( g_pVB->Lock( 0, sizeof(points), (void**)&pVertices, 0 ) ) ) return E_FAIL; memcpy( pVertices, points, sizeof(points) ); g_pVB->Unlock(); }
渲染
渲染主要分三步,首先设置一系列渲染状态,比如开启Blend,因为我们用到了纹理,所以要使用纹理混合功能,最重要的两个渲染状态分别是D3DRS_POINTSPRITEENABLE和D3DRS_POINTSCALEENABLE,前者启用点精灵,后者使点精灵可缩放。然后是渲染部分,渲染的类型是POINTLIST。最后部分是恢复前面设置的某些状态,比如禁用Blend。
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { // 设置渲染状态 g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); // 开启Blend g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE ); g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); g_pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE) ; g_pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE) ; g_pd3dDevice->SetRenderState( D3DRS_POINTSIZE, FtoDW(0.2f) ); // 点大小 // 设置纹理,纹理之前已经创建好 g_pd3dDevice->SetTexture(0, g_pTexture) ; // 绘制points g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(POINTVERTEX)); g_pd3dDevice->SetFVF(D3DFVF_POINTVERTEX) ; g_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, NUM_VERTEX) ; // 禁用Blend g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); g_pd3dDevice->EndScene(); }
效果图
为什么说点精灵是高效的呢,拿上面的图来说,我只使用了9个顶点,每个顶点配一个纹理图片。如果不使用点精灵儿直接贴图,那么至少需要4*9=36个顶点。可见点精灵是十分节省内存资源的。
Happy Coding!!!
== THE END ==
作者:zdd
出处:http://www.cnblogs.com/graphics/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述