水纹特效vc++源码

 /头文件/

#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);

}

猜你喜欢

转载自blog.csdn.net/zhengjian1996/article/details/112917166