Files
Client/Engine/Zalla3D Scene Class/WaterW.cpp
LGram16 e067522598 Initial commit: ROW Client source code
Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:24:34 +09:00

554 lines
15 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "WaterW.h"
#include "SceneManager.h"
#include "GMMemory.h"
CWaterW ::CWaterW() {
m_pWaterSpace = NULL;
m_pWaterChangeValue = NULL;
m_pWaterCoord = NULL;
m_nWidthSize = WATERWWIDTH;
m_nHeightSize = WATERWHEIGHT;
m_fLimitHeight = 0.0;
m_nDriftCount = 0;
m_Device = NULL;
m_nChopPower = WATERWCHOP;
m_IndexNum = 0;
m_ZeroPos.x = m_ZeroPos.y = m_ZeroPos.z = 0.0f;
m_QuadSize = 1.0f;
CreateWaterWSpace();
}
CWaterW ::CWaterW(int size,double lh,float chop,float x,float z,float quadsize,LPDIRECT3DDEVICE8 device) {
m_pWaterSpace = NULL;
m_pWaterChangeValue = NULL;
m_pWaterCoord = NULL;
m_nWidthSize = size;
m_nHeightSize = size;
m_fLimitHeight = lh;
m_nDriftCount = 0;
m_nChopPower = chop;
m_Device = device;
m_IndexNum = 0;
m_ZeroPos.x = x;
m_ZeroPos.z = z;
m_QuadSize = quadsize;
CreateWaterWSpace();
CreateTexture();
CreateVertexBuffer();
}
CWaterW ::CWaterW(int w,int h,double lh,float chop,float x,float z,float quadsize,LPDIRECT3DDEVICE8 device){
m_pWaterSpace = NULL;
m_pWaterChangeValue = NULL;
m_pWaterCoord = NULL;
m_nWidthSize = w;
m_nHeightSize = h;
m_fLimitHeight = lh;
m_nDriftCount = 0;
m_nChopPower = chop;
m_Device = device;
m_IndexNum = 0;
m_ZeroPos.x = x;
m_ZeroPos.z = z;
m_QuadSize = quadsize;
CreateWaterWSpace();
CreateTexture();
CreateVertexBuffer();
}
void CWaterW ::SetLimitHeight(double h) {
m_fLimitHeight = h;
}
bool CWaterW ::CreateWaterWSpace() {
int i;
if(!m_nWidthSize || !m_nHeightSize) {
return false;
}
////// mem clear //////
if(m_pWaterSpace != NULL) {
for(i=0;i<m_nWidthSize;i++) {
delete[] m_pWaterSpace[i];
m_pWaterSpace[i] = NULL;
}
delete[] m_pWaterSpace;
m_pWaterSpace = NULL;
}
if(m_pWaterChangeValue != NULL) {
for(i=0;i<m_nWidthSize;i++) {
delete[] m_pWaterChangeValue[i];
m_pWaterChangeValue[i] = NULL;
}
delete[] m_pWaterChangeValue;
m_pWaterChangeValue = NULL;
}
if(m_pWaterCoord != NULL) {
for(i=0;i<m_nWidthSize;i++) {
delete[] m_pWaterCoord[i];
m_pWaterCoord[i] = NULL;
}
delete[] m_pWaterCoord;
m_pWaterCoord = NULL;
}
//////////////////////////////////////////
m_pWaterSpace = new double*[m_nWidthSize];
m_pWaterChangeValue = new double*[m_nWidthSize];
m_pWaterCoord = new double*[m_nWidthSize];
for(i=0;i<m_nWidthSize;i++) {
m_pWaterSpace[i] = new double[m_nHeightSize];
m_pWaterChangeValue[i] = new double[m_nHeightSize];
m_pWaterCoord[i] = new double[m_nHeightSize];
}
// water <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
InitWaterW();
return true;
}
void CWaterW ::InitWaterW() {
int i,j;
for(i=0;i<m_nWidthSize;i++)
for(j=0;j<m_nHeightSize;j++){
m_pWaterSpace[i][j] = 0.0f;
m_pWaterChangeValue[i][j] = 0.0f;//((double)rand()/(double)RAND_MAX-.2)*1;
}
}
void CWaterW ::UpdateWaterW() {
int i,j;
float h;
for(i=1;i<m_nWidthSize-1;i++) {
for(j=1;j<m_nHeightSize-1;j++) {
h = (m_pWaterSpace[j-1][i] + m_pWaterSpace[j+1][i] + m_pWaterSpace[j][i-1] + m_pWaterSpace[j][i+1])/2.0f - m_pWaterChangeValue[j][i];
h -= h/32.0f;
m_pWaterChangeValue[j][i] = h;
}
}
for(i=0;i<m_nWidthSize;i++) {
for(j=0;j<m_nHeightSize;j++) {
float t;
t = m_pWaterSpace[j][i];
m_pWaterSpace[j][i] = m_pWaterChangeValue[j][i];
m_pWaterChangeValue[j][i] = t;
}
}
/*
// <20><>ȣ <20>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><> <20><><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD> <20><><EFBFBD><EFBFBD>ġ <20><><EFBFBD><EFBFBD>
for(i=1;i<m_nWidthSize - 1;i++) {
for(j=1;j<m_nHeightSize - 1;j++) {
m_pWaterChangeValue[i][j] = m_pWaterChangeValue[i][j] -
(m_pWaterSpace[i][j] -
(m_pWaterSpace[i][j-1] +
m_pWaterSpace[i][j+1] +
m_pWaterSpace[i-1][j-1] +
m_pWaterSpace[i-1][j] +
m_pWaterSpace[i+1][j] +
m_pWaterSpace[i+1][j+1])/6 ) * m_nChopPower;
}
}*/
/*
// <20><><EFBFBD><EFBFBD>ġ <20><><EFBFBD><EFBFBD>
for(i=0;i<m_nWidthSize;i++) {
for(j=0;j<m_nHeightSize;j++) {
m_pWaterChangeValue[i][j]=m_pWaterChangeValue[i][j]-_copysign(.01,m_pWaterSpace[i][j]);
m_pWaterChangeValue[i][j]=m_pWaterChangeValue[i][j]*0.99;
m_pWaterSpace[i][j]=m_pWaterSpace[i][j]+m_pWaterChangeValue[i][j];
}
}
*/
}
void CWaterW ::SetHeight(int x,int y,float height) {
m_pWaterSpace[y][x] = height;
}
void CWaterW ::ComputeWaterW() {
int unitnum = m_DriftUnit.size();
int i;
// water<65><72><EFBFBD><EFBFBD><EFBFBD>ȿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> unit <20><> <20><><EFBFBD><EFBFBD> <20><>ŭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
for(i=0;i<unitnum;i++) {
int x,y;
x = (int)m_DriftUnit[i].m_UnitPos.x;
y = (int)m_DriftUnit[i].m_UnitPos.y;
int unitrange = m_DriftUnit[i].m_nUnitRange;
m_pWaterSpace[y][x] = -0.4f;
DeleteDriftUnit(m_DriftUnit[i]);
//m_DriftUnit[i].m_UnitPos.x += m_DriftUnit[i].m_UnitFwd.x;
//m_DriftUnit[i].m_UnitPos.y += m_DriftUnit[i].m_UnitFwd.y;
/* int unitrange = m_DriftUnit[i].m_nUnitRange;
D3DXVECTOR3 pos = m_DriftUnit[i].m_UnitPos;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> water<65><72> <20><><EFBFBD><EFBFBD><EEB3B5> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
int xcenter=(int)(pos.x);
int ycenter=(int)(pos.y)+xcenter/2;
if((xcenter-unitrange)<0)
xcenter=unitrange;
if((xcenter+unitrange)>=m_nWidthSize)
xcenter=m_nWidthSize-unitrange;
if((ycenter-unitrange)<0)
ycenter=unitrange;
if((ycenter+unitrange)>m_nHeightSize)
ycenter=m_nHeightSize-unitrange;
// <20><><EFBFBD><EFBFBD> <20>ֱ<EFBFBD>
int b=ycenter-unitrange;int e=ycenter;
for(i=xcenter-unitrange;i<xcenter+unitrange;i++) {
for(j=b;j<e;j++) {
double force;
D3DXVECTOR3 is(pos.x,pos.y,pos.z);
if(m_pWaterSpace[i][j]>is.y) {
force=(m_pWaterSpace[i][j]-is.y)+m_pWaterChangeValue[i][j];
m_pWaterSpace[i][j]=is.y;
m_pWaterChangeValue[i][j]=m_pWaterChangeValue[i][j]-force*.5;
}
}
if(i<xcenter)
e++;
else
b++;
} */// for(i=xcenter-unitrange;i<xcenter+unitrange;i++)
} //for(i=0;i<unitnum;i++)
unitnum = m_DriftUnit.size();
for(i=0;i<unitnum;i++) {
if(((int)m_DriftUnit[i].m_UnitPos.x >=m_nWidthSize) || ((int)m_DriftUnit[i].m_UnitPos.x <0)) {
DeleteDriftUnit(m_DriftUnit[i]);
}
if(((int)m_DriftUnit[i].m_UnitPos.y >=m_nHeightSize) || ((int)m_DriftUnit[i].m_UnitPos.y <0)) {
DeleteDriftUnit(m_DriftUnit[i]);
}
}
}
void CWaterW ::AddDriftUnit(CDriftUnit tmp_u) {
tmp_u.SetUnitIndex(m_nDriftCount++);
m_DriftUnit.push_back(tmp_u);
}
void CWaterW ::DeleteDriftUnit(CDriftUnit tmp_u) {
int i;
for(i=0;i<(int)m_DriftUnit.size();i++) {
if(m_DriftUnit[i].m_nIndex == tmp_u.m_nIndex) {
m_DriftUnit.erase(m_DriftUnit.begin() + i);
break;
}
}
}
CWaterW ::~CWaterW() {
int i;
////// mem clear //////
if(m_pWaterSpace != NULL) {
for(i=0;i<m_nWidthSize;i++) {
delete[] m_pWaterSpace[i];
m_pWaterSpace[i] = NULL;
}
delete[] m_pWaterSpace;
m_pWaterSpace = NULL;
}
if(m_pWaterChangeValue != NULL) {
for(i=0;i<m_nWidthSize;i++) {
delete[] m_pWaterChangeValue[i];
m_pWaterChangeValue[i] = NULL;
}
delete[] m_pWaterChangeValue;
m_pWaterChangeValue = NULL;
}
if(m_pWaterCoord != NULL) {
for(i=0;i<m_nWidthSize;i++) {
delete[] m_pWaterCoord[i];
m_pWaterCoord[i] = NULL;
}
delete[] m_pWaterCoord;
m_pWaterCoord = NULL;
}
m_WaterVertexBuffer->Release();
m_WaterIndexBuffer->Release();
m_DriftUnit.clear();
}
int CWaterW::CDriftUnit::SetUnitIndex(int n) {
m_nIndex = n;
return m_nIndex;
}
void CWaterW::Render() {
ChangeVertexBuffer();
DWORD zmode,alphamode,cullmode;
D3DXMATRIX view,world,project;
D3DXMATRIX beforeworld;
D3DXMatrixIdentity(&beforeworld);
m_Device->GetTransform(D3DTS_WORLD,&world);
m_Device->SetTransform(D3DTS_WORLD,&beforeworld);
m_Device->GetTransform(D3DTS_VIEW,&view);
m_Device->GetTransform(D3DTS_PROJECTION,&project);
m_Device->GetRenderState(D3DRS_ZWRITEENABLE,&zmode);
m_Device->GetRenderState(D3DRS_ALPHABLENDENABLE,&alphamode);
m_Device->GetRenderState(D3DRS_CULLMODE,&cullmode);
//////////////////
m_Device->SetRenderState(D3DRS_ZWRITEENABLE,FALSE);
m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_Device->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
m_Device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
m_Device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
m_Device->SetRenderState(D3DRS_LIGHTING,TRUE);
m_Device->SetRenderState(D3DRS_ZWRITEENABLE,FALSE);
m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_Device->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
m_Device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
m_Device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
///0//////
//m_Device->SetTextureStageState(0,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
//m_Device->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL);
m_Device->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
m_Device->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
m_Device->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
m_Device->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
m_Device->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_MODULATE);
DWORD env_alpha;
env_alpha = D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f);
m_Device->SetRenderState(D3DRS_TEXTUREFACTOR,env_alpha);
m_Device->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TFACTOR);
m_Device->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_TEXTURE);
m_Device->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
/////////
// Turn on texture-coord generation for cubemapping
m_Device->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR );
m_Device->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 );
// Render the object with the environment-mapped body
m_Device->SetTexture( 0, m_pSkyCubeTex);
//////////////
m_Device->SetStreamSource(0,m_WaterVertexBuffer,sizeof(CWaterVertex));
m_Device->SetIndices(m_WaterIndexBuffer,0);
m_Device->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL);
m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_nWidthSize * m_nHeightSize,0,(m_IndexNum / 3));
m_Device->SetRenderState(D3DRS_ZWRITEENABLE,zmode);
m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE,alphamode);
m_Device->SetRenderState(D3DRS_CULLMODE,cullmode);
// Restore the render states
m_Device->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
m_Device->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
m_Device->SetTransform(D3DTS_WORLD,&world);
}
void CWaterW::CreateVertexBuffer() {
WORD *VertIndex;
int i,j;
int count = 0;
m_Device->CreateVertexBuffer((m_nWidthSize) * (m_nHeightSize) * sizeof(CWaterVertex),0,
D3DFVF_XYZ | D3DFVF_NORMAL,D3DPOOL_DEFAULT,&(m_WaterVertexBuffer));
VertIndex = new WORD[(m_nWidthSize-2) * (m_nHeightSize-2) * 6];
for(i=1;i<(m_nWidthSize -1);i++) {
for(j=1;j<(m_nHeightSize-1);j++) {
VertIndex[count++] = (m_nWidthSize * (i)) + j-1;
VertIndex[count++] = (m_nWidthSize * (i-1)) + j-1;
VertIndex[count++] = (m_nWidthSize * (i)) + j;
VertIndex[count++] = (m_nWidthSize * (i)) + j;
VertIndex[count++] = (m_nWidthSize * (i-1)) + j-1;
VertIndex[count++] = (m_nWidthSize * (i-1)) + j;
//vertIndex[count++] = 1,0 (i,j-1)
//vertIndex[count++] = 0,0 (i-1,j-1)
//vertIndex[count++] = 1,1 (i,j)
//vertIndex[count++] = 1,1 (i,j)
//vertIndex[count++] = 0,0 (i-1,j-1)
//vertIndex[count++] = 0,1 (i-1,j)
}
}
m_IndexNum = count;
m_Device->CreateIndexBuffer((m_nWidthSize-2) * (m_nHeightSize-2) * 6 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&(m_WaterIndexBuffer));
VOID *tmp_buffer;
m_WaterIndexBuffer->Lock(0,(m_nWidthSize-2) * (m_nHeightSize-2) * 6 * sizeof(WORD),(BYTE **)&tmp_buffer,0);
memcpy(tmp_buffer,VertIndex,(m_nWidthSize-2) * (m_nHeightSize-2) * 6 * sizeof(WORD));
m_WaterIndexBuffer->Unlock();
delete[] VertIndex;
}
void CWaterW::ChangeVertexBuffer() {
int i,j;
int count = 0;
CWaterVertex *m_WaterV = new CWaterVertex[(m_nHeightSize) * (m_nWidthSize)];
for(i=0;i<(m_nWidthSize);i++) {
for(j=0;j<(m_nHeightSize);j++) {
//quad setting
//left triangle
m_WaterV[count].x = m_ZeroPos.x + ((float)(j) * m_QuadSize);
m_WaterV[count].y = m_fLimitHeight + m_pWaterSpace[j][i];
m_WaterV[count].z = m_ZeroPos.z + ((float)(i)* m_QuadSize);
//normal
D3DXVECTOR3 tmp1;
D3DXVECTOR3 tmp2;
if((i-1 >=0) && (j-1 >=0)) {
tmp1.x = 0;
tmp1.y = m_pWaterSpace[j][i-1] - m_pWaterSpace[j][i];
tmp1.z = (i-1) - i;
D3DXVec3Normalize(&tmp1,&tmp1);
tmp2.x = (j-1) -j;
tmp2.y = m_pWaterSpace[j-1][i] - m_pWaterSpace[j][i];
tmp2.z = 0;
D3DXVec3Normalize(&tmp2,&tmp2);
D3DXVECTOR3 normal;
D3DXVec3Cross(&normal,&tmp1,&tmp2);
D3DXVec3Normalize(&normal,&normal);
m_WaterV[count].nx = normal.x;
m_WaterV[count].ny = normal.y;
m_WaterV[count].nz = normal.z;
}
else {
m_WaterV[count].nx = 0.0f;
m_WaterV[count].ny = 1.0f;
m_WaterV[count].nz = 0.0f;
}
count++;
}
}
VOID *tmp_buffer;
m_WaterVertexBuffer->Lock(0,(m_nHeightSize)*(m_nWidthSize)*sizeof(CWaterVertex),(BYTE **)&tmp_buffer,0);
memcpy(tmp_buffer,m_WaterV,((m_nHeightSize) * (m_nWidthSize) * sizeof(CWaterVertex)));
m_WaterVertexBuffer->Unlock();
delete[] m_WaterV;
}
bool CWaterW::SetTexture(char *filename,char *envfilename) {
CTexture::SetPath(EFFECTTEXTUREPATH);
if(strlen(filename) >0) {
m_WaterTexture.Load(filename);
}
if(strlen(envfilename) >0) {
m_WaterEnv.Load(envfilename);
return true;
}
return false;
}
// Water Scene <20><>ü <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
void CWaterW ::Update(float x,float y,float z) {
int x_index = (int)( (x - m_ZeroPos.x)/m_QuadSize);
int y_index = (int) ((z - m_ZeroPos.z)/m_QuadSize);
int flag = 0;
if(!(x == 0 && y == 0 && z==0))
if(x_index>= 0 && y_index >=0)
if(x_index <m_nWidthSize && y_index <m_nHeightSize) {
SetHeight(y_index,x_index,m_nChopPower);
flag = 1;
}
if(!flag) {
InitWaterW();
}
UpdateWaterW();
// ComputeWaterW();
}
void CWaterW ::CreateTexture() {
char* szSkyTex[6] = {
"c:\\lobbyxpos.bmp","c:\\lobbyxneg.bmp","c:\\lobbyypos.bmp","c:\\lobbyyneg.bmp","c:\\lobbyzneg.bmp","c:\\lobbyzpos.bmp"
};
for(int i = 0; i < 6; i++) {
D3DXCreateTextureFromFileEx(m_Device,szSkyTex[i], D3DX_DEFAULT, D3DX_DEFAULT,
1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
0, NULL, NULL, &m_pSkyTex[i]);
}
D3DXCreateCubeTexture(m_Device, 128, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, &m_pSkyCubeTex);
for(int i = 0; i < 6; i++) {
if(m_pSkyTex[i]) {
IDirect3DSurface8 *pSrc;
IDirect3DSurface8 *pDest;
m_pSkyTex[i]->GetSurfaceLevel(0, &pSrc);
m_pSkyCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES) i, 0, &pDest);
if(pSrc && pDest)
D3DXLoadSurfaceFromSurface(pDest, NULL, NULL, pSrc, NULL, NULL, D3DX_DEFAULT, 0);
pDest->Release();
pSrc->Release();
}
}
D3DXFilterCubeTexture(m_pSkyCubeTex, NULL, 0, D3DX_DEFAULT);
}