📄 zwater.cpp
字号:
#include "ZWater.h"
ZWater::ZWater()
{
m_pDev = NULL;
m_pVB = NULL;
m_pIB = NULL;
m_cx = m_cz = 0;
m_nWaveTick = 0;
m_fWave = 0.0f;
m_fDir = 0.1f;
m_nPrevTick = GetTickCount();
m_pTexWater[0] = NULL;
m_pTexWater[1] = NULL;
}
ZWater::~ZWater()
{
S_REL( m_pTexWater[0] );
S_REL( m_pTexWater[1] );
S_REL( m_pVB );
}
// 创建水网格
int ZWater::Create( LPDIRECT3DDEVICE9 pDev, int cx, int cz, int nSpeed )
{
m_pDev = pDev;
m_cx = cx;
m_cz = cz;
m_nWaveTick = nSpeed;
_LoadTextures();
_CreateVIB();
return 1;
}
// 用于表现水的两层纹理
int ZWater::_LoadTextures()
{
D3DXCreateTextureFromFile( m_pDev, "water1.bmp", &m_pTexWater[0] );
D3DXCreateTextureFromFile( m_pDev, "water2.bmp", &m_pTexWater[1] );
return 1;
}
// 创建四边形顶点缓冲
// 现在,输出几次四边形网格,这是效率非常低的方法.
// 最好创建可以表现水整体的大顶点缓冲(或是网格).
int ZWater::_CreateVIB()
{
WATERVERTEX vtx[4] =
{
{ -0.5f, 0.0f, -0.5f, 0x7fffffff, 0.0f, 1.0f },
{ -0.5f, 0.0f, 0.5f, 0x7fffffff, 0.0f, 0.0f },
{ 0.5f, 0.0f, -0.5f, 0x7fffffff, 1.0f, 1.0f },
{ 0.5f, 0.0f, 0.5f, 0x7fffffff, 1.0f, 0.0f }
};
if( FAILED( m_pDev->CreateVertexBuffer( 4 * sizeof(WATERVERTEX),
0, WATERVERTEX::FVF,
D3DPOOL_DEFAULT, &m_pVB, NULL ) ) )
return 0;
WATERVERTEX* pV;
if( FAILED( m_pVB->Lock( 0, 4 * sizeof(WATERVERTEX), (void**)&pV, 0 ) ) )
return E_FAIL;
memcpy( pV, vtx, 4 * sizeof(WATERVERTEX) );
m_pVB->Unlock();
return 1;
}
// 纹理动画
int ZWater::_WaveTexture()
{
D3DXMATRIXA16 matTex;
D3DXMatrixIdentity( &matTex );
int nCurrTick = GetTickCount();
if( (nCurrTick - m_nPrevTick) > m_nWaveTick )
{
// 设置纹理动画
m_fWave += m_fDir;
if( m_fWave > (D3DX_PI/8.0f) ) m_fDir = -0.01f;
if( m_fWave < (-D3DX_PI/8.0f) ) m_fDir = 0.01f;
// 0号纹理阶段的纹理与纹理变换矩阵相乘(D3DTS_TEXTURE0).
m_pDev->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
// 1号纹理阶段的纹理与纹理变换矩阵相乘(D3DTS_TEXTURE1).
m_pDev->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
// 设定0号纹理变换矩阵
D3DXMatrixRotationX( &matTex, m_fWave );
m_pDev->SetTransform( D3DTS_TEXTURE0, &matTex );
// 设定1号纹理变换矩阵
D3DXMatrixRotationY( &matTex, m_fWave );
m_pDev->SetTransform( D3DTS_TEXTURE1, &matTex );
}
return 1;
}
int ZWater::Draw()
{
float x, z;
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity( &matWorld );
_WaveTexture();
m_pDev->SetTexture( 0, m_pTexWater[0] );
m_pDev->SetTexture( 1, m_pTexWater[1] );
m_pDev->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); // 0号纹理 : 使用0号纹理索引
m_pDev->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 ); // 1号纹理 : 使用1号纹理索引
m_pDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pDev->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pDev->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pDev->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
m_pDev->SetSamplerState( 1, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );
m_pDev->SetStreamSource( 0, m_pVB, 0, sizeof(WATERVERTEX) );
m_pDev->SetFVF( WATERVERTEX::FVF );
// 循环,绘制网格.
// 如上所述,绘制网格是最坏的算法.
// 最好是更有效一些.
// 我选择了更好的算法.
for( z = 0.0f ; z < (float)m_cz ; z++ )
{
for( x = 0.0f ; x < (float)m_cx ; x++ )
{
matWorld._41 = x - m_cx/2.0f;
matWorld._43 = -((float)z-m_cz/2.0f);
m_pDev->SetTransform( D3DTS_WORLD, &matWorld );
m_pDev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
}
}
D3DXMatrixIdentity( &matWorld );
m_pDev->SetTransform( D3DTS_WORLD, &matWorld );
m_pDev->SetTransform( D3DTS_TEXTURE0, &matWorld );
m_pDev->SetTransform( D3DTS_TEXTURE1, &matWorld );
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -