⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zwater.cpp

📁 选自《3D游戏编程》第5章 实战例题:3D编程技术的实战例题
💻 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 + -