/头文件/
#pragma once
#include "Node.h"
struct WaterUpVertex
{
float x, y, z;
float tu, tv;
enum FVF
{
FVF_Flags = D3DFVF_XYZ | D3DFVF_TEX1
};
};
struct WaterDownVertex
{
float x, y, z;
float nx, ny, nz;
enum FVF
{
FVF_Flags = D3DFVF_XYZ | D3DFVF_NORMAL
};
};
class Water : public CNode
{
public:
LPDIRECT3DVERTEXBUFFER9 m_pWaterDownVB;//材质面顶点缓冲
LPDIRECT3DINDEXBUFFER9 m_pWaterDownIB;//材质面索引缓冲
LPDIRECT3DTEXTURE9 m_pWaterTextures[30];//贴图面纹理数组
WaterUpVertex m_WaterUpVertices[4];//贴图面顶点数组
LPDIRECT3DDEVICE9 m_pDevice;
float m_fWidth;//水面尺寸
float m_fLength;
float m_fTileLength;//水面单元格大小s
UINT m_uiNumXTile;//单元格行数
UINT m_uiNumYTile;//单元格列数
UINT m_uiNumTiles;//单元格总数
UINT m_uiNumVertices;//材质面顶点数
UINT m_uiNumIndices;//材质面索引数
UINT m_uiNumXWrap;//贴图面U向贴图数
UINT m_uiNumYWrap;//贴图面V向贴图数
UINT m_iCurrenrtFrame;//显示帧的当前帧
UINT m_fLifeTime;//换帧计时器
D3DMATERIAL9 m_WaterMaterial;
Water(void);
~Water(void);
// @param fWidth 水面的宽度
// @param fLength 水面的长度
// @param fTileLength 下层水面的格子长度
// @param uiNumWrap 上层水面的纹理包装次数
void Init(float fWidth, float fLength, float fTileLength, UINT uiNumXWrap,
UINT uiNumYWrap, TCHAR* pWaterPrefix,float height ,LPDIRECT3DDEVICE9 pDevice );
void Render( float fElapsedTime ); //换帧时间
};
///
源文件///
#include "StdAfx.h"
#include "Water.h"
Water::Water(void)
{
m_pWaterDownVB=NULL;
m_pWaterDownIB=NULL;
m_pDevice=NULL;
m_uiNumXTile=0;
m_uiNumYTile=0;
m_uiNumTiles=0;
m_uiNumVertices=0;
m_uiNumIndices=0;
m_fTileLength=0.f;
m_fWidth=0.f;
m_fLength=0.f;
m_uiNumXWrap=0;
m_uiNumYWrap=0;
m_iCurrenrtFrame=0;
m_fLength=0;
}
Water::~Water(void)
{
for( int i = 0; i < 30; ++i )
{
SAFE_RELEASE(m_pWaterTextures[i]);
}
SAFE_RELEASE(m_pWaterDownVB);
SAFE_RELEASE(m_pWaterDownIB);
}
void Water::Init(float fWidth, float fLength, float fTileLength, UINT uiNumXWrap,
UINT uiNumYWrap, TCHAR* pWaterPrefix,float height, LPDIRECT3DDEVICE9 pDevice )
{
m_pDevice = pDevice;
m_fWidth = fWidth;
m_fLength = fLength;
m_fTileLength = fTileLength;
m_uiNumXTile = (UINT)(m_fWidth / m_fTileLength);
m_uiNumYTile = (UINT)(m_fLength / m_fTileLength);
m_uiNumTiles = m_uiNumXTile * m_uiNumYTile;
m_uiNumVertices = m_uiNumTiles * 4;
m_uiNumIndices = m_uiNumTiles * 6;
m_uiNumXWrap = uiNumXWrap;
m_uiNumYWrap = uiNumYWrap;
for( int i = 0; i < 30; ++i )//图片的相关信息
{
TCHAR cWaterIdx[255];
wsprintf(cWaterIdx,_T("%s%d.tga"),pWaterPrefix,i+1);//%s:pWaterPrefix %d:i+1
D3DXCreateTextureFromFile( pDevice, cWaterIdx, &m_pWaterTextures[i] );
}
//水面贴图面4个顶点的初始化
float fHalfWidth = m_fWidth * 0.5f;
float fHalfLength = m_fLength * 0.5f;
m_WaterUpVertices[0].x = m_pos.x-fHalfWidth;
m_WaterUpVertices[0].y = height;
m_WaterUpVertices[0].z = m_pos.y-fHalfLength;
m_WaterUpVertices[0].tu = 0.f;
m_WaterUpVertices[0].tv = (float)m_uiNumYWrap;
m_WaterUpVertices[1].x = m_pos.x+fHalfWidth;
m_WaterUpVertices[1].y = height;
m_WaterUpVertices[1].z = m_pos.y-fHalfLength;
m_WaterUpVertices[1].tu = (float)m_uiNumXWrap;
m_WaterUpVertices[1].tv = (float)m_uiNumYWrap;
m_WaterUpVertices[2].x = m_pos.x-fHalfWidth;
m_WaterUpVertices[2].y = height;
m_WaterUpVertices[2].z = m_pos.y+fHalfLength;
m_WaterUpVertices[2].tu = 0.f;
m_WaterUpVertices[2].tv = 0.f;
m_WaterUpVertices[3].x = m_pos.x+fHalfWidth;
m_WaterUpVertices[3].y = height;
m_WaterUpVertices[3].z = m_pos.y+fHalfLength;
m_WaterUpVertices[3].tu = (float)m_uiNumXWrap;
m_WaterUpVertices[3].tv = 0.f;
m_pDevice->CreateVertexBuffer( m_uiNumVertices * sizeof(WaterDownVertex), D3DUSAGE_WRITEONLY,
WaterDownVertex::FVF_Flags,D3DPOOL_DEFAULT, &m_pWaterDownVB,NULL );
m_pDevice->CreateIndexBuffer( m_uiNumIndices * sizeof(WORD), D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pWaterDownIB, NULL );
WaterDownVertex *pWaterDownVertices = NULL;
m_pWaterDownVB->Lock( 0, m_uiNumVertices * sizeof(WaterDownVertex), (void**)&pWaterDownVertices, 0 );
//材质面的顶点初始化
UINT uiIndex = 0;
for( UINT y = 0; y < m_uiNumYTile; ++y )
{
for( UINT x = 0; x < m_uiNumXTile; ++x )
{
pWaterDownVertices[uiIndex].x = m_pos.x-fHalfWidth + m_fTileLength * x;
pWaterDownVertices[uiIndex].y = height-0.1f;
pWaterDownVertices[uiIndex].z = m_pos.y-fHalfLength + m_fTileLength * y;
pWaterDownVertices[uiIndex].nx = 0.f;
pWaterDownVertices[uiIndex].ny = 1.f;
pWaterDownVertices[uiIndex].nz = 0.f;
uiIndex++;
pWaterDownVertices[uiIndex].x = m_pos.x-fHalfWidth + m_fTileLength * (x+1);
pWaterDownVertices[uiIndex].y = height-0.1f;
pWaterDownVertices[uiIndex].z = m_pos.y-fHalfLength + m_fTileLength * y;
pWaterDownVertices[uiIndex].nx = 0.f;
pWaterDownVertices[uiIndex].ny = 1.f;
pWaterDownVertices[uiIndex].nz = 0.f;
uiIndex++;
pWaterDownVertices[uiIndex].x = m_pos.x-fHalfWidth + m_fTileLength * x;
pWaterDownVertices[uiIndex].y = height-0.1f;
pWaterDownVertices[uiIndex].z = m_pos.y-fHalfLength + m_fTileLength * (y+1);
pWaterDownVertices[uiIndex].nx = 0.f;
pWaterDownVertices[uiIndex].ny = 1.f;
pWaterDownVertices[uiIndex].nz = 0.f;
uiIndex++;
pWaterDownVertices[uiIndex].x = m_pos.x-fHalfWidth + m_fTileLength * (x+1);
pWaterDownVertices[uiIndex].y = height-0.1f;
pWaterDownVertices[uiIndex].z = m_pos.y-fHalfLength + m_fTileLength * (y+1);
pWaterDownVertices[uiIndex].nx = 0.f;
pWaterDownVertices[uiIndex].ny = 1.f;
pWaterDownVertices[uiIndex].nz = 0.f;
uiIndex++;
}
}
m_pWaterDownVB->Unlock();
//定制材质面索引信息
WORD *pIndices = NULL;
m_pWaterDownIB->Lock( 0, sizeof(WORD) * m_uiNumIndices, (void**)&pIndices, 0 );
for(
unsigned short idx, idxOff, i = 0;
i < m_uiNumTiles;
++i )
{
idx = i * 6;
idxOff = i * 4;
pIndices[idx] = idxOff + 0;
pIndices[idx+1] = idxOff + 3;
pIndices[idx+2] = idxOff + 1;
pIndices[idx+3] = idxOff + 0;
pIndices[idx+4] = idxOff + 2;
pIndices[idx+5] = idxOff + 3;
}
m_pWaterDownIB->Unlock();
//材质面的材质(全材质)
ZeroMemory(&m_WaterMaterial , sizeof(D3DMATERIAL9));//初始化m_WaterMaterial数组里的值
m_WaterMaterial.Diffuse.r = 1.f;
m_WaterMaterial.Diffuse.g = 1.f;
m_WaterMaterial.Diffuse.b = 1.f;
m_WaterMaterial.Ambient.r = 1.f;
m_WaterMaterial.Ambient.g = 1.f;
m_WaterMaterial.Ambient.b = 1.f;
m_WaterMaterial.Specular.r = 1.f;
m_WaterMaterial.Specular.g = 1.f;
m_WaterMaterial.Specular.b = 1.f;
}
void Water::Render( float fElapsedTime )
{
D3DXMATRIX matWorld;
m_pDevice->SetMaterial( &m_WaterMaterial );
m_pDevice->SetTransform( D3DTS_WORLD, &matWorld );
//第一次ALPHA混合(材质面,混合参数为1)
m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
//绘制材质面
m_pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
m_pDevice->SetRenderState( D3DRS_AMBIENT, 0xff555555 );
D3DXMatrixIdentity( &matWorld );
m_pDevice->SetTransform( D3DTS_WORLD, &matWorld );
m_pDevice->SetStreamSource( 0, m_pWaterDownVB, 0, sizeof(WaterDownVertex) );
m_pDevice->SetIndices( m_pWaterDownIB );
m_pDevice->SetTexture( 0, 0 );
m_pDevice->SetFVF( WaterDownVertex::FVF_Flags );
//贴图面的绘制
m_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_uiNumTiles*4,0, m_uiNumTiles*2 );//关闭光照,以便做第2次ALPHA混哈
m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
m_pDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
//帧切换
m_fLifeTime++;
if (m_fLifeTime>fElapsedTime)
{
m_fLifeTime=0;
m_iCurrenrtFrame++;
if (m_iCurrenrtFrame>29)
{
m_iCurrenrtFrame=0;
}
}
D3DXMatrixIdentity( &matWorld );
m_pDevice->SetTransform( D3DTS_WORLD, &matWorld );
m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
//第2次ALPHA混合(混合参数为1-SOURCEALPHA,SOURCEALPHA,光照已关闭)
m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA );
m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA );
m_pDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
m_pDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
//UV贴图模式,默认为WARP
m_pDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
m_pDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
m_pDevice->SetTexture( 0,m_pWaterTextures[m_iCurrenrtFrame] );
m_pDevice->SetFVF( WaterUpVertex::FVF_Flags );
m_pDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, m_WaterUpVertices, sizeof(WaterUpVertex) );
m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
}