📄 water.cpp
字号:
//--------------------------------------------------
// Desc: 类似WOW的水特效
// Author: artsylee/2007.3.12
//--------------------------------------------------
#include "Water.h"
#include "Common.h"
#include "ase/ASEngine.h"
CWater::CWater()
{
SetNodeType(NT_WATER);
for(int i=0; i<30; i++)
m_hTex[i] = INVALID_HANDLE;
m_LastUpdate = 0;
m_CurFrame = 0;
m_eWaterType = WT_INVALID;
m_fWidth = 0;
m_fLength = 0;
m_NumXWrap = 0;
m_NumYWrap = 0;
m_pHighLightVB = NULL;
m_pHighLightIB = NULL;
m_nXTile = 0;
m_nYTile = 0;
m_nVertices = 0;
m_nIndices = 0;
m_fTileSize = 0;
}
CWater::~CWater()
{
for(int i=0; i<30; i++)
{
ReleaseTexture(m_hTex[i]);
}
if(m_pHighLightVB)
{
m_pHighLightVB->Release();
m_pHighLightVB = NULL;
}
if(m_pHighLightIB)
{
m_pHighLightIB->Release();
m_pHighLightIB = NULL;
}
}
void CWater::InitWater()
{
m_fWidth = 500.0f;
m_fLength = 580.0f;
m_NumXWrap = 2;
m_NumYWrap = 2;
if(m_pHighLightVB)
{
m_pHighLightVB->Release();
m_pHighLightVB = NULL;
}
if(m_pHighLightIB)
{
m_pHighLightIB->Release();
m_pHighLightIB = NULL;
}
for(int i=0; i<15; i++)
{
if(m_hTex[i]>INVALID_HANDLE)
ReleaseTexture(m_hTex[i]);
m_hTex[i] = g_pTextureManager->LoadAMFTexture("Picture\\lake.amf", i);
}
m_eWaterType = WT_HIGHLIGHT;
SetScale(D3DXVECTOR3(1.0f, 1.0f, 1.0f));
SetPosition(D3DXVECTOR3(525, 144/*+70*/, 3661));
// 不直接设置方向, 通过旋转方式设置
SetRotateY(0.0f);
UpdateFromParent();
FillWaterVertex();
if(m_eWaterType == WT_HIGHLIGHT)
{
m_fTileSize = 20.0f;
if(m_fTileSize == 0.0f) m_fTileSize = 1.0f;
m_nXTile = (int)(m_fWidth / m_fTileSize);
m_nYTile = (int)(m_fLength / m_fTileSize);
m_nVertices = (m_nXTile+1) * (m_nYTile+1);
m_nIndices = m_nXTile*m_nYTile*6;
// 高光网格材质
ZeroMemory(&m_HighLightMaterial, sizeof(D3DMATERIAL9));
m_HighLightMaterial.Ambient.r = 0.6f;
m_HighLightMaterial.Ambient.g = 0.6f;
m_HighLightMaterial.Ambient.b = 0.6f;
m_HighLightMaterial.Ambient.a = 0.0f;
m_HighLightMaterial.Diffuse.r = 0.1f;
m_HighLightMaterial.Diffuse.g = 0.1f;
m_HighLightMaterial.Diffuse.b = 0.1f;
m_HighLightMaterial.Diffuse.a = 1.0f;
m_HighLightMaterial.Specular.r = 1.0f;
m_HighLightMaterial.Specular.g = 1.0f;
m_HighLightMaterial.Specular.b = 1.0f;
m_HighLightMaterial.Specular.a = 1.0f;
m_HighLightMaterial.Power = 6.5f;
FillHighLightVertex();
}
}
void CWater::FillWaterVertex()
{
/*
// 图示 0-1-2-3
-------------------------------------------
1-----3
| \ | Z
| \ | |
| \ | |
0-----2 ------ X
-------------------------------------------
*/
float fHalfWidth = 0.5f * m_fWidth;
float fHalfLength = 0.5f * m_fLength;
m_WaterVertices[0].x = -fHalfWidth;
m_WaterVertices[0].y = 0.0f;
m_WaterVertices[0].z = -fHalfLength;
m_WaterVertices[0].nx = 0.0f;
m_WaterVertices[0].ny = 1.0f;
m_WaterVertices[0].nz = 0.0f;
m_WaterVertices[0].tu = 0.0f;
m_WaterVertices[0].tv = (float)m_NumYWrap;
m_WaterVertices[1].x = -fHalfWidth;
m_WaterVertices[1].y = 0.0f;
m_WaterVertices[1].z = fHalfLength;
m_WaterVertices[1].nx = 0.0f;
m_WaterVertices[1].ny = 1.0f;
m_WaterVertices[1].nz = 0.0f;
m_WaterVertices[1].tu = 0.0f;
m_WaterVertices[1].tv = 0.0f;
m_WaterVertices[2].x = fHalfWidth;
m_WaterVertices[2].y = 0.0f;
m_WaterVertices[2].z = -fHalfLength;
m_WaterVertices[2].nx = 0.0f;
m_WaterVertices[2].ny = 1.0f;
m_WaterVertices[2].nz = 0.0f;
m_WaterVertices[2].tu = (float)m_NumXWrap;
m_WaterVertices[2].tv = (float)m_NumYWrap;
m_WaterVertices[3].x = fHalfWidth;
m_WaterVertices[3].y = 0.0f;
m_WaterVertices[3].z = fHalfLength;
m_WaterVertices[3].nx = 0.0f;
m_WaterVertices[3].ny = 1.0f;
m_WaterVertices[3].nz = 0.0f;
m_WaterVertices[3].tu = (float)m_NumXWrap;
m_WaterVertices[3].tv = 0.0f;
}
void CWater::FillHighLightVertex()
{
/*
// 图示0-2-3 0-3-1
-------------------------------------------
2-----3
| /| Z
| / | |
|/ | |
0-----1 ------ X
-------------------------------------------
*/
float fHalfWidth = 0.5f * m_fWidth;
float fHalfLength = 0.5f * m_fLength;
g_pD3DDevice->CreateVertexBuffer(m_nVertices * sizeof(HighLightVertex), D3DUSAGE_WRITEONLY,
HighLightVertex::FVF_Flags, D3DPOOL_MANAGED, &m_pHighLightVB, NULL);
g_pD3DDevice->CreateIndexBuffer(m_nIndices * sizeof(WORD), D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pHighLightIB, NULL);
HighLightVertex *pWaterDownVertices = NULL;
m_pHighLightVB->Lock(0, m_nVertices*sizeof(HighLightVertex), (void**)&pWaterDownVertices, 0);
int iIndex = 0;
for(int y=0; y<=m_nYTile; y++)
{
for(int x=0; x<=m_nXTile; x++)
{
pWaterDownVertices[iIndex].x = -fHalfWidth + m_fTileSize * x;
pWaterDownVertices[iIndex].y = -0.1f;
pWaterDownVertices[iIndex].z = -fHalfLength + m_fTileSize * y;
pWaterDownVertices[iIndex].nx = 0.0f;
pWaterDownVertices[iIndex].ny = 1.0f;
pWaterDownVertices[iIndex].nz = 0.0f;
iIndex++;
}
}
m_pHighLightVB->Unlock();
WORD *pIndices = NULL;
m_pHighLightIB->Lock(0, sizeof(WORD)*m_nIndices, (void**)&pIndices, 0);
iIndex = 0;
for(int y=0; y<m_nYTile; y++)
{
for(int x=0; x<m_nXTile; x++)
{
pIndices[iIndex*6+0] = y * (m_nXTile+1) + x;
pIndices[iIndex*6+1] = (y+1) * (m_nXTile+1) + x;
pIndices[iIndex*6+2] = (y+1) * (m_nXTile+1) + x+1;
pIndices[iIndex*6+3] = y * (m_nXTile+1) + x;
pIndices[iIndex*6+4] = (y+1) * (m_nXTile+1) + x+1;
pIndices[iIndex*6+5] = y * (m_nXTile+1) + x+1;
iIndex++;
}
}
m_pHighLightIB->Unlock();
}
void CWater::Render()
{
if(m_eWaterType == WT_INVALID)
return;
D3DXMATRIX matTrans;
GetWorldTransform(&matTrans);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matTrans);
g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pD3DDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
g_pD3DDevice->LightEnable(0, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
if(m_eWaterType == WT_HIGHLIGHT)
{
// 高光网格
g_pD3DDevice->SetTexture(0, NULL);
g_pD3DDevice->SetMaterial(&m_HighLightMaterial);
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pD3DDevice->SetStreamSource(0, m_pHighLightVB, 0, sizeof(HighLightVertex));
g_pD3DDevice->SetIndices(m_pHighLightIB);
g_pD3DDevice->SetFVF(HighLightVertex::FVF_Flags);
g_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_nVertices, 0, m_nIndices/3);
}
// 动画序列帧
if(g_GlobalTime - m_LastUpdate>=300)
{
m_LastUpdate = g_GlobalTime;
m_CurFrame++;
if(m_CurFrame>=15)
{
m_CurFrame = 0;
}
}
// 水动画
SET_TEXTURE_TYPE(0, m_hTex[m_CurFrame]);
if(m_eWaterType == WT_HIGHLIGHT)
{
// 水的颜色
g_pD3DDevice->SetRenderState(D3DRS_TEXTUREFACTOR, MakeARGB(0xff, 88, 117, 133));
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
}
g_pD3DDevice->SetFVF(WaterVertex::FVF_Flags);
g_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, m_WaterVertices, sizeof(WaterVertex));
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pD3DDevice->LightEnable(0, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -