1019 lines
32 KiB
C++
1019 lines
32 KiB
C++
#include "StdAfx.h"
|
|
#include "TEtWorldWater.h"
|
|
#include "TEtWorldWaterRiver.h"
|
|
#include "TEtWorldGrid.h"
|
|
#include "TEtWorldSector.h"
|
|
#include "UnionValueProperty.h"
|
|
#include "PropertyGridCreator.h"
|
|
#include "SundriesFuncEx.h"
|
|
#include "resource.h"
|
|
#include "UserMessage.h"
|
|
#include "PaneDefine.h"
|
|
#include "MainFrm.h"
|
|
#include "EtWater.h"
|
|
#include <map>
|
|
using namespace std;
|
|
|
|
#include "RenderBase.h"
|
|
|
|
PropertyGridBaseDefine g_WaterSeaPropertyDefine[] = {
|
|
{ "Shader", "Effect Name", CUnionValueProperty::String_FileOpen, "Shader File Name|Shader Effect File|*.fx", FALSE },
|
|
{ "Common", "Enable", CUnionValueProperty::Boolean, "Enable Water", TRUE },
|
|
{ "Common", "Water Level", CUnionValueProperty::Float, "Water Level", TRUE },
|
|
{ "Common", "UV U Ratio", CUnionValueProperty::Float, "Texture UV", TRUE },
|
|
{ "Common", "UV V Ratio", CUnionValueProperty::Float, "Texture UV", TRUE },
|
|
{ "Alphamap", "Width", CUnionValueProperty::Integer_Combo, "알파맵 가로 사이즈|32|64|128|256|512|1024|2048", TRUE },
|
|
{ "Alphamap", "Height", CUnionValueProperty::Integer_Combo, "알파맵 세로 사이즈|32|64|128|256|512|1024|2048", TRUE },
|
|
{ "Alphamap", "Border Reduction", CUnionValueProperty::Integer, "경계면 축소 카운트(Default=10)|0|50|1", TRUE },
|
|
{ "Alphamap", "Blur Value", CUnionValueProperty::Integer, "블러값(Default=10)|0|30|1", TRUE },
|
|
{ "Alphamap", "Blur Epsilon", CUnionValueProperty::Float, "블러값2 위의 값이 커지면 가치 커져야 한다.(Default=7.f)|0.1f|30.f|0.01f", TRUE },
|
|
{ "Alphamap", "Min Alpha", CUnionValueProperty::Integer, "알파 최소값|0|255|1", TRUE },
|
|
{ "Alphamap", "Max Alpha", CUnionValueProperty::Integer, "알파 최대값|0|255|1", TRUE },
|
|
{ "Alphamap", "Revision Alpha", CUnionValueProperty::Float, "계산 후 알파값 보정|0.f|5.f|0.001f", TRUE },
|
|
{ "Common", "Mesh Grid Size", CUnionValueProperty::Float, "매쉬 그리드 사이즈(Default=200(cm))", TRUE },
|
|
{ NULL },
|
|
};
|
|
|
|
CTEtWorldWater::CTEtWorldWater( CEtWorldSector *pSector )
|
|
: CEtWorldWater( pSector )
|
|
{
|
|
m_pMesh = NULL;
|
|
m_szShaderName = "water.fx";
|
|
m_nEngineWaterCount = 0;
|
|
|
|
SAFE_DELETEA( m_pAlphaTable );
|
|
if( m_pAlphaTable == NULL ) {
|
|
m_pAlphaTable = new BYTE[ m_nAlphaTableWidth * m_nAlphaTableHeight ];
|
|
for( int i=0; i<m_nAlphaTableHeight; i++ ) {
|
|
for( int j=0; j<m_nAlphaTableWidth; j++ ) {
|
|
m_pAlphaTable[ i * m_nAlphaTableWidth + j ] = 128;
|
|
}
|
|
}
|
|
}
|
|
|
|
CreateMesh();
|
|
RefreshShader();
|
|
RefreshTexture();
|
|
RefreshTextureAlpha();
|
|
}
|
|
|
|
CTEtWorldWater::~CTEtWorldWater()
|
|
{
|
|
if( m_bEnable ) DelEngineWaterCount();
|
|
std::map<std::string, EtTextureHandle>::iterator it;
|
|
for( it = m_MapTextureList.begin(); it!=m_MapTextureList.end(); it++ ) {
|
|
SAFE_RELEASE_SPTR( it->second );
|
|
}
|
|
m_MapTextureList.clear();
|
|
//SAFE_DELETE_PVEC( m_pVecPropertyList );
|
|
for( DWORD MACRO_0 = 0; MACRO_0< m_pVecPropertyList.size(); MACRO_0++ ) { \
|
|
if( m_pVecPropertyList[MACRO_0] ) m_pVecPropertyList[MACRO_0]; \
|
|
}
|
|
m_pVecPropertyList.clear();
|
|
|
|
|
|
SAFE_RELEASE_SPTR( m_hMaterial );
|
|
SAFE_RELEASE_SPTR( m_hAlphaTexture );
|
|
SAFE_DELETE( m_pMesh );
|
|
SAFE_DELETE( m_pAlphaTable );
|
|
SAFE_DELETE_PVEC( m_pVecRiver );
|
|
}
|
|
|
|
bool CTEtWorldWater::Load( const char *szFileName )
|
|
{
|
|
bool bResult = CEtWorldWater::Load( szFileName );
|
|
if( m_bEnable ) AddEngineWaterCount();
|
|
|
|
CRenderBase::GetInstance().Lock();
|
|
CreateMesh();
|
|
RefreshShader();
|
|
|
|
for( DWORD i=0; i<m_pVecCustomParamList.size(); i++ ) {
|
|
CUnionValueProperty *pVariable = NULL;
|
|
for( DWORD j=0; j<m_pVecPropertyList.size(); j++ ) {
|
|
if( _stricmp( m_pVecCustomParamList[i]->szName.c_str(), m_pVecPropertyList[j]->GetDescription() ) == NULL ) {
|
|
pVariable = m_pVecPropertyList[j];
|
|
break;
|
|
}
|
|
}
|
|
if( pVariable == NULL ) continue;
|
|
switch( m_pVecCustomParamList[i]->nType ) {
|
|
case EPT_INT:
|
|
pVariable->SetVariable( m_pVecCustomParamList[i]->nInt );
|
|
AddCustomParam( m_vecCustomParam, EPT_INT, m_hMaterial, m_pVecCustomParamList[i]->szName.c_str(), &m_pVecCustomParamList[i]->nInt );
|
|
break;
|
|
case EPT_FLOAT:
|
|
pVariable->SetVariable( m_pVecCustomParamList[i]->fFloat );
|
|
AddCustomParam( m_vecCustomParam, EPT_FLOAT, m_hMaterial, m_pVecCustomParamList[i]->szName.c_str(), &m_pVecCustomParamList[i]->fFloat );
|
|
break;
|
|
case EPT_VECTOR:
|
|
pVariable->SetVariable( *(EtVector4*)m_pVecCustomParamList[i]->fFloat4 );
|
|
AddCustomParam( m_vecCustomParam, EPT_VECTOR, m_hMaterial, m_pVecCustomParamList[i]->szName.c_str(), &m_pVecCustomParamList[i]->fFloat4 );
|
|
break;
|
|
case EPT_TEX:
|
|
{
|
|
pVariable->SetVariable( m_pVecCustomParamList[i]->szTexName );
|
|
|
|
std::map<std::string, EtTextureHandle>::iterator it = m_MapTextureList.find(m_pVecCustomParamList[i]->szName);
|
|
if( it != m_MapTextureList.end() ) {
|
|
SAFE_RELEASE_SPTR( it->second );
|
|
m_MapTextureList.erase( it );
|
|
}
|
|
EtTextureHandle hTexture = LoadResource( pVariable->GetVariableString(), RT_TEXTURE );
|
|
int nTexIndex = hTexture.GetIndex();
|
|
m_MapTextureList.insert( make_pair( m_pVecCustomParamList[i]->szName, hTexture ) );
|
|
if( nTexIndex == -1 ) {
|
|
nTexIndex = CEtTexture::GetBlankTexture().GetIndex();
|
|
}
|
|
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, m_pVecCustomParamList[i]->szName.c_str(), &nTexIndex );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if( m_pAlphaTable == NULL ) {
|
|
m_pAlphaTable = new BYTE[ m_nAlphaTableWidth * m_nAlphaTableHeight ];
|
|
for( int i=0; i<m_nAlphaTableHeight; i++ ) {
|
|
for( int j=0; j<m_nAlphaTableWidth; j++ ) {
|
|
m_pAlphaTable[ i * m_nAlphaTableWidth + j ] = 128;
|
|
}
|
|
}
|
|
}
|
|
|
|
RefreshTexture();
|
|
RefreshTextureAlpha();
|
|
|
|
CRenderBase::GetInstance().Unlock();
|
|
|
|
CWnd *pWnd = GetPaneWnd( WATERPROP_PANE );
|
|
if( pWnd ) pWnd->SendMessage( UM_REFRESH_PANE_VIEW, 1, (LPARAM)this );
|
|
|
|
return bResult;
|
|
}
|
|
|
|
CEtWorldWaterRiver *CTEtWorldWater::AllocRiver()
|
|
{
|
|
return new CTEtWorldWaterRiver( this );
|
|
}
|
|
|
|
|
|
bool CTEtWorldWater::Save( const char *szFileName )
|
|
{
|
|
FILE *fp;
|
|
CString szName;
|
|
fopen_s( &fp, szFileName, "wb" );
|
|
if( fp == NULL ) return false;
|
|
|
|
// 실제 데이터들
|
|
fwrite( &m_bEnable, sizeof(bool), 1, fp );
|
|
fwrite( &m_nAlphaTableWidth, sizeof(int), 1, fp );
|
|
fwrite( &m_nAlphaTableHeight, sizeof(int), 1, fp );
|
|
fwrite( &m_fGridSize, sizeof(float), 1, fp );
|
|
fwrite( &m_vUVRatio, sizeof(EtVector2), 1, fp );
|
|
fwrite( &m_fWaterLevel, sizeof(float), 1, fp );
|
|
fwrite( m_pAlphaTable, sizeof(BYTE) * ( m_nAlphaTableWidth * m_nAlphaTableHeight ), 1, fp );
|
|
|
|
// 툴에서만 사용하는 파라매터지만 가치 저장하자.
|
|
fwrite( &m_nBorderReduction, sizeof(int), 1, fp );
|
|
fwrite( &m_nGaussianValue, sizeof(int), 1, fp );
|
|
fwrite( &m_fGaussianEpsilon, sizeof(float), 1, fp );
|
|
fwrite( &m_nMinAlpha, sizeof(int), 1, fp );
|
|
fwrite( &m_nMaxAlpha, sizeof(int), 1, fp );
|
|
fwrite( &m_fRevisionAlpha, sizeof(float), 1, fp );
|
|
|
|
szName = m_szShaderName.c_str();
|
|
WriteCString( &szName, fp );
|
|
|
|
long nOffset = ftell(fp);
|
|
int nCustomParamCount = 0;
|
|
fwrite( &nCustomParamCount, sizeof(int), 1, fp );
|
|
|
|
EtParameterHandle hParam;
|
|
EffectParamType Type;
|
|
for( int i=0; i<m_hMaterial->GetCustomParamCount(); i++ ) {
|
|
|
|
hParam = m_hMaterial->GetCustomParamHandle(i);
|
|
Type = m_hMaterial->GetCustomParamType(i);
|
|
szName = m_hMaterial->GetParameterName( hParam );
|
|
|
|
SCustomParam *pParam = NULL;
|
|
for( DWORD j=0; j<m_vecCustomParam.size(); j++ ) {
|
|
if( m_vecCustomParam[j].hParamHandle == hParam &&
|
|
m_vecCustomParam[j].Type == Type ) {
|
|
pParam = &m_vecCustomParam[j];
|
|
break;
|
|
}
|
|
}
|
|
if( pParam == NULL ) continue;
|
|
if( _stricmp( szName, "g_TransparencyTex" ) == NULL ) continue;
|
|
if( _stricmp( szName, "g_WaterMapTex" ) == NULL ) continue;
|
|
if( _stricmp( szName, "g_LastViewMat" ) == NULL ) continue;
|
|
|
|
WriteCString( &szName, fp );
|
|
fwrite( &Type, sizeof(EffectParamType), 1, fp );
|
|
switch( Type ) {
|
|
case EPT_INT: fwrite( &pParam->nInt, sizeof(int), 1, fp ); break;
|
|
case EPT_FLOAT: fwrite( &pParam->fFloat, sizeof(float), 1, fp ); break;
|
|
case EPT_VECTOR: fwrite( pParam->fFloat4, sizeof(float)*4, 1, fp ); break;
|
|
case EPT_TEX:
|
|
{
|
|
bool bEmptyTexture = false;
|
|
if( pParam->nTextureIndex == -1 ) bEmptyTexture = true;
|
|
if( CEtTexture::GetBlankTexture().GetIndex() == pParam->nTextureIndex ) bEmptyTexture = true;
|
|
if( bEmptyTexture ) {
|
|
szName.Empty();
|
|
WriteCString( &szName, fp );
|
|
break;
|
|
}
|
|
EtTextureHandle hTexture = CEtResource::GetResource( pParam->nTextureIndex );
|
|
if( !hTexture ) continue;
|
|
szName = hTexture->GetFileName();
|
|
if( szName.IsEmpty() ) continue;
|
|
WriteCString( &szName, fp );
|
|
break;
|
|
}
|
|
case EPT_MATRIX: fwrite( pParam->fFloat4, sizeof(float)*16, 1, fp ); break;
|
|
}
|
|
nCustomParamCount++;
|
|
}
|
|
int nRiverCount = (int)m_pVecRiver.size();
|
|
fwrite( &nRiverCount, sizeof(int), 1, fp );
|
|
for( int i=0; i<nRiverCount; i++ ) {
|
|
((CTEtWorldWaterRiver*)m_pVecRiver[i])->Save( fp );
|
|
}
|
|
|
|
fseek( fp, nOffset, SEEK_SET );
|
|
fwrite( &nCustomParamCount, sizeof(int), 1, fp );
|
|
fclose(fp);
|
|
|
|
return true;
|
|
}
|
|
|
|
void CTEtWorldWater::Render( LOCAL_TIME LocalTime )
|
|
{
|
|
if( m_bEnable ) {
|
|
GetEtWater()->SetWaterHeight( GetEngineWaterIndex(this), m_fWaterLevel );
|
|
GetEtWater()->SetWaterIgnoreBake( GetEngineWaterIndex(this), false );
|
|
|
|
SRenderStackElement RenderElement;
|
|
EtMatrix WorldMat;
|
|
|
|
EtMatrixIdentity( &WorldMat );
|
|
RenderElement.hMaterial = m_hMaterial;
|
|
RenderElement.nTechniqueIndex = 0;
|
|
RenderElement.WorldMat = WorldMat;
|
|
RenderElement.PrevWorldMat = WorldMat;
|
|
RenderElement.nSaveMatIndex = -1;
|
|
RenderElement.pvecCustomParam = &m_vecCustomParam;
|
|
RenderElement.pRenderMeshStream = m_pMesh;
|
|
RenderElement.renderPriority = RP_HIGH;
|
|
GetCurRenderStack()->AddAlphaRenderElement( RenderElement );
|
|
}
|
|
|
|
for( DWORD i=0; i<m_pVecRiver.size(); i++ ) {
|
|
((CTEtWorldWaterRiver*)m_pVecRiver[i])->Render( LocalTime );
|
|
}
|
|
}
|
|
|
|
bool CTEtWorldWater::CreateMesh()
|
|
{
|
|
SAFE_DELETE( m_pMesh );
|
|
m_pMesh = new CEtMeshStream;
|
|
|
|
RefreshVertex();
|
|
RefreshIndex();
|
|
RefreshNormal();
|
|
RefreshTextureCoord();
|
|
|
|
return true;
|
|
}
|
|
|
|
void CTEtWorldWater::OnSetValue( CUnionValueProperty *pVariable, DWORD dwIndex, CPropertyGridImp *pImp )
|
|
{
|
|
if( dwIndex >= 2 ) {
|
|
pImp->SetReadOnly( pVariable, !m_bEnable );
|
|
}
|
|
switch( dwIndex ) {
|
|
case 0:
|
|
pVariable->SetVariable( (char*)m_szShaderName.c_str() );
|
|
break;
|
|
case 1:
|
|
pVariable->SetVariable( m_bEnable );
|
|
break;
|
|
case 2:
|
|
pVariable->SetVariable( m_fWaterLevel );
|
|
break;
|
|
case 3:
|
|
pVariable->SetVariable( m_vUVRatio.x );
|
|
break;
|
|
case 4:
|
|
pVariable->SetVariable( m_vUVRatio.y );
|
|
break;
|
|
case 5:
|
|
switch( m_nAlphaTableWidth ) {
|
|
case 32: pVariable->SetVariable(0); break;
|
|
case 64: pVariable->SetVariable(1); break;
|
|
case 128: pVariable->SetVariable(2); break;
|
|
case 256: pVariable->SetVariable(3); break;
|
|
case 512: pVariable->SetVariable(4); break;
|
|
case 1024: pVariable->SetVariable(5); break;
|
|
case 2048: pVariable->SetVariable(6); break;
|
|
}
|
|
break;
|
|
case 6:
|
|
switch( m_nAlphaTableHeight ) {
|
|
case 32: pVariable->SetVariable(0); break;
|
|
case 64: pVariable->SetVariable(1); break;
|
|
case 128: pVariable->SetVariable(2); break;
|
|
case 256: pVariable->SetVariable(3); break;
|
|
case 512: pVariable->SetVariable(4); break;
|
|
case 1024: pVariable->SetVariable(5); break;
|
|
case 2048: pVariable->SetVariable(6); break;
|
|
}
|
|
break;
|
|
case 7:
|
|
pVariable->SetVariable( m_nBorderReduction );
|
|
break;
|
|
case 8:
|
|
pVariable->SetVariable( m_nGaussianValue );
|
|
break;
|
|
case 9:
|
|
pVariable->SetVariable( m_fGaussianEpsilon );
|
|
break;
|
|
case 10:
|
|
pVariable->SetVariable( m_nMinAlpha );
|
|
break;
|
|
case 11:
|
|
pVariable->SetVariable( m_nMaxAlpha );
|
|
break;
|
|
case 12:
|
|
pVariable->SetVariable( m_fRevisionAlpha );
|
|
break;
|
|
case 13:
|
|
pVariable->SetVariable( m_fGridSize );
|
|
break;
|
|
|
|
};
|
|
int nOffset = ( sizeof(g_WaterSeaPropertyDefine) / sizeof(PropertyGridBaseDefine) ) - 1;
|
|
if( dwIndex - nOffset >= 0 && dwIndex - nOffset < m_pVecPropertyList.size() ) {
|
|
EtParameterHandle hParam;
|
|
EffectParamType Type;
|
|
|
|
for( DWORD i=0; i<m_vecCustomParam.size(); i++ ) {
|
|
hParam = m_hMaterial->GetCustomParamHandle(i);
|
|
Type = m_hMaterial->GetCustomParamType(i);
|
|
const char *szName = m_hMaterial->GetParameterName( hParam );
|
|
if( _stricmp( szName, pVariable->GetDescription() ) == NULL ) {
|
|
|
|
switch( pVariable->GetType() ) {
|
|
case CUnionValueProperty::Float:
|
|
pVariable->SetVariable( m_vecCustomParam[i].fFloat );
|
|
break;
|
|
case CUnionValueProperty::Integer:
|
|
pVariable->SetVariable( m_vecCustomParam[i].nInt );
|
|
break;
|
|
case CUnionValueProperty::Vector4Color:
|
|
pVariable->SetVariable( *(EtVector4*)m_vecCustomParam[i].fFloat4 );
|
|
break;
|
|
case CUnionValueProperty::String_FileOpen:
|
|
{
|
|
std::map<std::string, EtTextureHandle>::iterator it = m_MapTextureList.find(pVariable->GetDescription());
|
|
if( it != m_MapTextureList.end() ) {
|
|
if( it->second )
|
|
pVariable->SetVariable( (char*)it->second->GetFileName() );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CTEtWorldWater::OnChangeValue( CUnionValueProperty *pVariable, DWORD dwIndex, CPropertyGridImp *pImp )
|
|
{
|
|
CGlobalValue::GetInstance().SetModify();
|
|
switch( dwIndex ) {
|
|
case 0:
|
|
m_szShaderName = pVariable->GetVariableString();
|
|
RefreshShader();
|
|
{
|
|
CWnd *pWnd = GetPaneWnd( WATERPROP_PANE );
|
|
if( pWnd ) pWnd->SendMessage( UM_REFRESH_PANE_VIEW, 1, (LPARAM)this );
|
|
}
|
|
break;
|
|
case 1:
|
|
if( m_bEnable ) DelEngineWaterCount();
|
|
m_bEnable = pVariable->GetVariableBool();
|
|
if( m_bEnable ) AddEngineWaterCount();
|
|
for( int i=2; i<(int)m_pVecPropertyList.size(); i++ ) {
|
|
pImp->SetReadOnly( i, !m_bEnable );
|
|
}
|
|
break;
|
|
case 2:
|
|
m_fWaterLevel = pVariable->GetVariableFloat();
|
|
//GetEtWater()->SetWaterHeight( m_fWaterLevel );
|
|
RefreshVertex();
|
|
break;
|
|
case 3:
|
|
m_vUVRatio.x = pVariable->GetVariableFloat();
|
|
RefreshTextureCoord();
|
|
break;
|
|
case 4:
|
|
m_vUVRatio.y = pVariable->GetVariableFloat();
|
|
RefreshTextureCoord();
|
|
break;
|
|
case 5:
|
|
switch( pVariable->GetVariableInt() ) {
|
|
case 0: m_nAlphaTableWidth = 32; break;
|
|
case 1: m_nAlphaTableWidth = 64; break;
|
|
case 2: m_nAlphaTableWidth = 128; break;
|
|
case 3: m_nAlphaTableWidth = 256; break;
|
|
case 4: m_nAlphaTableWidth = 512; break;
|
|
case 5: m_nAlphaTableWidth = 1024; break;
|
|
case 6: m_nAlphaTableWidth = 2048; break;
|
|
}
|
|
break;
|
|
case 6:
|
|
switch( pVariable->GetVariableInt() ) {
|
|
case 0: m_nAlphaTableHeight = 32; break;
|
|
case 1: m_nAlphaTableHeight = 64; break;
|
|
case 2: m_nAlphaTableHeight = 128; break;
|
|
case 3: m_nAlphaTableHeight = 256; break;
|
|
case 4: m_nAlphaTableHeight = 512; break;
|
|
case 5: m_nAlphaTableHeight = 1024; break;
|
|
case 6: m_nAlphaTableHeight = 2048; break;
|
|
}
|
|
break;
|
|
case 7:
|
|
m_nBorderReduction = pVariable->GetVariableInt();
|
|
break;
|
|
case 8:
|
|
m_nGaussianValue = pVariable->GetVariableInt();
|
|
break;
|
|
case 9:
|
|
m_fGaussianEpsilon = pVariable->GetVariableFloat();
|
|
break;
|
|
case 10:
|
|
m_nMinAlpha = pVariable->GetVariableInt();
|
|
break;
|
|
case 11:
|
|
m_nMaxAlpha = pVariable->GetVariableInt();
|
|
break;
|
|
case 12:
|
|
m_fRevisionAlpha = pVariable->GetVariableFloat();
|
|
RefreshTextureAlpha();
|
|
break;
|
|
case 13:
|
|
m_fGridSize = pVariable->GetVariableFloat();
|
|
CreateMesh();
|
|
break;
|
|
|
|
}
|
|
int nOffset = ( sizeof(g_WaterSeaPropertyDefine) / sizeof(PropertyGridBaseDefine) ) - 1;
|
|
if( dwIndex - nOffset >= 0 && dwIndex - nOffset < m_pVecPropertyList.size() ) {
|
|
switch( pVariable->GetType() ) {
|
|
case CUnionValueProperty::Float:
|
|
{
|
|
float fValue = pVariable->GetVariableFloat();
|
|
AddCustomParam( m_vecCustomParam, EPT_FLOAT, m_hMaterial, pVariable->GetDescription(), &fValue );
|
|
}
|
|
break;
|
|
case CUnionValueProperty::Integer:
|
|
{
|
|
int nValue = pVariable->GetVariableInt();
|
|
AddCustomParam( m_vecCustomParam, EPT_INT, m_hMaterial, pVariable->GetDescription(), &nValue );
|
|
}
|
|
break;
|
|
case CUnionValueProperty::Vector4Color:
|
|
{
|
|
EtVector4 vVec = pVariable->GetVariableVector4();
|
|
AddCustomParam( m_vecCustomParam, EPT_VECTOR, m_hMaterial, pVariable->GetDescription(), &vVec );
|
|
}
|
|
break;
|
|
case CUnionValueProperty::String_FileOpen:
|
|
{
|
|
OutputDebug( "Tex : %s %s\n", pVariable->GetDescription(), pVariable->GetVariableString() );
|
|
std::map<std::string, EtTextureHandle>::iterator it = m_MapTextureList.find(pVariable->GetDescription());
|
|
if( it != m_MapTextureList.end() ) {
|
|
SAFE_RELEASE_SPTR( it->second );
|
|
m_MapTextureList.erase( it );
|
|
}
|
|
EtTextureHandle hTexture = LoadResource( pVariable->GetVariableString(), RT_TEXTURE );
|
|
int nTexIndex = hTexture.GetIndex();
|
|
m_MapTextureList.insert( make_pair( pVariable->GetDescription(), hTexture ) );
|
|
if( nTexIndex == -1 ) {
|
|
nTexIndex = CEtTexture::GetBlankTexture().GetIndex();
|
|
}
|
|
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, pVariable->GetDescription(), &nTexIndex );
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
CGlobalValue::GetInstance().RefreshRender();
|
|
}
|
|
|
|
void CTEtWorldWater::OnSelectChangeValue( CUnionValueProperty *pVariable, DWORD dwIndex, CPropertyGridImp *pImp )
|
|
{
|
|
}
|
|
|
|
|
|
void CTEtWorldWater::RefreshTextureCoord()
|
|
{
|
|
if( !m_pMesh ) return;
|
|
|
|
float fWidth = (float)m_pSector->GetParentGrid()->GetGridWidth() * 100.f;
|
|
float fHeight = (float)m_pSector->GetParentGrid()->GetGridHeight() * 100.f;
|
|
|
|
int nWidthCount = (int)( ( fWidth / m_fGridSize ) + 1.f );
|
|
int nHeightCount = (int)( ( fHeight / m_fGridSize ) + 1.f );
|
|
|
|
int nSize = nWidthCount * nHeightCount;
|
|
EtVector2 *pUV = new EtVector2[ nSize ];
|
|
|
|
for( int j=0; j<nHeightCount; j++ ) {
|
|
for( int i=0; i<nWidthCount; i++ ) {
|
|
pUV[ j * nWidthCount + i ].x = ( m_vUVRatio.x / (float)(nWidthCount-1) ) * (float)i;
|
|
pUV[ j * nWidthCount + i ].y = ( m_vUVRatio.y / (float)(nHeightCount-1) ) * (float)j;
|
|
}
|
|
}
|
|
|
|
CMemoryStream Stream( pUV, sizeof(EtVector2) * nSize );
|
|
m_pMesh->LoadVertexStream( &Stream, MST_TEXCOORD, 0, nSize );
|
|
|
|
for( int j=0; j<nHeightCount; j++ ) {
|
|
for( int i=0; i<nWidthCount; i++ ) {
|
|
pUV[ j * nWidthCount + i ].x = ( 1.f / (float)(nWidthCount-1) ) * (float)i;
|
|
pUV[ j * nWidthCount + i ].y = ( 1.f / (float)(nHeightCount-1) ) * (float)j;
|
|
}
|
|
}
|
|
|
|
Stream.Initialize( pUV, sizeof(EtVector2) * nSize );
|
|
m_pMesh->LoadVertexStream( &Stream, MST_TEXCOORD, 1, nSize );
|
|
|
|
|
|
SAFE_DELETE( pUV );
|
|
}
|
|
|
|
void CTEtWorldWater::RefreshVertex()
|
|
{
|
|
if( !m_pMesh ) return;
|
|
|
|
EtVector3 vOffset = *m_pSector->GetOffset();
|
|
float fWidth = (float)m_pSector->GetParentGrid()->GetGridWidth() * 100.f;
|
|
float fHeight = (float)m_pSector->GetParentGrid()->GetGridHeight() * 100.f;
|
|
|
|
int nWidthCount = (int)( ( fWidth / m_fGridSize ) + 1.f );
|
|
int nHeightCount = (int)( ( fHeight / m_fGridSize ) + 1.f );
|
|
|
|
int nSize = nWidthCount * nHeightCount;
|
|
EtVector3 *pVertex = new EtVector3[ nSize ];
|
|
|
|
for( int j=0; j<nHeightCount; j++ ) {
|
|
for( int i=0; i<nWidthCount; i++ ) {
|
|
pVertex[ j * nWidthCount + i ].x = vOffset.x - ( fWidth / 2.f ) + ( i * m_fGridSize );
|
|
pVertex[ j * nWidthCount + i ].y = GetWaterLevel();
|
|
pVertex[ j * nWidthCount + i ].z = vOffset.z - ( fHeight / 2.f ) + ( j * m_fGridSize );
|
|
}
|
|
}
|
|
|
|
CMemoryStream Stream( pVertex, sizeof(EtVector3) * nSize );
|
|
m_pMesh->LoadVertexStream( &Stream, MST_POSITION, 0, nSize );
|
|
SAFE_DELETE( pVertex );
|
|
}
|
|
|
|
void CTEtWorldWater::RefreshIndex()
|
|
{
|
|
if( !m_pMesh ) return;
|
|
|
|
float fWidth = (float)m_pSector->GetParentGrid()->GetGridWidth() * 100.f;
|
|
float fHeight = (float)m_pSector->GetParentGrid()->GetGridHeight() * 100.f;
|
|
|
|
int nWidthCount = (int)( ( fWidth / m_fGridSize ) );
|
|
int nHeightCount = (int)( ( fHeight / m_fGridSize ) );
|
|
|
|
int nSize = nWidthCount * nHeightCount * 6;
|
|
WORD *pIndex = new WORD[ nSize ];
|
|
|
|
int nOffset;
|
|
for( int j=0; j<nHeightCount; j++ ) {
|
|
for( int i=0; i<nWidthCount; i++ ) {
|
|
nOffset = (j*6) * nWidthCount + (i*6);
|
|
|
|
pIndex[nOffset] = ( j * ( nWidthCount + 1 ) ) + i;
|
|
pIndex[nOffset + 1] = ( (j+1) * ( nWidthCount + 1 ) ) + i;
|
|
pIndex[nOffset + 2] = ( (j+1) * ( nWidthCount + 1 ) ) + (i+1);
|
|
pIndex[nOffset + 3] = ( j * ( nWidthCount + 1 ) ) + i;
|
|
pIndex[nOffset + 4] = ( (j+1) * ( nWidthCount + 1 ) ) + (i+1);
|
|
pIndex[nOffset + 5] = ( j * ( nWidthCount + 1 ) ) + (i+1);
|
|
}
|
|
}
|
|
|
|
CMemoryStream Stream( pIndex, sizeof(WORD) * nSize );
|
|
m_pMesh->LoadIndexStream( &Stream, false, nSize );
|
|
|
|
SAFE_DELETE( pIndex );
|
|
}
|
|
|
|
void CTEtWorldWater::RefreshNormal()
|
|
{
|
|
if( !m_pMesh ) return;
|
|
|
|
EtVector3 vOffset = *m_pSector->GetOffset();
|
|
float fWidth = (float)m_pSector->GetParentGrid()->GetGridWidth() * 100.f;
|
|
float fHeight = (float)m_pSector->GetParentGrid()->GetGridHeight() * 100.f;
|
|
|
|
int nWidthCount = (int)( ( fWidth / m_fGridSize ) + 1.f );
|
|
int nHeightCount = (int)( ( fHeight / m_fGridSize ) + 1.f );
|
|
|
|
int nSize = nWidthCount * nHeightCount;
|
|
EtVector3 *pVertex = new EtVector3[ nSize ];
|
|
|
|
for( int j=0; j<nHeightCount; j++ ) {
|
|
for( int i=0; i<nWidthCount; i++ ) {
|
|
pVertex[ j * nWidthCount + i ] = EtVector3( 0.f, 1.f, 0.f );
|
|
}
|
|
}
|
|
|
|
CMemoryStream Stream( pVertex, sizeof(EtVector3) * nSize );
|
|
m_pMesh->LoadVertexStream( &Stream, MST_NORMAL, 0, nSize );
|
|
SAFE_DELETE( pVertex );
|
|
}
|
|
|
|
void CTEtWorldWater::RefreshShader()
|
|
{
|
|
SAFE_RELEASE_SPTR( m_hMaterial );
|
|
//SAFE_DELETE_PVEC( m_pVecPropertyList );
|
|
|
|
for( DWORD MACRO_0 = 0; MACRO_0< m_pVecPropertyList.size(); MACRO_0++ ) { \
|
|
if( m_pVecPropertyList[MACRO_0] ) m_pVecPropertyList[MACRO_0]; \
|
|
}
|
|
m_pVecPropertyList.clear();
|
|
|
|
CUnionValueProperty *pVariable;
|
|
for( DWORD i=0; ; i++ ) {
|
|
if( g_WaterSeaPropertyDefine[i].szCategory == NULL ) break;
|
|
|
|
pVariable = new CUnionValueProperty( g_WaterSeaPropertyDefine[i].Type );
|
|
pVariable->SetCategory( g_WaterSeaPropertyDefine[i].szCategory );
|
|
pVariable->SetDescription( g_WaterSeaPropertyDefine[i].szStr );
|
|
pVariable->SetSubDescription( g_WaterSeaPropertyDefine[i].szDescription, true );
|
|
pVariable->SetDefaultEnable( g_WaterSeaPropertyDefine[i].bEnable );
|
|
pVariable->SetCustomDialog( g_WaterSeaPropertyDefine[i].bCustomDialog );
|
|
|
|
m_pVecPropertyList.push_back( pVariable );
|
|
}
|
|
|
|
m_hMaterial = LoadResource( m_szShaderName.c_str(), RT_SHADER );
|
|
EtParameterHandle hParam;
|
|
EffectParamType Type;
|
|
for( int i=0; i<m_hMaterial->GetCustomParamCount(); i++ ) {
|
|
|
|
hParam = m_hMaterial->GetCustomParamHandle(i);
|
|
Type = m_hMaterial->GetCustomParamType(i);
|
|
const char *szName = m_hMaterial->GetParameterName( hParam );
|
|
// 보여줄 필요 없는 파라메터 여기서 걸러주자.
|
|
if( _stricmp( szName, "g_TransparencyTex" ) == NULL ) continue;
|
|
if( _stricmp( szName, "g_WaterMapTex" ) == NULL ) continue;
|
|
if( _stricmp( szName, "g_LastViewMat" ) == NULL )
|
|
{
|
|
AddCustomParam( m_vecCustomParam, EPT_MATRIX_PTR, m_hMaterial, "g_LastViewMat", GetEtWater()->GetWaterBakeViewMat() );
|
|
continue;
|
|
}
|
|
///////////////////////////////////////////////
|
|
if( Type == EPT_TEX ) {
|
|
pVariable = new CUnionValueProperty( CUnionValueProperty::String_FileOpen );
|
|
pVariable->SetCategory( "Texture" );
|
|
pVariable->SetDescription( szName );
|
|
pVariable->SetSubDescription( "Texture File|All Texture Files|*.dds;*.jpg;*.tga;*.bmp" );
|
|
pVariable->SetDefaultEnable( TRUE );
|
|
|
|
int nIndex = -1;
|
|
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, szName, &nIndex );
|
|
}
|
|
else {
|
|
switch( Type ) {
|
|
case EPT_VECTOR:
|
|
{
|
|
pVariable = new CUnionValueProperty( CUnionValueProperty::Vector4Color );
|
|
|
|
EtVector4 vVec = pVariable->GetVariableVector4();
|
|
AddCustomParam( m_vecCustomParam, EPT_VECTOR, m_hMaterial, szName, &vVec );
|
|
}
|
|
break;
|
|
case EPT_FLOAT:
|
|
{
|
|
pVariable = new CUnionValueProperty( CUnionValueProperty::Float );
|
|
|
|
float fValue = pVariable->GetVariableFloat();
|
|
AddCustomParam( m_vecCustomParam, EPT_FLOAT, m_hMaterial, szName, &fValue );
|
|
}
|
|
break;
|
|
case EPT_INT:
|
|
{
|
|
pVariable = new CUnionValueProperty( CUnionValueProperty::Integer );
|
|
|
|
int nValue = pVariable->GetVariableInt();
|
|
AddCustomParam( m_vecCustomParam, EPT_INT, m_hMaterial, szName, &nValue );
|
|
}
|
|
break;
|
|
}
|
|
pVariable->SetCategory( "Shader Parameter" );
|
|
pVariable->SetDescription( szName );
|
|
pVariable->SetSubDescription( "Shader Setting Value" );
|
|
pVariable->SetDefaultEnable( TRUE );
|
|
}
|
|
m_pVecPropertyList.push_back( pVariable );
|
|
}
|
|
CWnd *pWnd = GetPaneWnd( WATERPROP_PANE );
|
|
if( pWnd ) pWnd->SendMessage( UM_REFRESH_PANE_VIEW, 1, (LPARAM)this );
|
|
|
|
}
|
|
|
|
void CTEtWorldWater::RefreshTexture( bool bInit )
|
|
{
|
|
SAFE_RELEASE_SPTR( m_hAlphaTexture );
|
|
|
|
m_hAlphaTexture = CEtTexture::CreateNormalTexture( m_nAlphaTableWidth, m_nAlphaTableHeight, FMT_A8R8G8B8, USAGE_DEFAULT, POOL_MANAGED );
|
|
if( bInit ) {
|
|
int nStride;
|
|
DWORD *pPtr = (DWORD*)m_hAlphaTexture->Lock( nStride, true );
|
|
|
|
for( int j=0; j<m_nAlphaTableHeight; j++ ) {
|
|
for( int i=0; i<m_nAlphaTableWidth; i++ ) {
|
|
*pPtr = D3DCOLOR_ARGB( 128, 0, 0, 0 );
|
|
pPtr++;
|
|
}
|
|
}
|
|
m_hAlphaTexture->Unlock();
|
|
}
|
|
if( m_hAlphaTexture ) {
|
|
int nTexIndex = m_hAlphaTexture.GetIndex();
|
|
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, "g_TransparencyTex", &nTexIndex );
|
|
}
|
|
RefreshWaterTexture();
|
|
}
|
|
|
|
void CTEtWorldWater::RefreshWaterTexture()
|
|
{
|
|
if( !m_hMaterial ) return;
|
|
int nTexIndex = -1;
|
|
if( m_bEnable ) {
|
|
EtTextureHandle hTexture = GetEtWater()->GetWaterMapTexture( GetEngineWaterIndex(this) );
|
|
nTexIndex = hTexture.GetIndex();
|
|
}
|
|
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, "g_WaterMapTex", &nTexIndex );
|
|
}
|
|
|
|
void CTEtWorldWater::RefreshTextureAlpha()
|
|
{
|
|
int nStride;
|
|
float fValue;
|
|
DWORD *pPtr = (DWORD*)m_hAlphaTexture->Lock( nStride, true );
|
|
|
|
for( int j=0; j<m_nAlphaTableHeight; j++ ) {
|
|
for( int i=0; i<m_nAlphaTableWidth; i++ ) {
|
|
fValue = m_pAlphaTable[j*m_nAlphaTableWidth+i] * m_fRevisionAlpha;
|
|
if( fValue < 0.f ) fValue = 0.f;
|
|
if( fValue > 255.f ) fValue = 255.f;
|
|
*pPtr = D3DCOLOR_ARGB( (BYTE)fValue, 0, 0, 0 );
|
|
pPtr++;
|
|
}
|
|
}
|
|
|
|
m_hAlphaTexture->Unlock();
|
|
}
|
|
|
|
void CTEtWorldWater::GenerationAlphaMap()
|
|
{
|
|
SAFE_DELETEA( m_pAlphaTable );
|
|
m_pAlphaTable = new BYTE[ m_nAlphaTableWidth * m_nAlphaTableHeight ];
|
|
|
|
EtVector3 vOffset = *m_pSector->GetOffset();
|
|
float fWidth = (float)m_pSector->GetParentGrid()->GetGridWidth() * 100.f;
|
|
float fHeight = (float)m_pSector->GetParentGrid()->GetGridHeight() * 100.f;
|
|
|
|
EtVector2 vPos;
|
|
float fWidthDist = fWidth / (float)m_nAlphaTableWidth;
|
|
float fHeightDist = fHeight / (float)m_nAlphaTableHeight;
|
|
float fValue;
|
|
|
|
float fMin = (float)m_nMinAlpha;
|
|
float fMax = (float)m_nMaxAlpha;
|
|
for( int j=0; j<m_nAlphaTableHeight; j++ ) {
|
|
for( int i=0; i<m_nAlphaTableWidth; i++ ) {
|
|
vPos.x = ( fWidthDist / 2.f ) + ( ( vOffset.x - ( fWidth / 2.f ) ) + ( fWidthDist * i ) );
|
|
vPos.y = ( fHeightDist / 2.f ) + ( ( vOffset.z - ( fHeight / 2.f ) ) + ( fHeightDist * j ) );
|
|
fValue = m_pSector->GetHeightToWorld( vPos.x, vPos.y );
|
|
if( fValue > m_fWaterLevel )
|
|
m_pAlphaTable[j*m_nAlphaTableWidth+i] = (BYTE)fMin;
|
|
else m_pAlphaTable[j*m_nAlphaTableWidth+i] = (BYTE)fMax;
|
|
}
|
|
}
|
|
// 버퍼를 Float 로 변형한 담에 하자.
|
|
int nBufferSize = m_nAlphaTableWidth * m_nAlphaTableHeight;
|
|
float *pTable = new float[nBufferSize];
|
|
for( int j=0; j<m_nAlphaTableHeight; j++ ) {
|
|
for( int i=0; i<m_nAlphaTableWidth; i++ ) {
|
|
int nIndex = j * m_nAlphaTableWidth + i;
|
|
pTable[nIndex] = (float)m_pAlphaTable[nIndex];
|
|
}
|
|
}
|
|
|
|
float *pTempBuf1 = new float[nBufferSize];
|
|
float *pTempBuf2 = new float[nBufferSize];
|
|
int nTempWidth = m_nAlphaTableWidth - 1;
|
|
int nTempHeight = m_nAlphaTableHeight - 1;
|
|
|
|
float fReduction = ( fMax - fMin ) / (float)m_nBorderReduction;
|
|
for( int g=0; g<m_nBorderReduction; g++ ) {
|
|
memcpy( pTempBuf1, pTable, sizeof(float) * m_nAlphaTableWidth * m_nAlphaTableHeight );
|
|
memcpy( pTempBuf2, pTable, sizeof(float) * m_nAlphaTableWidth * m_nAlphaTableHeight );
|
|
fMin = fReduction * g;
|
|
fValue = fReduction * (g+1);
|
|
for( int j=0; j<nTempHeight; j++ ) {
|
|
for( int i=0; i<nTempWidth; i++ ) {
|
|
int nIndex = j * m_nAlphaTableWidth + i;
|
|
if( pTable[nIndex] == fMin && pTable[nIndex+1] == fMax ) {
|
|
pTempBuf1[nIndex+1] = fValue;
|
|
}
|
|
else if( pTable[nIndex] == fMax && pTable[nIndex+1] == fMin ) {
|
|
pTempBuf1[nIndex] = fValue;
|
|
}
|
|
}
|
|
}
|
|
for( int j=0; j<nTempHeight; j++ ) {
|
|
for( int i=0; i<nTempWidth; i++ ) {
|
|
int nIndex = j * m_nAlphaTableWidth + i;
|
|
int nIndex2 = (j+1) * m_nAlphaTableWidth + i;
|
|
if( pTable[nIndex] == fMin && pTable[nIndex2] == fMax ) {
|
|
pTempBuf2[nIndex2] = fValue;
|
|
}
|
|
else if( pTable[nIndex] == fMax && pTable[nIndex2] == fMin ) {
|
|
pTempBuf2[nIndex] = fValue;
|
|
}
|
|
}
|
|
}
|
|
for( int j=0; j<m_nAlphaTableHeight; j++ ) {
|
|
for( int i=0; i<m_nAlphaTableWidth; i++ ) {
|
|
int nIndex = j*m_nAlphaTableWidth+i;
|
|
if( pTempBuf1[nIndex] == fValue || pTempBuf2[nIndex] == fValue ) pTable[nIndex] = fValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
SAFE_DELETE( pTempBuf1 );
|
|
SAFE_DELETE( pTempBuf2 );
|
|
|
|
if( m_nGaussianValue > 0 ) {
|
|
int nBlurValue = m_nGaussianValue;
|
|
float **ppfGaussianTable;
|
|
|
|
int nTableSize = ( nBlurValue * 2 ) + 1;
|
|
ppfGaussianTable = new float*[nTableSize];
|
|
for( int i=0; i<nTableSize; i++ )
|
|
ppfGaussianTable[i] = new float[nTableSize];
|
|
CalcGaussianTable( nBlurValue, m_fGaussianEpsilon, ppfGaussianTable );
|
|
|
|
float *pTempBuf = new float[nBufferSize];
|
|
|
|
memcpy( pTempBuf, pTable, sizeof(float) * m_nAlphaTableWidth * m_nAlphaTableHeight );
|
|
|
|
for( int j=0; j<m_nAlphaTableHeight; j++ ) {
|
|
for( int i=0; i<m_nAlphaTableWidth; i++ ) {
|
|
if( i < nBlurValue ) continue;
|
|
if( i >= m_nAlphaTableWidth - nBlurValue ) continue;
|
|
if( j < nBlurValue ) continue;
|
|
if( j >= m_nAlphaTableHeight - nBlurValue ) continue;
|
|
|
|
pTable[j*m_nAlphaTableWidth+i] = GetNewAlpha( pTempBuf, i, j, nBlurValue, ppfGaussianTable );
|
|
}
|
|
}
|
|
for( int i=0; i<nTableSize; i++ ) {
|
|
SAFE_DELETE( ppfGaussianTable[i] );
|
|
}
|
|
SAFE_DELETE( ppfGaussianTable );
|
|
SAFE_DELETE( pTempBuf );
|
|
}
|
|
for( int j=0; j<m_nAlphaTableHeight; j++ ) {
|
|
for( int i=0; i<m_nAlphaTableWidth; i++ ) {
|
|
int nIndex = j * m_nAlphaTableWidth + i;
|
|
m_pAlphaTable[nIndex] = (BYTE)pTable[nIndex];
|
|
}
|
|
}
|
|
SAFE_DELETE( pTable );
|
|
|
|
RefreshTexture();
|
|
RefreshTextureAlpha();
|
|
}
|
|
|
|
float CTEtWorldWater::GetNewAlpha( float *pBuffer, int x, int y, int nBlurValue, float **ppfTable )
|
|
{
|
|
int nTableSize = ( nBlurValue * 2 ) + 1;
|
|
|
|
x -= nBlurValue;
|
|
y -= nBlurValue;
|
|
|
|
float fValue = 0.f;
|
|
for( int j=0; j<nTableSize; j++ ) {
|
|
for( int i=0; i<nTableSize; i++ ) {
|
|
int nOffset = (y+j) * m_nAlphaTableWidth + (x+i);
|
|
|
|
fValue += pBuffer[nOffset] * ppfTable[i][j];
|
|
}
|
|
}
|
|
if( fValue > 255.f ) fValue = 255.f;
|
|
else if( fValue < 0.f ) fValue = 0.f;
|
|
return fValue;
|
|
}
|
|
|
|
CTEtWorldWaterRiver *CTEtWorldWater::AddRiver( EtVector3 &vPos )
|
|
{
|
|
CTEtWorldWaterRiver *pRiver = (CTEtWorldWaterRiver *)AllocRiver();
|
|
CString szName = GetRiverUniqueName();
|
|
pRiver->SetName( szName.GetBuffer() );
|
|
pRiver->InsertPoint( vPos );
|
|
m_pVecRiver.push_back( pRiver );
|
|
|
|
return pRiver;
|
|
}
|
|
|
|
CString CTEtWorldWater::GetRiverUniqueName()
|
|
{
|
|
int nCount = 0;
|
|
char szStr[64];
|
|
for( int i=0; i<1000; i++ ) {
|
|
sprintf_s( szStr, "River - #%03d", i );
|
|
if( GetRiverFromName( szStr ) == NULL ) return CString(szStr);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
void CTEtWorldWater::RemoveRiver( CTEtWorldWaterRiver *pRiver )
|
|
{
|
|
for( DWORD i=0; i<m_pVecRiver.size(); i++ ) {
|
|
if( m_pVecRiver[i] == pRiver ) {
|
|
SAFE_DELETE( pRiver );
|
|
m_pVecRiver.erase( m_pVecRiver.begin() + i );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CTEtWorldWater::RemoveRiverPoint( CTEtWorldWaterRiver::RiverPoint *pPoint )
|
|
{
|
|
CTEtWorldWaterRiver *pRiver;
|
|
for( DWORD i=0; i<m_pVecRiver.size(); i++ ) {
|
|
pRiver = (CTEtWorldWaterRiver *)m_pVecRiver[i];
|
|
if( pRiver->RemovePoint( pPoint ) ) {
|
|
if( pRiver->GetPointCount() <= 1 ) {
|
|
RemoveRiver( pRiver );
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CTEtWorldWater::AddEngineWaterCount()
|
|
{
|
|
m_nEngineWaterCount++;
|
|
GetEtWater()->Initialize( m_nEngineWaterCount );
|
|
|
|
RefreshWaterTexture();
|
|
for( DWORD i=0; i<m_pVecRiver.size(); i++ ) {
|
|
((CTEtWorldWaterRiver*)m_pVecRiver[i])->RefreshWaterTexture();
|
|
}
|
|
}
|
|
|
|
void CTEtWorldWater::DelEngineWaterCount()
|
|
{
|
|
if( m_nEngineWaterCount == 0 ) return;
|
|
m_nEngineWaterCount--;
|
|
GetEtWater()->Initialize( m_nEngineWaterCount );
|
|
|
|
RefreshWaterTexture();
|
|
for( DWORD i=0; i<m_pVecRiver.size(); i++ ) {
|
|
((CTEtWorldWaterRiver*)m_pVecRiver[i])->RefreshWaterTexture();
|
|
}
|
|
}
|
|
|
|
int CTEtWorldWater::GetEngineWaterIndex( void *pWaterObject )
|
|
{
|
|
int nIndex = 0;
|
|
if( m_bEnable ) {
|
|
nIndex++;
|
|
if( pWaterObject == this ) return 0;
|
|
}
|
|
for( DWORD i=0; i<m_pVecRiver.size(); i++ ) {
|
|
if( ((CTEtWorldWaterRiver*)m_pVecRiver[i])->IsDestroy() ) {
|
|
nIndex--;
|
|
continue;
|
|
}
|
|
if( pWaterObject == m_pVecRiver[i] ) return nIndex + i;
|
|
}
|
|
return -1;
|
|
}
|