游戏程序
平台类型: | PC/兼容机 |
---|
程序设计: | 客户端 3D图形 |
---|
编程语言: | C/C++ |
---|
引擎/SDK: | DirectX |
---|
一. 公告板的应用: 公告板可被用于场景中对细节要求不高的树木花草,也可用于玩家头顶的某些特效表现等。其好处自然是高效简洁。 二. 公告板基本原理: 公告板最基本的原理就是,绘制一个带贴图的矩形区域,由阿尔法混合使贴图看起来更逼真,并且保证每帧矩形都是正对摄像机,从而在效果上表现出贴图中的对象。 由于只绘制了一个矩形因此其绘制的性能很高。 三. 公告板实现方式及相关代码: 由公告板的基本原理可以将其实现归纳为以下步骤: 1. 初始化公告板矩形并将其放置到场景中 2. 每帧根据当前相机位置在XZ平面旋转矩阵保证其正对摄像机(当相机可绕UP方向移动旋转时会导致公告板穿帮,此时需要其他手段来解决。) 3. 绘制矩形并对其贴图进行阿尔法混合。 具体相关代码如下: 1. 初始化公告板矩形定点信息 a. 定义公告板定点信息 // 公告板定点信息 struct CUSTOMVERTEX { float x, y, z; //顶点位置 float u,v ; //顶点纹理坐标 }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_TEX1) b. 创建定点缓冲区 // 创建定点缓冲 pDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),0, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVertexBuf, NULL ); // 初始化顶点数据 填充顶点缓冲区数据 CUSTOMVERTEX Vertices[] = { { -m_fWidth / 2.0f, -m_fHeigh / 2.0f, 0.0f, 0.0f, 1.0f, }, { -m_fWidth / 2.0f, m_fHeigh / 2.0f, 0.0f, 0.0f, 0.0f, }, { m_fWidth / 2.0f, -m_fHeigh / 2.0f, 0.0f, 1.0f, 1.0f, }, { m_fWidth / 2.0f, m_fHeigh / 2.0f, 0.0f, 1.0f, 0.0f, } }; void* pVertices; if( FAILED( m_pVertexBuf->Lock( 0, sizeof(Vertices), (void**)&pVertices,0 ) ) ) memcpy( pVertices, Vertices, sizeof(Vertices) ); m_pVertexBuf->Unlock(); c. 创建纹理贴图 D3DXCreateTextureFromFileA( pDevice, pTexPath, &m_pTexture ); 2. 每帧根据相机位置旋转公告板 a. 计算相机朝向 VECTOR3 vPos; pCamera->GetPostion( &vPos ); VECTOR3 vLookAt; pCamera->GetLookAt( &vLookAt ); m_vCamera = vLookAt - vPos; b. 更新公告板方向(只计算在XZ平面的方向为了避免失真) float fAngle = 0; if( m_vCamera.x > 0.0f ) fAngle = -atanf(m_vCamera.z/m_vCamera.x)+D3DX_PI/2; else fAngle = -atanf(m_vCamera.z/m_vCamera.x)-D3DX_PI/2; c. 设置旋转矩阵 D3DXMatrixRotationY( &matRotation, fAngle + nIndex * m_nCount / D3DX_PI ); 3. 设置纹理贴图绘制公告板 a. 设置纹理阿尔法混合 pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true ); pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); b. 绘制公告板 pDevice->SetTexture( 0, m_pTexture ); pDevice->SetStreamSource( 0, m_pVertexBuf, 0, sizeof(CUSTOMVERTEX) ); pDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); pDevice->SetTransform( D3DTS_WORLD, &matBillboard ); pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); 四. 效果展示: 公告板 十字交叉公告板 五. 其他: 1. 关于十字交叉公告板: 所谓十字交叉公告板既是在公告板的基础上再将矩形旋转90度,使得两个公告板交叉。十字交叉公告板比单纯公告板表现效果更好。 2. 关于在UP方向旋转相机导致公告板穿帮的问题可以采用在XZ平面增加一个顶部公告板的方式解决。 |
|