#include "stdafx.h" #include "KRenderDevice.h" #include "SGameCloud.h" #include "SEnvPrimitive.h" #include "K3DTypes.h" #include "KSeqModel.h" #include "K3DCamera.h" #include "KResourceManager.h" #include "KRenderObjectEtc.h" #include #include #include "TerrainPrimitive.h" //#include "SDebug_Util.h" #include "SGameWeather.h" // [sonador] to include 'lerp' function in namespace 'env_fx' #include "SGameLightning.h" #include #include //#include "SGameMilesSoundMgr.h" #ifdef CLOUD_LUA #include "SGameSystem.h" #include "SGameAvatarEx.h" #include "SGameWorld.h" CCloudKindDB* g_pCloudKindDB = NULL; CCloudThicknessDB* g_pCloudThicknesDB = NULL; CCloudThicknessGapDB* g_pCloudThicknessGapDB = NULL; CCloudSizeDB* g_pCloudSizeDB = NULL; CCloudTxrGroupDB* g_pCloudTxrGroupDB = NULL; CCloudDistributionDB* g_pCloudDistributionDB = NULL; CCloudHeightRadomGapDB* g_pCloudHeightRadomGapDB = NULL; CCloudLayerGapDB* g_pCloudCloudLayerGapDB = NULL; CCloudMoveDirDB* g_pCloudCloudMoveDirDB = NULL; CCloudPathDB* g_pCloudPathDB = NULL; CCloudTypeInfoDB* g_pCloudTypeInfoDB = NULL; CCloudLayerDB* g_pCloudLayerDB = NULL; CCloudLayerSetDB* g_pCloudLayerSetDB = NULL; float g_fMyPlayerHeight = 0.0f; extern SGameSystem * g_pCurrentGameSystem; int g_nFadeState = 0; float g_fRateG = 1.0f; float g_fRate = 1.0f; float g_fRateScale= 1.0f; float g_fTestX = 0.0f; float g_fTestY = 0.0f; float g_fTestZ = 0.0f; float g_fTestG = 3.0f; bool g_bUseWorldTM = false; float g_fZ = 0.0f; float g_fX = 0.0f; float g_fY = 0.0f; #endif #ifdef SKYBOX_CLOUD const int CLOUD_MAX = 190; const float START_TIME = 6000.f; const float END_TIME = 4000.f; const float DEFAULT_HEIGHT = 500.0f; // { [sonador] const int THUNDER_CLOUD_MAX = 3; const float DEFAULT_HEIGHT_THUNDER_CLOUD = 510.0f; // } float fRotSpeed[] = { 0.2f, // 0.2f, // 0.3f, // 0.4f, // 0.5f, }; bool SGameCloud::m_bProcessPause = false; float SCloudEx::s_fFactor = 0.1f; float SCloudEx::s_fLightningFactor = 1.0f; DWORD SCloudEx::s_dwDuration = 250; int SCloudEx::s_nFlashCount = 3; K3DColor SCloudEx::s_sDestColor = K3DColor( 0xffdae7fe ); SCloudEx::SCloudEx() { InitVariable(); } SCloudEx::SCloudEx(int nType, int nCount, int nDepth, int nZoneWidth, int nZoneHeight) { InitVariable(); } SCloudEx::~SCloudEx() { Destroy(); } void SCloudEx::InitVariable() { nWidth = 0; nHeight = 0; vPosition = K3DVector(0, 0, 0); vStartPosition = K3DVector(0, 0, 0); fVisibilityCap = 1; fVisibility = 0; color = 0x00000000; bActive = false; pVecCloud = 0; dwStartTime = 0; dwOldTime = 0; fRotSpeed = 0.1f; eStep = APPEAR; } void SCloudEx::Init( K3DRenderDevice *pDevice, K3DIndexBuffer * pIndexBuf ) { m_pDevice = pDevice; /* DWORD dwFormat = 0; m_pVB = m_pDevice->CreateVertexBufferUsePoolDefault( sizeof(K3DVERTEX_CLOUD), dwFormat, 4 * nDepth, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY ); if( m_pVB && m_pVB->IsValidVtx() ) { K3DVERTEX_CLOUD* vtx = NULL; int nVtxSize; m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );"); if( vtx == NULL ) return; for( int n=0; 4 * nDepth > n; ) { int nRand = rand() % 150 + 255; vtx[n].position = K3DVector( (float)-m_nWidth/2.f, (float)-m_nHeight/2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 0.f; vtx[n].texcoord0.y = 0.f; n++; vtx[n].position = K3DVector( m_nWidth / 2.f, (float)-m_nHeight/2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 1.f; vtx[n].texcoord0.y = 0.f; n++; vtx[n].position = K3DVector( (float)-m_nWidth/2.f, m_nHeight / 2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 0.0f; vtx[n].texcoord0.y = 1.f; n++; vtx[n].position = K3DVector( m_nWidth / 2.f, m_nHeight / 2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 1.0f; vtx[n].texcoord0.y = 1.f; n++; } m_pVB->Unlock(); m_pVB->Backup(); m_spIB = NULL; // Index Buf m_spTexture = NULL; m_spAlphaTexture = NULL; m_pMat = new K3DMaterial; m_pMat->SetAmbient( K3DColor( 1.f, 1.f, 1.f, 1.f ) ); m_pMat->SetDiffuse( K3DColor( 1.f, 1.f, 1.f, 1.f ) ); m_pMat->SetSpecular( K3DColor( 0.f, 0.f, 0.f, 1.f ) ); m_pMat->SetSpecularPower( 1.0f ); m_pParentMat = NULL; // SkyBox 위치 K3DMatrixIdentity( m_LocalMat ); // 구름 위치 K3DMatrixIdentity( m_WorldMat ); m_pPrimitive = new SCloudPrimitive; // Render Object m_pPrimitive->SetTransparent( true ); m_pPrimitive->SetTransform( &m_LocalMat, &m_WorldMat ); m_pPrimitive->SetVertexBuffer( m_pVB ); m_pPrimitive->SetMaterial( m_pMat ); this->initCloudObjects(); } */ } void SCloudEx::Process( DWORD dwTime ) { /* if( IsProcessPause() ) return; if( m_pVB == NULL || !m_pVB->IsValidVtx() ) return; m_dwTime = dwTime; // [sonador] Lock / Unlock 을 짧은 시간에 수행하기 위해 update 를 분리하였음. for( int it = 0; it < m_nCloudCount; ++it ) { if( m_pCloud[ it ].IsActive() ) this->procesSCloudEx( it ); } K3DVERTEX_CLOUD* vtx = NULL; int nVtxSize; int nPrimCnt = 0; //D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨. #if defined( _DEBUG ) m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); #else m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_DISCARD ); #endif assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );"); if( vtx == NULL ) return; for(int it = 0; it < m_nCloudCount; ++it) { if( m_pCloud[ it ].IsActive() ) { this->updateVB( &vtx[ nPrimCnt * 4 ], m_pCloud[ it ] ); } else { vtx[ nPrimCnt * 4 + 0 ].color.a = 0; vtx[ nPrimCnt * 4 + 1 ].color.a = 0; vtx[ nPrimCnt * 4 + 2 ].color.a = 0; vtx[ nPrimCnt * 4 + 3 ].color.a = 0; } ++nPrimCnt; } m_pVB->Unlock(); m_pPrimitive->SetVertexCnt( nPrimCnt * 4 ); */ /*K3DMatrix mat; K3DMatrixIdentity( mat ); //K3DMatrixRotationAxis( &mat, m_pVecCloud, (10.f*K3D_PI/180.f) ); K3DMatrixIdentity( m_LocalMat ); K3DMatrixSetPosVector( m_LocalMat, m_Pos ); K3DMatrixMultiply( &m_LocalMat, &mat, &m_LocalMat ); if( m_pParentMat ) K3DMatrixMultiply( &m_LocalMat, &m_LocalMat, m_pParentMat );*/ } void SCloudEx::Render( KViewportObject *viewport ) { if( m_pPrimitive && m_pPrimitive->GetVertexCnt() > 0 ) { viewport->Register( m_pPrimitive, KRenderObject::RENDEREFX_CLOUD ); } } void SCloudEx::Create(int nType, int nCount, int nDepth, int nZoneWidth, int nZoneHeight) { if ( nType == 0 ) { ; } else if( nType == 0 ) { } else if( nType == 0 ) { } } void SCloudEx::Destroy() { } void SCloudEx::SetPosition( float x, float y, float z ) { if( vStartPosition.x == 0.f && vStartPosition.y == 0.f && vStartPosition.z == 0.f ) vStartPosition = vPosition; vPosition.Set( x, y, z ); } void SCloudEx::SetColor( const K3DColor& _color ) { color.r = (unsigned char)(_color.r * 255); color.g = (unsigned char)(_color.g * 255); color.b = (unsigned char)(_color.b * 255); } void SCloudEx::SetColor( const KColor& _color ) { color.r = _color.r; color.g = _color.g; color.b = _color.b; } void SCloudEx::SetVisibility( float _visibility ) { fVisibility = std::min( _visibility, fVisibilityCap ); fVisibility = std::max( 0.f, std::min( 1.0f, fVisibility ) ); color.a = (unsigned char)( 255 * fVisibility ); } void SCloudEx::SetVisibilityCap( float _cap ) { fVisibilityCap = _cap; } K3DVector SCloudEx::GetVertexPosition( EVtxPos _pos_type ) const { K3DVector vResult; switch( _pos_type ) { case UL: vResult.Set( vPosition.x - nWidth / 2.f, vPosition.y - nHeight / 2.f, vPosition.z ); break; case UR: vResult.Set( vPosition.x + nWidth / 2.f, vPosition.y - nHeight / 2.f, vPosition.z ); break; case BL: vResult.Set( vPosition.x - nWidth / 2.f, vPosition.y + nHeight / 2.f, vPosition.z ); break; case BR: vResult.Set( vPosition.x + nWidth / 2.f, vPosition.y + nHeight / 2.f, vPosition.z ); break; } return vResult; } void SCloudEx::checkStartTime( DWORD dwTime_msec_ ) { if( dwStartTime == 0 ) dwStartTime = dwTime_msec_; } void SCloudEx::ResetStartTime() { dwStartTime = 0; } void SCloudEx::resetPosition() { vPosition.x = (K3DVALUE)(-rand()%8000); vPosition.y = (K3DVALUE)(-rand()%8000); } void SCloudEx::ChangeStep( EStep step ) { eStep = step; //dwStartTime = 0; } void SCloudEx::processByStep( DWORD elapsed_time , const KColor& _cloud_color ) { //1)처음 나타나면, 0~1 서서히 나타난다. //2)모두 보이면, 이동 시작 //3)이동이 끝나면 1~0 서서히 사라진다. switch( eStep ) { case APPEAR: this->onAppear( elapsed_time ); break; case DISAPPEAR: this->onDisappear( elapsed_time ); break; case MOVE: this->onMove( elapsed_time ); break; default: break; } } void SCloudEx::movePosition() { vPosition.x += fRotSpeed; vPosition.y += fRotSpeed; } bool SCloudEx::IsOutOfBound() const { return ( vPosition.x > 1800.f || vPosition.y > 1800.f ); } void SCloudEx::Update( DWORD _time, const KColor& _cloud_color ) { this->checkStartTime( _time ); DWORD elapsed_time = _time - dwStartTime; this->SetColor( _cloud_color ); this->SetVisibilityCap( (float)_cloud_color.a / 255 ); this->processByStep( elapsed_time, _cloud_color ); this->movePosition(); if( this->IsOutOfBound() && !this->IsStep( DISAPPEAR ) ) { this->ChangeStep( DISAPPEAR ); this->ResetStartTime(); } } void SCloudEx::onAppear( DWORD elapsed_time ) { if ( elapsed_time > START_TIME ) { //종료 this->ChangeStep( MOVE ); this->ResetStartTime(); } else { this->SetVisibility( (float)elapsed_time / START_TIME ); } } void SCloudEx::onDisappear( DWORD elapsed_time ) { if( elapsed_time < END_TIME ) { this->SetVisibility( 1.f - ( (float)elapsed_time / END_TIME ) ); } else { //this->SetActivity( (rand() % 2) == 1 ); // 랜덤하게 활동여부를 설정하는 이유는? this->resetPosition(); this->ResetStartTime(); this->ChangeStep( APPEAR ); } } void SCloudEx::onMove( DWORD elapsed_time ) { this->SetVisibility( fVisibilityCap ); } // ======================================================================= // SGameCloud // ======================================================================= SGameCloud::SGameCloud( int cloud_count ) : m_dwTime ( 0 ) , m_nCloudCount ( cloud_count ) , m_CloudColor ( 255, 255, 255, 255 ) , m_pSoundMgr ( 0 ) , m_pDevice ( 0 ) { } SGameCloud::~SGameCloud() { SAFE_DELETE( m_pMat ); SAFE_DELETE_ARRAY( m_pCloud ); if( m_pVB ) m_pDevice->DelReloadVertexList( m_pVB ); } void SGameCloud::Init( K3DRenderDevice *pDevice, K3DIndexBuffer * pIndexBuf ) { m_pDevice = pDevice; DWORD dwFormat = 0; m_pVB = pDevice->CreateVertexBufferUsePoolDefault( sizeof(K3DVERTEX_CLOUD), dwFormat, 4*m_nCloudCount, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY ); //기본 사각형 if( m_pVB && m_pVB->IsValidVtx() ) { // m_spVB = pDevice->CreateVertexBufferBlend( sizeof(K3DBLENDEDBUMPVERTEX), dwFormat, 4*m_nCloudCount ); //기본 사각형 this->initVB(); m_spIB = NULL; // Index Buf m_spTexture = NULL; m_spAlphaTexture = NULL; m_pMat = new K3DMaterial; m_pMat->SetAmbient( K3DColor( 1.f, 1.f, 1.f, 1.f ) ); m_pMat->SetDiffuse( K3DColor( 1.f, 1.f, 1.f, 1.f ) ); m_pMat->SetSpecular( K3DColor( 0.f, 0.f, 0.f, 1.f ) ); m_pMat->SetSpecularPower( 1.0f ); m_pParentMat = NULL; // SkyBox 위치 K3DMatrixIdentity( m_LocalMat ); // 구름 위치 K3DMatrixIdentity( m_WorldMat ); m_pPrimitive = new SCloudPrimitive; // Render Object m_pPrimitive->SetTransparent( true ); m_pPrimitive->SetTransform( &m_LocalMat, &m_WorldMat ); m_pPrimitive->SetVertexBuffer( m_pVB ); m_pPrimitive->SetMaterial( m_pMat ); this->initCloudObjects(); } } void SGameCloud::Process( DWORD dwTime ) { if( IsProcessPause() ) return; if( m_pVB == NULL || !m_pVB->IsValidVtx() ) return; m_dwTime = dwTime; // [sonador] Lock / Unlock 을 짧은 시간에 수행하기 위해 update 를 분리하였음. for( int it = 0; it < m_nCloudCount; ++it ) { if( m_pCloud[ it ].IsActive() ) this->procesSCloudEx( it ); } K3DVERTEX_CLOUD* vtx = NULL; int nVtxSize; int nPrimCnt = 0; //D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨. #if defined( _DEBUG ) m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); #else m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_DISCARD ); #endif assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );"); if( vtx == NULL ) return; for(int it = 0; it < m_nCloudCount; ++it) { if( m_pCloud[ it ].IsActive() ) { this->updateVB( &vtx[ nPrimCnt * 4 ], m_pCloud[ it ] ); } else { vtx[ nPrimCnt * 4 + 0 ].color.a = 0; vtx[ nPrimCnt * 4 + 1 ].color.a = 0; vtx[ nPrimCnt * 4 + 2 ].color.a = 0; vtx[ nPrimCnt * 4 + 3 ].color.a = 0; } ++nPrimCnt; } m_pVB->Unlock(); m_pPrimitive->SetVertexCnt( nPrimCnt * 4 ); /*K3DMatrix mat; K3DMatrixIdentity( mat ); //K3DMatrixRotationAxis( &mat, m_pVecCloud, (10.f*K3D_PI/180.f) ); K3DMatrixIdentity( m_LocalMat ); K3DMatrixSetPosVector( m_LocalMat, m_Pos ); K3DMatrixMultiply( &m_LocalMat, &mat, &m_LocalMat ); if( m_pParentMat ) K3DMatrixMultiply( &m_LocalMat, &m_LocalMat, m_pParentMat );*/ } void SGameCloud::Render( KViewportObject *viewport ) { if( m_pPrimitive && m_pPrimitive->GetVertexCnt() > 0 ) { viewport->Register( m_pPrimitive, KRenderObject::RENDEREFX_CLOUD ); } } void SGameCloud::SetHeight( int i, float fz ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[i].vPosition.z = fz; } else { assert( !"SGameCloud : refered wrong index" ); } //if( m_pThunderCloud ) // m_pThunderCloud->SetHeight( i, fz ); } void SGameCloud::SetPosition( int i, float fx, float fy, float fz ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[i].SetPosition( fx, fy, fz ); } else { assert( !"SGameCloud : refered wrong index" ); } //if( m_pThunderCloud ) // m_pThunderCloud->SetPosition( i, fz, fy, fz ); } void SGameCloud::SetMaxVisibility( int i, float fVis ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[i].SetVisibilityCap( fVis ); } else { assert( !"SGameCloud : refered wrong index" ); } //if( m_pThunderCloud ) // m_pThunderCloud->SetMaxVisibility( i, fVis ); } void SGameCloud::SetVisibility( int i, float fVis ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[i].SetVisibility( fVis ); } else { assert( !"SGameCloud : refered wrong index" ); } //if( m_pThunderCloud ) // m_pThunderCloud->SetVisibility( i, fVis ); } void SGameCloud::SetCloudColor( int i, K3DColor & color ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[ i ].SetColor( color ); } else { assert(0); } //if( m_pThunderCloud ) // m_pThunderCloud->SetCloudColor( i, color ); } void SGameCloud::SetCloudColor( KColor & color ) { m_CloudColor = color; } void SGameCloud::SetTransform( K3DMatrix* pParentMatrix ) { SetParentMat( pParentMatrix ); m_pPrimitive->SetTransform( pParentMatrix, pParentMatrix ); } SCloudEx* SGameCloud::GetFirstDeactiveCloud() { SCloudEx* pCloud = std::find_if( &m_pCloud[ 0 ], &m_pCloud[ m_nCloudCount ], SFindFirstDeactiveCloud() ); if( pCloud != &m_pCloud[ m_nCloudCount ] ) return pCloud; return 0; } void SGameCloud::SetSoundManager( SGameMilesSoundMgr* pSoundMgr ) { m_pSoundMgr = pSoundMgr; } void SGameCloud::initVB() { K3DVERTEX_CLOUD* vtx = NULL; int nVtxSize; m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );"); if( vtx == NULL ) return; for( int n=0; 4 * m_nCloudCount > n; ) { int nRand = rand() % 150 + 255; vtx[n].position = K3DVector( (float)-m_nWidth/2.f, (float)-m_nHeight/2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 0.f; vtx[n].texcoord0.y = 0.f; //vtx[n].texcoord1.x = 0.f; //vtx[n].texcoord1.y = 0.f; n++; vtx[n].position = K3DVector( m_nWidth / 2.f, (float)-m_nHeight/2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 1.f; vtx[n].texcoord0.y = 0.f; //vtx[n].texcoord1.x = 1.f; //vtx[n].texcoord1.y = 0.f; n++; vtx[n].position = K3DVector( (float)-m_nWidth/2.f, m_nHeight / 2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 0.0f; vtx[n].texcoord0.y = 1.f; //vtx[n].texcoord1.x = 0.0f; //vtx[n].texcoord1.y = 1.f; n++; vtx[n].position = K3DVector( m_nWidth / 2.f, m_nHeight / 2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 1.0f; vtx[n].texcoord0.y = 1.f; //vtx[n].texcoord1.x = 1.0f; //vtx[n].texcoord1.y = 1.f; n++; } m_pVB->Unlock(); m_pVB->Backup(); } void SGameCloud::updateVB( K3DVERTEX_CLOUD* vtx, const SCloudEx& cloud ) { vtx[ 0 ].position = cloud.GetVertexPosition( SCloudEx::UL ); vtx[ 1 ].position = cloud.GetVertexPosition( SCloudEx::UR ); vtx[ 2 ].position = cloud.GetVertexPosition( SCloudEx::BL ); vtx[ 3 ].position = cloud.GetVertexPosition( SCloudEx::BR ); for( short p = 0; p < 4; p++) { vtx[ p ].color = cloud.color; vtx[ p ].normal = K3DVector( 0.f, 0.f, -1.f); } vtx[ 0 ].texcoord0.Set( 0, 0 ); vtx[ 1 ].texcoord0.Set( 1, 0 ); vtx[ 2 ].texcoord0.Set( 0, 1 ); vtx[ 3 ].texcoord0.Set( 1, 1 ); //vtx[ 0 ].texcoord1.Set( 0, 0 ); //vtx[ 1 ].texcoord1.Set( 1, 0 ); //vtx[ 2 ].texcoord1.Set( 0, 1 ); //vtx[ 3 ].texcoord1.Set( 1, 1 ); } void SGameCloud::initCloudObjects() { m_pCloud = new SCloudEx[ m_nCloudCount ]; for(int i = 0; i < m_nCloudCount; ++i) { m_pCloud[i].nWidth = 1000+rand()/16000;//(float)(rand()/10000)+1400; m_pCloud[i].nHeight = 1000+rand()/10000;//(float)(rand()/10000)+1400; m_pCloud[i].dwStartTime = 0; m_pCloud[i].dwOldTime = 0; m_pCloud[i].fRotSpeed = fRotSpeed[0/*rand()%5*/]; m_pCloud[i].fVisibility = 0.8f; m_pCloud[i].eStep = SCloudEx::MOVE; } } void SGameCloud::procesSCloudEx( int nIndex ) { assert( nIndex >= 0 && nIndex < m_nCloudCount && "wrong index" ); m_pCloud[ nIndex ].Update( m_dwTime, m_CloudColor ); } void SGameCloud::_addSoundEvent( const K3DVector& addedPosition ) { SSoundEvent* se = new SSoundEvent(); se->activeTime = m_dwTime + (DWORD)( addedPosition.Magnitude() ); se->activePos = addedPosition; m_ctSoundEvents.push( se ); } void SGameCloud::_procSoundEvent() { while( !m_ctSoundEvents.empty() ) { SSoundEvent* se = 0; se = m_ctSoundEvents.front(); if( se->activeTime >= m_dwTime ) { //if( m_pSoundMgr ) //{ // m_pSoundMgr->PlaySound3D( // SCloudEx::s_strSound.c_str(), // se->activePos.x, se->activePos.y, se->activePos.z, // 100, false, false, false ); // //} SAFE_DELETE( se ); m_ctSoundEvents.pop(); continue; } break; } } void SGameCloud::CreateCloudByType( int type ) { DestroyCloud(); if(type == 0) { int nCount = 15; m_vcCloud.resize(nCount); for(int x=0; xonAppear( elapsed_time ); break; case DISAPPEAR: this->onDisappear( elapsed_time ); break; case MOVE: this->onMove( elapsed_time ); break; case THUNDER: this->onThunder( elapsed_time ); break; default: break; } } void SCloudObject::movePosition() { vPosition.x += fRotSpeed; vPosition.y += fRotSpeed; } bool SCloudObject::IsOutOfBound() const { return ( vPosition.x > 1800.f || vPosition.y > 1800.f ); } void SCloudObject::Update( DWORD _time, const KColor& _cloud_color ) { this->checkStartTime( _time ); DWORD elapsed_time = _time - dwStartTime; this->SetColor( _cloud_color ); this->SetVisibilityCap( (float)_cloud_color.a / 255 ); this->processByStep( elapsed_time, _cloud_color ); this->movePosition(); if( this->IsOutOfBound() && !this->IsStep( DISAPPEAR ) ) { this->ChangeStep( DISAPPEAR ); this->ResetStartTime(); } } void SCloudObject::onAppear( DWORD elapsed_time ) { if ( elapsed_time > START_TIME ) { //종료 this->ChangeStep( MOVE ); this->ResetStartTime(); } else { this->SetVisibility( (float)elapsed_time / START_TIME ); } } void SCloudObject::onDisappear( DWORD elapsed_time ) { if( elapsed_time < END_TIME ) { this->SetVisibility( 1.f - ( (float)elapsed_time / END_TIME ) ); } else { //this->SetActivity( (rand() % 2) == 1 ); // 랜덤하게 활동여부를 설정하는 이유는? this->resetPosition(); this->ResetStartTime(); this->ChangeStep( APPEAR ); } } void SCloudObject::onMove( DWORD elapsed_time ) { this->SetVisibility( fVisibilityCap ); } void SCloudObject::onThunder( DWORD elapsed_time ) { this->SetVisibility( fVisibilityCap ); if( elapsed_time <= s_dwDuration + dwThunderBegin ) { float ftheta = K3D_PI * (float)( elapsed_time - dwThunderBegin ) * s_nFlashCount / (float)s_dwDuration; float fwave = sinf( ftheta ); fwave = fabs( fwave ); color.a = (unsigned char)( fwave * 255.0f ); } else { this->ChangeStep( MOVE ); } } SThunderCloudObject::SThunderCloudObject() : SCloudObject() { } SThunderCloudObject::~SThunderCloudObject() { } void SThunderCloudObject::onAppear( DWORD elapsed_time ) { this->SetActivity( false ); } void SThunderCloudObject::onDisappear( DWORD elapsed_time ) { this->SetActivity( false ); } void SThunderCloudObject::onMove( DWORD elapsed_time ) { this->SetActivity( false ); } void SThunderCloudObject::onThunder( DWORD elapsed_time ) { this->SetVisibility( fVisibilityCap ); if( elapsed_time <= s_dwDuration + dwThunderBegin ) { float ftheta = K3D_PI * (float)( elapsed_time - dwThunderBegin ) * s_nFlashCount / (float)s_dwDuration; float fwave = sinf( ftheta ); fwave = fabs( fwave ); color.a = (unsigned char)( fwave * 255.0f ); } else { this->SetActivity( false ); } } SGameCloud::SGameCloud( int cloud_count ) : m_dwTime ( 0 ) , m_nCloudCount ( cloud_count ) , m_CloudColor ( 255, 255, 255, 255 ) , m_bEnableThunder ( false ) , m_pThunderCloud ( 0 ) , m_pLightning ( 0 ) , m_pSoundMgr ( 0 ) , m_pDevice ( 0 ) { } SGameCloud::~SGameCloud() { SAFE_DELETE( m_pMat ); SAFE_DELETE_ARRAY( m_pCloud ); if( m_pVB ) m_pDevice->DelReloadVertexList( m_pVB ); } void SGameCloud::Init( K3DRenderDevice *pDevice, K3DIndexBuffer * pIndexBuf ) { m_pDevice = pDevice; DWORD dwFormat = 0; m_pVB = pDevice->CreateVertexBufferUsePoolDefault( sizeof(K3DVERTEX_CLOUD), dwFormat, 4*m_nCloudCount, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY ); //기본 사각형 if( m_pVB && m_pVB->IsValidVtx() ) { // m_spVB = pDevice->CreateVertexBufferBlend( sizeof(K3DBLENDEDBUMPVERTEX), dwFormat, 4*m_nCloudCount ); //기본 사각형 this->initVB(); m_spIB = NULL; // Index Buf m_spTexture = NULL; m_spAlphaTexture = NULL; m_pMat = new K3DMaterial; m_pMat->SetAmbient( K3DColor( 1.f, 1.f, 1.f, 1.f ) ); m_pMat->SetDiffuse( K3DColor( 1.f, 1.f, 1.f, 1.f ) ); m_pMat->SetSpecular( K3DColor( 0.f, 0.f, 0.f, 1.f ) ); m_pMat->SetSpecularPower( 1.0f ); m_pParentMat = NULL; // SkyBox 위치 K3DMatrixIdentity( m_LocalMat ); // 구름 위치 K3DMatrixIdentity( m_WorldMat ); m_pPrimitive = new SCloudPrimitive; // Render Object m_pPrimitive->SetTransparent( true ); m_pPrimitive->SetTransform( &m_LocalMat, &m_WorldMat ); m_pPrimitive->SetVertexBuffer( m_pVB ); m_pPrimitive->SetMaterial( m_pMat ); this->initCloudObjects(); } } void SGameCloud::Process( DWORD dwTime ) { if( IsProcessPause() ) return; if( m_pVB == NULL || !m_pVB->IsValidVtx() ) return; m_dwTime = dwTime; // [sonador] Lock / Unlock 을 짧은 시간에 수행하기 위해 update 를 분리하였음. for( int it = 0; it < m_nCloudCount; ++it ) { if( m_pCloud[ it ].IsActive() ) this->processCloudObject( it ); } K3DVERTEX_CLOUD* vtx = NULL; int nVtxSize; int nPrimCnt = 0; //D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨. #if defined( _DEBUG ) m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); #else m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_DISCARD ); #endif assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );"); if( vtx == NULL ) return; for(int it = 0; it < m_nCloudCount; ++it) { if( m_pCloud[ it ].IsActive() ) { this->updateVB( &vtx[ nPrimCnt * 4 ], m_pCloud[ it ] ); } else { vtx[ nPrimCnt * 4 + 0 ].color.a = 0; vtx[ nPrimCnt * 4 + 1 ].color.a = 0; vtx[ nPrimCnt * 4 + 2 ].color.a = 0; vtx[ nPrimCnt * 4 + 3 ].color.a = 0; } ++nPrimCnt; } m_pVB->Unlock(); m_pPrimitive->SetVertexCnt( nPrimCnt * 4 ); /*K3DMatrix mat; K3DMatrixIdentity( mat ); //K3DMatrixRotationAxis( &mat, m_pVecCloud, (10.f*K3D_PI/180.f) ); K3DMatrixIdentity( m_LocalMat ); K3DMatrixSetPosVector( m_LocalMat, m_Pos ); K3DMatrixMultiply( &m_LocalMat, &mat, &m_LocalMat ); if( m_pParentMat ) K3DMatrixMultiply( &m_LocalMat, &m_LocalMat, m_pParentMat );*/ } void SGameCloud::Render( KViewportObject *viewport ) { if( m_pPrimitive && m_pPrimitive->GetVertexCnt() > 0 ) { viewport->Register( m_pPrimitive, KRenderObject::RENDEREFX_CLOUD ); } } void SGameCloud::SetHeight( int i, float fz ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[i].vPosition.z = fz; } else { assert( !"SGameCloud : refered wrong index" ); } //if( m_pThunderCloud ) // m_pThunderCloud->SetHeight( i, fz ); } void SGameCloud::SetPosition( int i, float fx, float fy, float fz ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[i].SetPosition( fx, fy, fz ); } else { assert( !"SGameCloud : refered wrong index" ); } //if( m_pThunderCloud ) // m_pThunderCloud->SetPosition( i, fz, fy, fz ); } void SGameCloud::SetMaxVisibility( int i, float fVis ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[i].SetVisibilityCap( fVis ); } else { assert( !"SGameCloud : refered wrong index" ); } //if( m_pThunderCloud ) // m_pThunderCloud->SetMaxVisibility( i, fVis ); } void SGameCloud::SetVisibility( int i, float fVis ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[i].SetVisibility( fVis ); } else { assert( !"SGameCloud : refered wrong index" ); } //if( m_pThunderCloud ) // m_pThunderCloud->SetVisibility( i, fVis ); } void SGameCloud::SetCloudColor( int i, K3DColor & color ) { if( i >=0 && i < m_nCloudCount ) { m_pCloud[ i ].SetColor( color ); } else { assert(0); } //if( m_pThunderCloud ) // m_pThunderCloud->SetCloudColor( i, color ); } void SGameCloud::SetCloudColor( KColor & color ) { m_CloudColor = color; if( m_pThunderCloud ) m_pThunderCloud->SetCloudColor( color ); } void SGameCloud::SetEnableThunderFx( bool bEnable ) { m_bEnableThunder = bEnable; } void SGameCloud::SetThunderCloud( SGameCloud* pThunderCloud ) { m_pThunderCloud = pThunderCloud; } void SGameCloud::SetLightning( env_fx::SGameLightning* pLightning ) { m_pLightning = pLightning; } void SGameCloud::SetTransform( K3DMatrix* pParentMatrix ) { SetParentMat( pParentMatrix ); m_pPrimitive->SetTransform( pParentMatrix, pParentMatrix ); if( m_pThunderCloud ) m_pThunderCloud->SetTransform( pParentMatrix ); if( m_pLightning ) m_pLightning->SetParentMatrix( pParentMatrix ); } SCloudObject* SGameCloud::GetFirstDeactiveCloud() { SCloudObject* pCloud = std::find_if( &m_pCloud[ 0 ], &m_pCloud[ m_nCloudCount ], SFindFirstDeactiveCloud() ); if( pCloud != &m_pCloud[ m_nCloudCount ] ) return pCloud; return 0; } void SGameCloud::SetSoundManager( SGameMilesSoundMgr* pSoundMgr ) { m_pSoundMgr = pSoundMgr; } void SGameCloud::initVB() { K3DVERTEX_CLOUD* vtx = NULL; int nVtxSize; m_pVB->Lock( (void**)&vtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); assert(vtx && "m_pVB->Lock( (void**)&vtx, nVtxSize );"); if( vtx == NULL ) return; for( int n=0; 4 * m_nCloudCount > n; ) { int nRand = rand() % 150 + 255; vtx[n].position = K3DVector( (float)-m_nWidth/2.f, (float)-m_nHeight/2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 0.f; vtx[n].texcoord0.y = 0.f; //vtx[n].texcoord1.x = 0.f; //vtx[n].texcoord1.y = 0.f; n++; vtx[n].position = K3DVector( m_nWidth / 2.f, (float)-m_nHeight/2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 1.f; vtx[n].texcoord0.y = 0.f; //vtx[n].texcoord1.x = 1.f; //vtx[n].texcoord1.y = 0.f; n++; vtx[n].position = K3DVector( (float)-m_nWidth/2.f, m_nHeight / 2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 0.0f; vtx[n].texcoord0.y = 1.f; //vtx[n].texcoord1.x = 0.0f; //vtx[n].texcoord1.y = 1.f; n++; vtx[n].position = K3DVector( m_nWidth / 2.f, m_nHeight / 2.f, 0 ); vtx[n].color = m_CloudColor; vtx[n].color.a = nRand; vtx[n].normal = K3DVector( 0.f, 0.f, -1.f); vtx[n].texcoord0.x = 1.0f; vtx[n].texcoord0.y = 1.f; //vtx[n].texcoord1.x = 1.0f; //vtx[n].texcoord1.y = 1.f; n++; } m_pVB->Unlock(); m_pVB->Backup(); } void SGameCloud::updateVB( K3DVERTEX_CLOUD* vtx, const SCloudObject& cloud ) { vtx[ 0 ].position = cloud.GetVertexPosition( SCloudObject::UL ); vtx[ 1 ].position = cloud.GetVertexPosition( SCloudObject::UR ); vtx[ 2 ].position = cloud.GetVertexPosition( SCloudObject::BL ); vtx[ 3 ].position = cloud.GetVertexPosition( SCloudObject::BR ); for( short p = 0; p < 4; p++) { vtx[ p ].color = cloud.color; vtx[ p ].normal = K3DVector( 0.f, 0.f, -1.f); } vtx[ 0 ].texcoord0.Set( 0, 0 ); vtx[ 1 ].texcoord0.Set( 1, 0 ); vtx[ 2 ].texcoord0.Set( 0, 1 ); vtx[ 3 ].texcoord0.Set( 1, 1 ); //vtx[ 0 ].texcoord1.Set( 0, 0 ); //vtx[ 1 ].texcoord1.Set( 1, 0 ); //vtx[ 2 ].texcoord1.Set( 0, 1 ); //vtx[ 3 ].texcoord1.Set( 1, 1 ); } void SGameCloud::initCloudObjects() { m_pCloud = new SCloudObject[ m_nCloudCount ]; for(int i = 0; i < m_nCloudCount; ++i) { m_pCloud[i].nWidth = 1000+rand()/16000;//(float)(rand()/10000)+1400; m_pCloud[i].nHeight = 1000+rand()/10000;//(float)(rand()/10000)+1400; m_pCloud[i].dwStartTime = 0; m_pCloud[i].dwOldTime = 0; m_pCloud[i].fRotSpeed = fRotSpeed[0/*rand()%5*/]; m_pCloud[i].fVisibility = 0.8f; m_pCloud[i].eStep = SCloudObject::MOVE; } } void SGameCloud::processCloudObject( int nIndex ) { assert( nIndex >= 0 && nIndex < m_nCloudCount && "wrong index" ); m_pCloud[ nIndex ].Update( m_dwTime, m_CloudColor ); if( m_bEnableThunder && m_pThunderCloud && m_pCloud[ nIndex ].IsStep( SCloudObject::MOVE ) && (float)( rand() % 100000 ) * 0.001f <= SCloudObject::s_fFactor ) { SCloudObject* pCloud = m_pThunderCloud->GetFirstDeactiveCloud(); if( pCloud ) { pCloud->SetActivity( true ); pCloud->ResetStartTime(); pCloud->vPosition = m_pCloud[ nIndex ].vPosition; pCloud->vPosition.z = DEFAULT_HEIGHT_THUNDER_CLOUD; pCloud->ChangeStep( SCloudObject::THUNDER ); pCloud->nWidth = m_pCloud[ nIndex ].nWidth; pCloud->nHeight = m_pCloud[ nIndex ].nHeight; } // make lightning effect if( m_pLightning ) { float fRand = env_fx::util::GetRandomNumberInRange( 0.0f, 100.0f ); if( fRand <= SCloudObject::s_fLightningFactor ) { //bLightningEnable = true; m_pLightning->Emit( m_pCloud[ nIndex ].vPosition ); if( SCloudObject::s_strSound.size() > 0 ) _addSoundEvent( m_pCloud[ nIndex ].vPosition ); } } } } void SGameCloud::_addSoundEvent( const K3DVector& addedPosition ) { SSoundEvent* se = new SSoundEvent(); se->activeTime = m_dwTime + (DWORD)( SCloudObject::s_fSoundSpeed * addedPosition.Magnitude() ); se->activePos = addedPosition; m_ctSoundEvents.push( se ); } void SGameCloud::_procSoundEvent() { while( !m_ctSoundEvents.empty() ) { SSoundEvent* se = 0; se = m_ctSoundEvents.front(); if( se->activeTime >= m_dwTime ) { //if( m_pSoundMgr ) //{ // m_pSoundMgr->PlaySound3D( // SCloudObject::s_strSound.c_str(), // se->activePos.x, se->activePos.y, se->activePos.z, // 100, false, false, false ); // //} SAFE_DELETE( se ); m_ctSoundEvents.pop(); continue; } break; } } SGameThunderCloud::SGameThunderCloud( int cloud_count ) : SGameCloud ( cloud_count ) { } SGameThunderCloud::~SGameThunderCloud() { } void SGameThunderCloud::initCloudObjects() { m_pCloud = new SThunderCloudObject[ m_nCloudCount ]; for(int i = 0; i < m_nCloudCount; ++i) { m_pCloud[i].nWidth = 1000+rand()/16000;//(float)(rand()/10000)+1400; m_pCloud[i].nHeight = 1000+rand()/10000;//(float)(rand()/10000)+1400; m_pCloud[i].dwStartTime = 0; m_pCloud[i].dwOldTime = 0; m_pCloud[i].fRotSpeed = fRotSpeed[0/*rand()%5*/]; m_pCloud[i].fVisibility = 0.8f; m_pCloud[i].eStep = SCloudObject::MOVE; } } #endif #ifdef CLOUD_LUA //--------------------------------------------------------------------------------------- // Kind CCloudKindDB& GetCloudKindDB() { return *g_pCloudKindDB; } CCloudKindDB::CCloudKindDB() { } CCloudKindDB::~CCloudKindDB() { clear(); } void CCloudKindDB::add(int id, SCloudKind* pKind) { if( pKind ) m_vcKind.push_back( pKind ); } void CCloudKindDB::clear() { for(int i = 0; i < (int)m_vcKind.size(); ++i) { SCloudKind* p = m_vcKind[ i ]; SAFE_DELETE( p ); } m_vcKind.clear(); } void CCloudKindDB::size(int sz) { clear(); } SCloudKind* CCloudKindDB::find(int id) { int k=0; return m_vcKind[ id ]; } float CCloudKindDB::calculateRate(int nKindID, int nGrade, int nMaxGrade) { // 9 : nTickness = ? : k // ? = 9 x k / nTickness // 9 : 33 = ? : 4 // ? = 9 * 4 / 33 double dbMock = 0.0f; double nKindGapID = double( ( (float)nGrade * MAX_KIND_GRADE_F ) / (float)nMaxGrade ); float fNamujiRate = (float)modf(nKindGapID, &dbMock); int nMock = (int)dbMock; float fSZ0, fSZ1; if ( nMock >= MAX_KIND_GRADE - 1 ) // 몫이 마지막이면 { fSZ1 = (float)m_vcKind[ nKindID ]->v[ MAX_KIND_GRADE - 1 ] * RATE_CONVERT_100; fSZ0 = (float)m_vcKind[ nKindID ]->v[ MAX_KIND_GRADE - 2 ] * RATE_CONVERT_100; } else if( nMock == 0 ) // 몫이 처음이면 { fSZ1 = (float)m_vcKind[ nKindID ]->v[ 1 ] * RATE_CONVERT_100; fSZ0 = (float)m_vcKind[ nKindID ]->v[ 0 ] * RATE_CONVERT_100; } else { fSZ1 = (float)m_vcKind[ nKindID ]->v[ nMock + 1 ] * RATE_CONVERT_100; fSZ0 = (float)m_vcKind[ nKindID ]->v[ nMock ] * RATE_CONVERT_100; } float fRate = fSZ0 - ( (fSZ0 - fSZ1) * fNamujiRate ); if( fRate > 1.0f ) // 사실 이건 에러임!! fRate = 1.0f; return fRate; } //--------------------------------------------------------------------------------------- // thickness CCloudThicknessDB& GetCloudThicknessDB() { return *g_pCloudThicknesDB; } CCloudThicknessDB::CCloudThicknessDB() { } CCloudThicknessDB::~CCloudThicknessDB() { clear(); } void CCloudThicknessDB::add(int id, int nThickness) { if( nThickness ) m_vcTickness.push_back( nThickness ); } void CCloudThicknessDB::clear() { m_vcTickness.clear(); } void CCloudThicknessDB::size(int sz) { clear(); } int CCloudThicknessDB::find(int id) { return m_vcTickness[ id ]; } //--------------------------------------------------------------------------------------- // thickness gap CCloudThicknessGapDB& GetCloudThicknessGapDB() { return *g_pCloudThicknessGapDB; } CCloudThicknessGapDB::CCloudThicknessGapDB() { } CCloudThicknessGapDB::~CCloudThicknessGapDB() { clear(); } void CCloudThicknessGapDB::add(int id, float fThickness) { if( fThickness > 0.0f ) m_vcTicknessGap.push_back( fThickness ); } void CCloudThicknessGapDB::clear() { m_vcTicknessGap.clear(); } void CCloudThicknessGapDB::size(int sz) { clear(); } float CCloudThicknessGapDB::find(int id) { return m_vcTicknessGap[ id ]; } //--------------------------------------------------------------------------------------- // Size CCloudSizeDB& GetCloudSizeDB() { return *g_pCloudSizeDB; } CCloudSizeDB::CCloudSizeDB() { } CCloudSizeDB::~CCloudSizeDB() { clear(); } void CCloudSizeDB::add(int id, SCloudSize* pSize) { int k=0; if( pSize ) m_vcSize.push_back( pSize ); } void CCloudSizeDB::clear() { for(int i = 0; i < (int)m_vcSize.size(); ++i) { SCloudSize* p = m_vcSize[ i ]; SAFE_DELETE( p ); } m_vcSize.clear(); } void CCloudSizeDB::size(int sz) { clear(); m_vcSize.resize(sz); } SCloudSize* CCloudSizeDB::find(int id) { int k=0; return m_vcSize[ id ]; } //--------------------------------------------------------------------------------------- // texture names CCloudTxrNames::CCloudTxrNames() { } CCloudTxrNames::~CCloudTxrNames() { clear(); } void CCloudTxrNames::add(int id, std::string* pStrTxrName) { if( pStrTxrName ) m_vcName.push_back( pStrTxrName ); } void CCloudTxrNames::clear() { for(int i = 0; i < (int)m_vcName.size(); ++i) { std::string* p = m_vcName[ i ]; SAFE_DELETE( p ); } m_vcName.clear(); } void CCloudTxrNames::size(int sz) { clear(); } std::string* CCloudTxrNames::find(int id) { if( id >= 0 && id < (int)m_vcName.size() ) return m_vcName[ id ]; return NULL; } // texture name group CCloudTxrGroupDB& GetCloudTxrGroupDB() { return *g_pCloudTxrGroupDB;; } CCloudTxrGroupDB::CCloudTxrGroupDB() { } CCloudTxrGroupDB::~CCloudTxrGroupDB() { clear(); } int CCloudTxrGroupDB::get_size(int brightness_type) { if ( brightness_type == NORMAL ) return (int)m_vcNormal.size(); else if( brightness_type == MIDDLE ) return (int)m_vcMiddle.size(); else if( brightness_type == DARK ) return (int)m_vcDark.size(); return 0; } void CCloudTxrGroupDB::add(int brightness_type, int id, CCloudTxrNames* pTxrNames) { int k=0; if (brightness_type == NORMAL) { m_vcNormal.push_back( pTxrNames ); } else if(brightness_type == MIDDLE) { m_vcMiddle.push_back( pTxrNames ); } else if(brightness_type == DARK) { m_vcDark.push_back( pTxrNames ); } } void CCloudTxrGroupDB::clear(int brightness_type) { if (brightness_type == NORMAL) { for(int i = 0; i < (int)m_vcNormal.size(); ++i) { CCloudTxrNames* p = m_vcNormal[ i ]; SAFE_DELETE( p ); } m_vcNormal.clear(); } else if(brightness_type == MIDDLE) { for(int i = 0; i < (int)m_vcMiddle.size(); ++i) { CCloudTxrNames* p = m_vcMiddle[ i ]; SAFE_DELETE( p ); } m_vcMiddle.clear(); } else if(brightness_type == DARK) { for(int i = 0; i < (int)m_vcDark.size(); ++i) { CCloudTxrNames* p = m_vcDark[ i ]; SAFE_DELETE( p ); } m_vcDark.clear(); } else if(brightness_type == END) { clear( NORMAL ); clear( MIDDLE ); clear( DARK ); } } void CCloudTxrGroupDB::size(int brightness_type, int sz) { if (brightness_type == NORMAL) { clear( brightness_type ); } else if(brightness_type == MIDDLE) { clear( brightness_type ); } else if(brightness_type == DARK) { clear( brightness_type ); } } CCloudTxrNames* CCloudTxrGroupDB::find(int brightness_type, int id) { if (brightness_type == NORMAL) { if( id >= 0 && id < (int)m_vcNormal.size() ) return m_vcNormal[ id ]; } else if(brightness_type == MIDDLE) { if( id >= 0 && id < (int)m_vcMiddle.size() ) return m_vcMiddle[ id ]; } else if(brightness_type == DARK) { if( id >= 0 && id < (int)m_vcDark.size() ) return m_vcDark[ id ]; } return NULL; } std::string* CCloudTxrGroupDB::find_str(int brightness_type, int id) { CCloudTxrNames* pCloudTxrName = GetCloudTxrGroupDB().find( brightness_type, id ); if( pCloudTxrName ) { return pCloudTxrName->find( GetSafeTickCount() % (pCloudTxrName->get_size()) ); } else { _oprint( "CCloudTxrNames : not find texturename" ); } } //--------------------------------------------------------------------------------------- // thickness CCloudDistributionDB& GetCloudDistributionDB() { return *g_pCloudDistributionDB; } CCloudDistributionDB::CCloudDistributionDB() { } CCloudDistributionDB::~CCloudDistributionDB() { clear(); } void CCloudDistributionDB::add(int id, int nDistribution) { if( nDistribution ) m_vcDistribution.push_back( nDistribution ); } void CCloudDistributionDB::clear() { m_vcDistribution.clear(); } void CCloudDistributionDB::size(int sz) { clear(); } int CCloudDistributionDB::find(int id) { return m_vcDistribution[ id ]; } //--------------------------------------------------------------------------------------- // distribution CCloudHeightRadomGapDB& GetCloudHeightRadomGapDB() { return *g_pCloudHeightRadomGapDB; } CCloudHeightRadomGapDB::CCloudHeightRadomGapDB() { } CCloudHeightRadomGapDB::~CCloudHeightRadomGapDB() { clear(); } void CCloudHeightRadomGapDB::add(int id, int nRadomGap) { m_vcRadomGap.push_back( nRadomGap ); } void CCloudHeightRadomGapDB::clear() { m_vcRadomGap.clear(); } void CCloudHeightRadomGapDB::size(int sz) { clear(); } int CCloudHeightRadomGapDB::find(int id) { return m_vcRadomGap[ id ]; } //--------------------------------------------------------------------------------------- // layer gap CCloudLayerGapDB& GetCloudLayerGapDB() { return *g_pCloudCloudLayerGapDB; } CCloudLayerGapDB::CCloudLayerGapDB() { } CCloudLayerGapDB::~CCloudLayerGapDB() { clear(); } void CCloudLayerGapDB::add(int id, int nLayerGap) { m_vcLayerGap.push_back( nLayerGap ); } void CCloudLayerGapDB::clear() { m_vcLayerGap.clear(); } void CCloudLayerGapDB::size(int sz) { clear(); } int CCloudLayerGapDB::find(int id) { return m_vcLayerGap[ id ]; } //--------------------------------------------------------------------------------------- // layer gap CCloudMoveDirDB& GetCloudMoveDirDB() { return *g_pCloudCloudMoveDirDB; } CCloudMoveDirDB::CCloudMoveDirDB() { } CCloudMoveDirDB::~CCloudMoveDirDB() { clear(); } void CCloudMoveDirDB::add(int id, int nMoveDir) { m_vcMoveDir.push_back( nMoveDir ); } void CCloudMoveDirDB::clear() { m_vcMoveDir.clear(); } void CCloudMoveDirDB::size(int sz) { clear(); } int CCloudMoveDirDB::find(int id) { return m_vcMoveDir[ id ]; } //--------------------------------------------------------------------------------------- // path CCloudPathDB& GetCloudPathDB() { return *g_pCloudPathDB; } CCloudPathDB::CCloudPathDB() { } CCloudPathDB::~CCloudPathDB() { clear(); } void CCloudPathDB::add(int id, SCloudPath* pPath) { if( pPath ) m_vcPath.push_back( pPath ); } void CCloudPathDB::clear() { for(int i = 0; i < (int)m_vcPath.size(); ++i) { SCloudPath* p = m_vcPath[ i ]; SAFE_DELETE( p ); } m_vcPath.clear(); } void CCloudPathDB::size(int sz) { clear(); } SCloudPath* CCloudPathDB::find(int id) { return m_vcPath[ id ]; } float CCloudPathDB::calculateHeight(SCalculateHeightParam& sParam) { //----------------------------------------------- // y // ↑┌─────┐ N // ││ → → → │ ↑ // ││ ← ← ← │ │ // ││ ↓ ↑ │ W ←─┼─→ E // ││ ↓ ↑ │ │ // ││ │ ↓ // │└─────┘ S // 0 ──────→x //----------------------------------------------- // max // * // * * // * * // * * // start finish //----------------------------------------------- if( sParam.nPathType < 0 || sParam.nPathType >= (int)m_vcPath.size() ) return 0.0f; int nLayerGap = 0; if( sParam.nLayerGapType > 0 ) // 0번 타입은 기본 경로를 사용, 0번 타입보다 클때만 적용한다 nLayerGap = GetCloudLayerGapDB().find( sParam.nLayerGapType ); // x : (zonex / 2) = ? : max // ? = max * x / (zonex / 2) SCloudPath* pPath = m_vcPath[ sParam.nPathType ]; int max = pPath->max + nLayerGap; float fMaxHeight = float(max); float fHalfWidth = sParam.zoneX / 2.0f; float fHalfHeight = sParam.zoneY / 2.0f; float fResultHeight = 0.0f; if (sParam.nDir == 0 || sParam.nDir == 1) // 동→ 서← { if( sParam.x < fHalfWidth ) { fResultHeight = ( ( fMaxHeight * sParam.x ) / fHalfWidth ); if( sParam.y < fHalfHeight ) { // fResultHeight : fHalfHeight = h : sParam.y // h = sParam.y * fResultHeight / fHalfHeight; float fH = fResultHeight * sParam.y / fHalfHeight; fResultHeight = fH + pPath->start; } else { float ty = sParam.y - fHalfHeight; float fH = fResultHeight * (fHalfHeight - ty) / fHalfHeight; fResultHeight = fH + pPath->start; } } else { float tx = sParam.x - fHalfWidth; fResultHeight = ( fMaxHeight - ( ( fMaxHeight * tx ) / fHalfWidth ) ); if( sParam.y < fHalfHeight ) { float fH = fResultHeight * sParam.y / fHalfHeight; fResultHeight = fH + pPath->start; } else { float ty = sParam.y - fHalfHeight; float fH = fResultHeight * (fHalfHeight - ty) / fHalfHeight; fResultHeight = fH + pPath->start; } } } else if(sParam.nDir == 2 || sParam.nDir == 3) // 남↓ 북↑ { if( sParam.y < fHalfHeight ) { fResultHeight = ( ( fMaxHeight * sParam.y ) / fHalfHeight ); if( sParam.x < fHalfWidth ) { // fResultHeight : fHalfWidth = x : sParam.x // x = sParam.x * fResultHeight / fHalfWidth; float fW = fResultHeight * sParam.x / fHalfWidth; fResultHeight = fW + pPath->start; } else { float tx = sParam.x - fHalfHeight; float fW = fResultHeight * (fHalfWidth - tx) / fHalfWidth; fResultHeight = fW + pPath->start; } } else { float ty = sParam.y - fHalfHeight; fResultHeight = ( fMaxHeight - ( ( fMaxHeight * ty ) / fHalfHeight ) ); if( sParam.x < fHalfWidth ) { float fW = fResultHeight * sParam.x / fHalfWidth; fResultHeight = fW + pPath->start; } else { float tx = sParam.x - fHalfWidth; float fW = fResultHeight * (fHalfWidth - tx) / fHalfWidth; fResultHeight = fW + pPath->start; } } } return fResultHeight; } //--------------------------------------------------------------------------------------- // cloud CCloudTypeInfoDB& GetCloudTypeInfoDB() { return *g_pCloudTypeInfoDB; } CCloudTypeInfoDB::CCloudTypeInfoDB() { } CCloudTypeInfoDB::~CCloudTypeInfoDB() { clear(); } void CCloudTypeInfoDB::add(int id, SCloudTypeInfo* pTypeInfo) { m_vcTypeInfo.push_back( pTypeInfo ); } void CCloudTypeInfoDB::clear() { for(int i = 0; i < (int)m_vcTypeInfo.size(); ++i) { SCloudTypeInfo* p = m_vcTypeInfo[ i ]; SAFE_DELETE( p ); } m_vcTypeInfo.clear(); } void CCloudTypeInfoDB::size(int sz) { clear(); } SCloudTypeInfo* CCloudTypeInfoDB::find(int id) { return m_vcTypeInfo[ id ]; } //--------------------------------------------------------------------------------------- // appear layer void SCloudLayer::add(int id, SCloudShowInfo* pLayer) { vcShowInfo.push_back( pLayer ); } void SCloudLayer::clear() { for(int i = 0; i < (int)vcShowInfo.size(); ++i) { SCloudShowInfo* p = vcShowInfo[ i ]; SAFE_DELETE( p ); } vcShowInfo.clear(); } void SCloudLayer::size(int sz) { clear(); } SCloudShowInfo* SCloudLayer::find(int id) { return vcShowInfo[ id ]; } // appear layer CCloudLayerDB* GetCloudLayerDB() { return g_pCloudLayerDB; } CCloudLayerDB::CCloudLayerDB() { int k=0; } CCloudLayerDB::~CCloudLayerDB() { clear(); } void CCloudLayerDB::add(int id, SCloudLayer* pLayer) { m_vcLayer.push_back( pLayer ); } void CCloudLayerDB::clear() { for(int i = 0; i < (int)m_vcLayer.size(); ++i) { SCloudLayer* p = m_vcLayer[ i ]; SAFE_DELETE( p ); } m_vcLayer.clear(); } void CCloudLayerDB::size(int sz) { clear(); } SCloudLayer* CCloudLayerDB::find(int id) { return m_vcLayer[ id ]; } //--------------------------------------------------------------------------------------- // appear layer set void SCloudLayerSet::add(int id, SCloudLayerInfo* pLayer) { vcLayerInfo.push_back( pLayer ); } void SCloudLayerSet::clear() { for(int i = 0; i < (int)vcLayerInfo.size(); ++i) { SCloudLayerInfo* p = vcLayerInfo[ i ]; SAFE_DELETE( p ); } vcLayerInfo.clear(); } void SCloudLayerSet::size(int sz) { clear(); } SCloudLayerInfo* SCloudLayerSet::find(int id) { return vcLayerInfo[ id ]; } // appear layer CCloudLayerSetDB* GetCloudLayerSetDB() { return g_pCloudLayerSetDB; } CCloudLayerSetDB::CCloudLayerSetDB() { } CCloudLayerSetDB::~CCloudLayerSetDB() { clear(); } int CCloudLayerSetDB::get_size() { return (int)m_vcLayerSet.size(); } void CCloudLayerSetDB::add(int id, SCloudLayerSet* pLayer) { m_vcLayerSet.push_back( pLayer ); } void CCloudLayerSetDB::clear() { for(int i = 0; i < (int)m_vcLayerSet.size(); ++i) { SCloudLayerSet* p = m_vcLayerSet[ i ]; SAFE_DELETE( p ); } m_vcLayerSet.clear(); } void CCloudLayerSetDB::size(int sz) { clear(); // m_vcLayerSet.resize(sz); } SCloudLayerSet* CCloudLayerSetDB::find(int id) { return m_vcLayerSet[ id ]; } //--------------------------------------------------------------------------------------- // SCloudVertexBufferPack //--------------------------------------------------------------------------------------- void SCloudVertexBufferPack::add(K3DVERTEX_CLOUD* pVtx) { vcVB.push_back(pVtx); } void SCloudVertexBufferPack::add(int id, K3DVERTEX_CLOUD* pVtx) { vcVB.push_back(pVtx); } void SCloudVertexBufferPack::clear() { for(int i = 0; i < (int)vcVB.size(); ++i) { K3DVERTEX_CLOUD* p = vcVB[ i ]; SAFE_DELETE( p ); } vcVB.clear(); } K3DVERTEX_CLOUD* SCloudVertexBufferPack::find(int id) { if(id < 0 || id >= (int)vcVB.size()) return NULL; return vcVB[ id ]; } //--------------------------------------------------------------------------------------- // cloud unit //--------------------------------------------------------------------------------------- CCloudUnit::CCloudUnit() : SGameEnvCloud(), m_pDevice( 0 ) { SetFadeState( FADE_NONE ); m_fMoveFrame = 0.0f; m_fMovePosX = m_fMovePosY = m_fMovePosZ = 0.0f; } CCloudUnit::~CCloudUnit() { SAFE_DELETE(m_pPrimitive); } int CCloudUnit::make(SCloudCreateParam& pr) { m_fMoveFrame = 0.0f; m_fMovePosX = m_vPos.x; m_fMovePosY = m_vPos.y; m_nDir = pr.nDir; if ( m_nDir == 0 ) m_vDir = K3DVector(-1.0f, 0.0f, 0.0f); else if( m_nDir == 1 ) m_vDir = K3DVector(1.0f, 0.0f, 0.0f); else if( m_nDir == 2 ) m_vDir = K3DVector(0.0f, 1.0f, 0.0f); else if( m_nDir == 3 ) m_vDir = K3DVector(0.0f, -1.0f, 0.0f); int nCurrentTick = (int)GetSafeTickCount(); m_nType = pr.nType; m_nLayerGap = pr.nLayerGapType; m_nPath = pr.nPath; SCloudTypeInfo* pTypeInfo = GetCloudTypeInfoDB().find( m_nType ); // 구름 타입정보를 구한다 if( pTypeInfo == NULL ) return 0; m_nTypeSize = pTypeInfo->type_size; // 크기 타입 m_nTypeThickness = pTypeInfo->type_thickness; // 두께 타입 m_nTypeThicknessGap = pTypeInfo->type_thickness_gap; // 두께 간격 타입 m_nTypeTxrGroup[C_BRIGHT] = pTypeInfo->type_txr_normal; // 보통 덱스처 그룸 타입 m_nTypeTxrGroup[C_GRAY] = pTypeInfo->type_txr_middle; // 중간 밝기 텍스처 그룹 타입 m_nTypeTxrGroup[C_DARK] = pTypeInfo->type_txr_dark; // 어두운 텍스처 그룹 타입 m_fMoveSpeed = pTypeInfo->fMoveSpeed; // 이동 속도 m_nThickness = GetCloudThicknessDB().find( m_nTypeThickness ); // 구름 두께 구함 if( m_nThickness <= 0 ) return -1; float fThicknessGap = GetCloudThicknessGapDB().find( m_nTypeThicknessGap ); // 구름 두께 간격 ( 구름 평면간의 간격 ) if( fThicknessGap < 0.0f ) return -2; SCloudKind* pKind = GetCloudKindDB().find( m_nType ); // 구름모양의 종류 디비 if( pKind == NULL ) return -3; SCloudSize* pSizeType = GetCloudSizeDB().find( m_nTypeSize ); // cloud size if( pSizeType == NULL ) return -4; float fSizeGap = pSizeType->e - pSizeType->s; int nSGap = 3; if( fSizeGap < 0.0f ) nSGap = 1; float fCloudSize100 = (float)( (GetSafeTickCount() % nSGap) + pSizeType->s ); float fRealSizeW2 = fCloudSize100 / 2.0f; // height float fHeight = pr.fStandardHeight + ((float)m_nThickness * fThicknessGap); GenerateCloudTexture( CCloudTxrGroupDB::NORMAL ); // 밝은 텍스처 GenerateCloudTexture( CCloudTxrGroupDB::MIDDLE ); // 중간 밝기 텍스처 GenerateCloudTexture( CCloudTxrGroupDB::DARK ); // 어두운 텍스처 int nHalfCount = m_nThickness / 2; int j=0; float fG = 1.0f / (float)nHalfCount; for(int k=m_nThickness; k>0; k--) { float fRate = GetCloudKindDB().calculateRate(m_nType, k, m_nThickness); // 지정된 두께 비율에 따라 현재 단계의 비율을 구한다 float fCurrentCloudSize = fRate + fCloudSize100; // 구름 타입의 9단계 비율과 구름 두께의 비율이 조합된 현재 단계의 구름 크기 float fRealSizeW = (float)pSizeType->s + ( fSizeGap * fRate); // cloud size height float fRealSizeW2 = fRealSizeW / 2.0f; float fRealSizeH = (float)pSizeType->s + ( fSizeGap * fRate); // cloud size height float fRealSizeH2 = fRealSizeH / 2.0f; KColor cloudColor(pr.color[1], pr.color[2], pr.color[3], pr.color[0]); int id = k * ONE_CLOUD_PLANE_VTX_COUNT; // 구름 한 평면당 버텍스 4 int nColorType = 0; if ( k == 0 ) // 바닥은 어두운 텍스처 nColorType = C_DARK; else if( k < nHalfCount ) // 중간까지는 중간 밝기 텍스처 nColorType = C_GRAY; else if( k >= nHalfCount ) // 중간 이상은 가장 밝은 텍스처 { nColorType = C_BRIGHT; float rx = tan( fG * (float)(j) ) / 1.57079f; cloudColor.a = BYTE( 255.0f * rx ); j++; } K3DVERTEX_CLOUD* pVtx = new K3DVERTEX_CLOUD[ ONE_CLOUD_PLANE_VTX_COUNT ]; pVtx[ 0 ].position = K3DVector( pr.fx - fRealSizeW2, pr.fy - fRealSizeH2, fHeight ); pVtx[ 0 ].color = cloudColor; pVtx[ 0 ].normal = K3DVector( 0.0f, 0.0f, 1.0f ); pVtx[ 0 ].texcoord0.Set(0.0f, 0.0f); pVtx[ 1 ].position = K3DVector( pr.fx + fRealSizeW2, pr.fy - fRealSizeH2, fHeight ); pVtx[ 1 ].color = cloudColor; pVtx[ 1 ].normal = K3DVector( 0.0f, 0.0f, 1.0f ); pVtx[ 1 ].texcoord0.Set(1.0f, 0.0f); pVtx[ 2 ].position = K3DVector( pr.fx - fRealSizeW2, pr.fy + fRealSizeH2, fHeight ); pVtx[ 2 ].color = cloudColor; pVtx[ 2 ].normal = K3DVector( 0.0f, 0.0f, 1.0f ); pVtx[ 2 ].texcoord0.Set(0.0f, 1.0f); pVtx[ 3 ].position = K3DVector( pr.fx + fRealSizeW2, pr.fy + fRealSizeH2, fHeight ); pVtx[ 3 ].color = cloudColor; pVtx[ 3 ].normal = K3DVector( 0.0f, 0.0f, 1.0f ); pVtx[ 3 ].texcoord0.Set(1.0f, 1.0f); m_VBPack[ nColorType ].add( &pVtx[ 0 ] ); m_VBPack[ nColorType ].add( &pVtx[ 1 ] ); m_VBPack[ nColorType ].add( &pVtx[ 2 ] ); m_VBPack[ nColorType ].add( &pVtx[ 3 ] ); fHeight -= fThicknessGap; // cloud height } GenerateCloudVertexBuffer(); return 1; } void CCloudUnit::GenerateCloudTexture(int nColorType) { if(nColorType < C_BRIGHT || nColorType >= C_MAX) return ; std::string* pStrTxrName = GetCloudTxrGroupDB().find_str( nColorType, m_nTypeTxrGroup[ nColorType ] ); if( pStrTxrName->size() <= 3 ) return ; NX3LoadPack loadpack; loadpack.Init(); K3DTexture* pTexture = KTextureManager::GetManager()->GetTexture( pStrTxrName->c_str(), &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); if( pTexture == NULL ) return ; m_pPrimitive->SetTexture( nColorType, pTexture ); // 텍스처 설정 } void CCloudUnit::GenerateCloudVertexBuffer() { m_pPrimitive->ClearVertexBuffer(); for(int y=C_BRIGHT; yCreateVertexBufferUsePoolDefault( sizeof(K3DVERTEX_CLOUD), dwFormat, ONE_CLOUD_PLANE_VTX_COUNT * count, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY ); // 버텍스 버퍼 만듦 if( pVB == NULL ) assert(pVB && "Failed CreateVertexBufferUsePoolDefault"); // 버텍스 버퍼에 락걸고 내용을 채운다 int nVtxSize, nPrimCnt = 0; K3DVERTEX_CLOUD* pVtx = NULL; #if defined( _DEBUG ) // D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨 pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); #else pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_DISCARD ); #endif assert(vtx && "pVB->Lock( (void**)&vtx, nVtxSize );"); if( pVtx == NULL ) return; int nPlaneCount = count / ONE_CLOUD_PLANE_VTX_COUNT; for(int x=0; xUnlock(); m_pPrimitive->SetVertexCnt( y, nPrimCnt ); if( pVB ) m_pPrimitive->SetVertexBuffer( y, pVB ); // 렌더링 프리미티브에 버퍼 연결 // 인덱스 버퍼 int nInBCount = nPlaneCount * ONE_CLOUD_PLANE_INDEX_COUNT; K3DIndexBuffer* pIB = m_pDevice->CreateIndexBuffer( nInBCount ); if( pIB == NULL ) assert(pIB && "Failed CreateIndexBuffer"); WORD *idxb; int idxSize; pIB->Lock((void **)&idxb, idxSize); assert(idxb && "pIB->Lock((void **)&idxb, idxSize);"); int kid = 0; for(int k = 0; k < nPlaneCount; k++, kid += ONE_CLOUD_PLANE_INDEX_COUNT) { idxb[ kid + 0 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 0; idxb[ kid + 1 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 1; idxb[ kid + 2 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 2; idxb[ kid + 3 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 3; idxb[ kid + 4 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 2; idxb[ kid + 5 ] = k * ONE_CLOUD_PLANE_VTX_COUNT + 1; } pIB->Unlock(); if( pIB ) m_pPrimitive->SetIndexBuffer( y, pIB ); // 렌더링 프리미티브에 버퍼 연결 } } void CCloudUnit::UpdatePos( float fx, float fy, float fz ) { int k=0; } void CCloudUnit::Init( K3DRenderDevice *pDevice, K3DIndexBuffer * pIndexBuf ) { m_pDevice = pDevice; m_pMtl = new K3DMaterial; m_pMtl->SetAmbient( K3DColor( 1.f, 0.f, 0.f, 0.f ) ); m_pMtl->SetDiffuse( K3DColor( 1.f, 0.f, 0.f, 0.f ) ); m_pMtl->SetSpecular( K3DColor( 0.f, 0.f, 0.f, 0.f ) ); m_pMtl->SetSpecularPower( 1.0f ); m_pParentMat = NULL; // SkyBox 위치 K3DMatrixIdentity( m_LocalMat ); // 구름 위치 K3DMatrixIdentity( m_WorldMat ); m_pPrimitive->SetTransparent( true ); m_pPrimitive->SetTransform( &m_LocalMat, &m_WorldMat ); m_pPrimitive->SetMaterial( m_pMtl ); } int CCloudUnit::ProcessSecond( DWORD dwTime ) { DWORD dwFrameTick = dwTime - m_dwTickOld; if( dwFrameTick < 0 ) return 0; // 속도 = 움직인 거리 / 단위시간 // 거리 = 시간 * 속도 // 시간 = 거리 / 속도 float fGap = (float)dwFrameTick * (float)m_fMoveSpeed; if ( m_nDir == 0 ) { m_fMoveFrame += ( m_vDir.x * fGap ); m_fMovePosX = m_vPos.x + m_fMoveFrame; if( m_fMovePosX < -ZONE_CLOUD_WIDTH_D2 ) { m_fMoveFrame = ZONE_CLOUD_WIDTH_D2; m_fMovePosX = ZONE_CLOUD_WIDTH_D2; } } else if( m_nDir == 1 ) { m_fMoveFrame += ( m_vDir.x * fGap ); m_fMovePosX = m_vPos.x + m_fMoveFrame; if( m_fMovePosX > ZONE_CLOUD_WIDTH_D2 ) { m_fMoveFrame = -ZONE_CLOUD_WIDTH_D2; m_fMovePosX = -ZONE_CLOUD_WIDTH_D2; } } else if( m_nDir == 2 ) { m_fMoveFrame += ( m_vDir.y * fGap ); m_fMovePosY = m_vPos.y + m_fMoveFrame; if( m_fMovePosY > ZONE_CLOUD_HEIGHT_D2 ) { m_fMoveFrame = -ZONE_CLOUD_HEIGHT_D2; m_fMovePosY = -ZONE_CLOUD_HEIGHT_D2; } } else if( m_nDir == 3 ) { m_fMoveFrame += ( m_vDir.y * fGap ); m_fMovePosY = m_vPos.y + m_fMoveFrame; if( m_fMovePosY < -ZONE_CLOUD_HEIGHT_D2 ) { m_fMoveFrame = ZONE_CLOUD_HEIGHT_D2; m_fMovePosY = ZONE_CLOUD_HEIGHT_D2; } } SCalculateHeightParam sParam; sParam.nLayerGapType = m_nLayerGap; sParam.nPathType = m_nPath; sParam.nDir = m_nDir; sParam.x = m_fMovePosX + ZONE_CLOUD_WIDTH_D2; sParam.y = m_fMovePosY + ZONE_CLOUD_HEIGHT_D2; sParam.zoneX = ZONE_CLOUD_WIDTH; sParam.zoneY = ZONE_CLOUD_HEIGHT; m_fMovePosZ = GetCloudPathDB().calculateHeight( sParam ); m_fMovePosZ -= g_fMyPlayerHeight; m_dwTickOld = dwTime; return 0; } void CCloudUnit::SetFadeState( int nState ) { m_sFadeState = nState; if ( m_sFadeState == FADE_IN ) m_fAlpha = 0.0f; else if( m_sFadeState == FADE_OUT ) m_fAlpha = 1.0f; } // 서서히 알파값 높아져 투명하게 변화시킴 int CCloudUnit::IncreaseAlpha( DWORD dwFrameTick ) { m_fAlpha += (float)dwFrameTick / FADE_ALPHA_TIME; float fCurAlpha = m_fAlpha; float fCurAlpha2 = fCurAlpha; if( fCurAlpha > 1.0f ) fCurAlpha = 1.0f; UpdateAlpha( fCurAlpha ); return 1; } // 서서히 알파값 낮아져 불투명하게 변화시킴 int CCloudUnit::DecreaseAlpha( DWORD dwFrameTick ) { m_fAlpha -= (float)dwFrameTick / FADE_ALPHA_TIME; float fCurAlpha = m_fAlpha; float fCurAlpha2 = fCurAlpha; if( fCurAlpha < 0.0f ) fCurAlpha = 0.0f; UpdateAlpha( fCurAlpha ); return 1; } void CCloudUnit::UpdateAlpha( float fAlpha ) { for(int y=C_BRIGHT; yGetVertexBuffer( y ); if( pVB == NULL ) continue ; // 버텍스 버퍼에 락걸고 내용을 채운다 int nVtxSize, nPrimCnt = 0; K3DVERTEX_CLOUD* pVtx = NULL; #if defined( _DEBUG ) // D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨 pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); #else pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_DISCARD ); #endif assert(vtx && "pVB->Lock( (void**)&vtx, nVtxSize );"); if( pVtx == NULL ) return; for(int x=0; xUnlock(); } } void CCloudUnit::UpdateAlphaBrightLayer() { int y=C_BRIGHT; { int count = m_VBPack[ y ].get_size(); if( count <= 0 ) return ; K3DVertexBuffer* pVB = m_pPrimitive->GetVertexBuffer( y ); if( pVB == NULL ) return ; // 버텍스 버퍼에 락걸고 내용을 채운다 int nVtxSize, nPrimCnt = 0; K3DVERTEX_CLOUD* pVtx = NULL; #if defined( _DEBUG ) // D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨 pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); #else pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_DISCARD ); #endif assert(vtx && "pVB->Lock( (void**)&vtx, nVtxSize );"); if( pVtx == NULL ) return; int nPlaneCount = count / ONE_CLOUD_PLANE_VTX_COUNT; float fG = 1.0f / (float)nPlaneCount; for(int x=0; xUnlock(); } } void CCloudUnit::Render( KViewportObject *viewport ) { if( m_pPrimitive ) { viewport->Register( m_pPrimitive, KRenderObject::RENDEREFX_CLOUD ); } } void CCloudUnit::SetHeight( int i, float fz ) { } void CCloudUnit::SetPosition( float fx, float fy, float fz ) { m_vPos.x = fx; m_vPos.y = fy; m_vPos.z = fz; } K3DVector& CCloudUnit::GetPosition() { return m_vPos; } void CCloudUnit::UpdatePosition(float fx, float fy, float fz) { SGameWorld* pGameWorld = dynamicCast(g_pCurrentGameSystem->GetGame()); float gfx = 0.0f; float gfy = 0.0f; float gfz = 0.0f; SGameAvatarEx* pMyCharacter = g_pCurrentGameSystem->GetLocalPlayer(); if( pMyCharacter ) { float out; WORD wTile; K3DVector vPos = pMyCharacter->GetCurPos(); pGameWorld->GetHeight( vPos.x, vPos.y, out, wTile ); gfz = pMyCharacter->GetCurPos().z; gfz = out; } K3DMatrix* pMat = m_pPrimitive->GetTransform(); pMat->_41 = m_fMovePosX + g_fX + gfx; pMat->_42 = m_fMovePosY + g_fY + gfy; pMat->_43 = m_fMovePosZ + fz + g_fZ + gfz; } void CCloudUnit::SetTransform( K3DMatrix* pParentMatrix ) { SetParentMat( pParentMatrix ); m_pPrimitive->SetTransform( pParentMatrix, pParentMatrix ); } void CCloudUnit::initVB() { } void CCloudUnit::initCloudObjects() { } void CCloudUnit::ChangeCloudColor(int nR, int nG, int nB) { int count = m_VBPack[ C_BRIGHT ].get_size(); if( count <= 0 ) return ; K3DVertexBuffer* pVB = m_pPrimitive->GetVertexBuffer( C_BRIGHT ); if( pVB == NULL ) return ; // 버텍스 버퍼에 락걸고 내용을 채운다 int nVtxSize, nPrimCnt = 0; K3DVERTEX_CLOUD* pVtx = NULL; #if defined( _DEBUG ) // D3DLOCK_NOOVERWRITE 옵션이 일부 그래픽 카드에서 문제 발생되어 수정됨 pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD ); #else pVB->Lock( (void**)&pVtx, nVtxSize, D3DLOCK_DISCARD ); #endif assert(vtx && "pVB->Lock( (void**)&vtx, nVtxSize );"); if( pVtx == NULL ) return; int _r = nR; // - pVtx->color.r; int _g = nG; // - pVtx->color.g; int _b = nB; // - pVtx->color.b; int j=0; int nPlaneCount = count / ONE_CLOUD_PLANE_VTX_COUNT; float fG = 1.0f / (float)nPlaneCount; for(int k=nPlaneCount; k>0; k--, j++) { float rx = tan( fG * (float)j ) / 1.57079f; int id = (k - 1) * ONE_CLOUD_PLANE_VTX_COUNT; for(int z=0; zcolor.r = _r; pV->color.g = _g; pV->color.b = _b; } } pVB->Unlock(); } //--------------------------------------------------------------------------------------- // cloud uni manager CCloudLayer::CCloudLayer() { } CCloudLayer::~CCloudLayer() { clear(); } void CCloudLayer::add(int id, CCloudUnit* pCloud) { m_vcCloud.push_back( pCloud ); } void CCloudLayer::clear() { int nCount = m_vcCloud.size(); for(int x=0; xvcShowInfo.size(); std::vector< int > vecCount; std::vector< POINT > vecXY; int nTotalCount = 0; for(int x=0; xfind( x ); if( pShowInfo == NULL ) return -4; // 구름의 개수 int nCloudCount = (tDistribution * pShowInfo->type_show_rate) / 100; for(int z=0; zfind( x ); if( pShowInfo == NULL ) return -4; for(int z=0; zInit( m_pDevice ); pCloud->SetParent( this ); // cloud position float fx = (float)vecXY[ id ].x; float fy = (float)vecXY[ id ].y; SCalculateHeightParam sHeightParam; sHeightParam.nLayerGapType = m_sParam.nLayerGapType; sHeightParam.nPathType = m_sParam.nTypePathType; sHeightParam.nDir = m_sParam.nTypeMoveDir; sHeightParam.x = fx; sHeightParam.y = fy; sHeightParam.zoneX = ZONE_CLOUD_WIDTH; sHeightParam.zoneY = ZONE_CLOUD_HEIGHT; float fHeight = GetCloudPathDB().calculateHeight( sHeightParam ); fx -= ZONE_CLOUD_WIDTH_D2; fy -= ZONE_CLOUD_HEIGHT_D2; pCloud->SetPosition(fx, fy, fHeight); pCloud->SetID( id ); SCloudCreateParam pr; pr.nType = pShowInfo->type_cloud; pr.nLayerGapType = m_sParam.nLayerGapType; pr.nPath = m_sParam.nTypePathType; pr.fStandardHeight = 0.0f; pr.nDir = m_sParam.nTypeMoveDir; pr.fx = 0.0f; pr.fy = 0.0f; pr.color[0] = sParam.pCloudShowInfo->color[0]; pr.color[1] = sParam.pCloudShowInfo->color[1]; pr.color[2] = sParam.pCloudShowInfo->color[2]; pr.color[3] = sParam.pCloudShowInfo->color[3]; if( 0 == pCloud->make( pr ) ) return -4; add( id, pCloud ); id += 1; } } return 1; } int CCloudLayer::Process( DWORD dwTime ) { int sz = (int)m_vcCloud.size(); for(int x=0; xProcessSecond( dwTime ); if( nState == FADE_IN_COMPLETE || nState == FADE_OUT_COMPLETE ) return nState; } return 1; } void CCloudLayer::Render( KViewportObject *viewport ) { int sz = (int)m_vcCloud.size(); for(int x=0; xRender( viewport ); } } void CCloudLayer::SetPosition( float fx, float fy, float fz, int idCloud ) { int sz = (int)m_vcCloud.size(); if( idCloud == -1 ) { for(int x=0; xSetPosition( fx, fy, fz ); } return ; } if( idCloud < 0 || idCloud >= sz ) return ; m_vcCloud[ idCloud ]->SetPosition( fx, fy, fz ); } void CCloudLayer::UpdatePosition(float fx, float fy, float fz) { int sz = (int)m_vcCloud.size(); for(int x=0; xUpdatePosition(fx, fy, fz); } } void CCloudLayer::FadeInOutCloud(int nFadeState) { int sz = (int)m_vcCloud.size(); for(int x=0; xSetFadeState( nFadeState ); } } void CCloudLayer::CompleteFadeIn() { m_pParent->CompleteFadeIn(); } void CCloudLayer::CompleteFadeOut() { m_pParent->CompleteFadeOut(); } void CCloudLayer::SetAlpha( float fAlpha ) { int sz = (int)m_vcCloud.size(); for(int x=0; xSetAlpha( fAlpha ); } } void CCloudLayer::UpdateAlpha( float fAlpha ) { int sz = (int)m_vcCloud.size(); for(int x=0; xUpdateAlpha( fAlpha ); } } void CCloudLayer::UpdateAlphaBrightLayer() { int sz = (int)m_vcCloud.size(); for(int x=0; xUpdateAlphaBrightLayer(); } } int CCloudLayer::DecreaseAlpha( DWORD dwFrameTick ) { int sz = (int)m_vcCloud.size(); for(int x=0; xDecreaseAlpha( dwFrameTick ); } return 1; } int CCloudLayer::IncreaseAlpha( DWORD dwFrameTick ) { int sz = (int)m_vcCloud.size(); for(int x=0; xIncreaseAlpha( dwFrameTick ); } return 1; } void CCloudLayer::ChangeCloudColor(int nR, int nG, int nB) { int sz = (int)m_vcCloud.size(); for(int x=0; xChangeCloudColor(nR, nG, nB); } } //--------------------------------------------------------------------------------------- // cloud uni manager CCloudLayerSet::CCloudLayerSet() { m_nRenderCloudID = -1; } CCloudLayerSet::~CCloudLayerSet() { clear(); } bool CCloudLayerSet::SetRenderCloudID( int id ) { m_nRenderCloudID = id; return true; } int CCloudLayerSet::get_size() { return (int)m_vcLayer.size(); } void CCloudLayerSet::SetDevice(K3DRenderDevice* pDvc) { m_pDevice = pDvc; } void CCloudLayerSet::add(int id, CCloudLayer* pLayer) { m_vcLayer.push_back( pLayer ); } void CCloudLayerSet::clear() { int nCount = m_vcLayer.size(); for(int x=0; xfind( nType ); if( pCloudLayerDB == NULL ) return -3; int sz = pCloudLayerDB->vcShowInfo.size(); for(int x=0; xSetDevice( m_pDevice ); pLayer->SetParent( this ); SCloudParam sParam; sParam.nTypeDistribution = pCloudLayerDB->type_distribution; sParam.nTypeCloudHeightRandomGap = pCloudLayerDB->type_height_random_gap; sParam.nTypePathType = nPathType; sParam.nTypeMoveDir = nDir; sParam.nLayerGapType = nLayerGapType; sParam.pCloudShowInfo = pCloudLayerDB; if( 0 == pLayer->makeClouds( sParam ) ) return -4; add( x, pLayer ); } return 1; } int CCloudLayerSet::Process( DWORD dwTime ) { if( m_nRenderCloudID < 0 || m_nRenderCloudID >= m_vcLayer.size() ) return 0; SGameWorld* pGameWorld = dynamicCast(g_pCurrentGameSystem->GetGame()); SGameAvatarEx* pMyCharacter = g_pCurrentGameSystem->GetLocalPlayer(); if( pMyCharacter ) { WORD wTile; K3DVector vPos = pMyCharacter->GetCurPos(); pGameWorld->GetHeight( vPos.x, vPos.y, g_fMyPlayerHeight, wTile ); } int sz = (int)m_vcLayer.size(); for(int x=0; xProcess( dwTime ); if( nState == FADE_IN_COMPLETE || nState == FADE_OUT_COMPLETE ) return nState; } return 1; } void CCloudLayerSet::Render( KViewportObject *viewport ) { if( m_nRenderCloudID < 0 || m_nRenderCloudID >= m_vcLayer.size() ) return ; int sz = (int)m_vcLayer.size(); for(int x=0; xRender( viewport ); } } void CCloudLayerSet::SetPosition( float fx, float fy, float fz ) { if( m_nRenderCloudID < 0 || m_nRenderCloudID >= m_vcLayer.size() ) return ; m_vcLayer[ m_nRenderCloudID ]->SetPosition( fx, fy, fz ); } void CCloudLayerSet::UpdatePosition(float fx, float fy, float fz) { int nCount = m_vcLayer.size(); for(int x=0; xUpdatePosition(fx, fy, fz); } } void CCloudLayerSet::FadeInOutCloud(int nFadeState) { int nCount = m_vcLayer.size(); for(int x=0; xFadeInOutCloud( nFadeState ); } } void CCloudLayerSet::CompleteFadeIn() { m_pParent->CompleteFadeIn(); } void CCloudLayerSet::CompleteFadeOut() { m_pParent->CompleteFadeOut(); } void CCloudLayerSet::SetAlpha( float fAlpha ) { int sz = (int)m_vcLayer.size(); for(int x=0; xSetAlpha( fAlpha ); } } void CCloudLayerSet::UpdateAlpha( float fAlpha ) { int sz = (int)m_vcLayer.size(); for(int x=0; xUpdateAlpha( fAlpha ); } } void CCloudLayerSet::UpdateAlphaBrightLayer() { int sz = (int)m_vcLayer.size(); for(int x=0; xUpdateAlphaBrightLayer(); } } int CCloudLayerSet::DecreaseAlpha( DWORD dwFrameTick ) { int sz = (int)m_vcLayer.size(); for(int x=0; xDecreaseAlpha( dwFrameTick ); } return 1; } int CCloudLayerSet::IncreaseAlpha( DWORD dwFrameTick ) { int sz = (int)m_vcLayer.size(); for(int x=0; xIncreaseAlpha( dwFrameTick ); } return 1; } void CCloudLayerSet::ChangeCloudColor(int nR, int nG, int nB) { int sz = (int)m_vcLayer.size(); for(int x=0; xChangeCloudColor(nR, nG, nB); } } //--------------------------------------------------------------------------------------- void CreateCloudDB() { g_pCloudKindDB = new CCloudKindDB; g_pCloudThicknesDB = new CCloudThicknessDB; g_pCloudThicknessGapDB = new CCloudThicknessGapDB; g_pCloudSizeDB = new CCloudSizeDB; g_pCloudTxrGroupDB = new CCloudTxrGroupDB; g_pCloudDistributionDB = new CCloudDistributionDB; g_pCloudHeightRadomGapDB = new CCloudHeightRadomGapDB; g_pCloudCloudLayerGapDB = new CCloudLayerGapDB; g_pCloudCloudMoveDirDB = new CCloudMoveDirDB; g_pCloudPathDB = new CCloudPathDB; g_pCloudTypeInfoDB = new CCloudTypeInfoDB; g_pCloudLayerDB = new CCloudLayerDB; g_pCloudLayerSetDB = new CCloudLayerSetDB; } void DestroyCloudDB() { SAFE_DELETE(g_pCloudKindDB); SAFE_DELETE(g_pCloudThicknesDB); SAFE_DELETE(g_pCloudThicknessGapDB); SAFE_DELETE(g_pCloudSizeDB); SAFE_DELETE(g_pCloudTxrGroupDB); SAFE_DELETE(g_pCloudDistributionDB); SAFE_DELETE(g_pCloudHeightRadomGapDB); SAFE_DELETE(g_pCloudCloudLayerGapDB); SAFE_DELETE(g_pCloudCloudMoveDirDB); SAFE_DELETE(g_pCloudPathDB); SAFE_DELETE(g_pCloudTypeInfoDB); SAFE_DELETE(g_pCloudLayerDB); SAFE_DELETE(g_pCloudLayerSetDB); } //--------------------------------------------------------------------------------------- // cloud uni manager CCloudMaker::CCloudMaker() { m_dwTickOld = 0; m_bShow = false; m_pCloud = new CCloudLayerSet; m_pCloud->SetParent( this ); } CCloudMaker::~CCloudMaker() { clearCloud(); SAFE_DELETE( m_pCloud ); } void CCloudMaker::SetWillCloudID( int _id ) { m_nWillCloudID = _id; } int CCloudMaker::GetRenderCloudID() const { if( m_pCloud ) return m_pCloud->GetRenderCloudID(); return -1; } void CCloudMaker::ClearRenderCloudID() { if( m_pCloud ) m_pCloud->SetRenderCloudID( -1 ); } void CCloudMaker::SetDevice(K3DRenderDevice* pDvc) { m_pCloud->SetDevice(pDvc); } int CCloudMaker::makeCloud(int id) { if( id < 0 ) return 0; if( m_pCloud->GetRenderCloudID() == id ) return 1; if( id > GetCloudLayerSetDB()->get_size() ) return -1; // current cloud id ( rendering ) if( false == m_pCloud->SetRenderCloudID( id ) ) return -2; clearCloud(); SCloudLayerSet* pLayerSet = GetCloudLayerSetDB()->find( id ); // 아이디로 구름세트 구조체 얻는다 if( pLayerSet == NULL ) return -3; int sz = (int)pLayerSet->vcLayerInfo.size(); for(int x=0; xfind(x); if( pLayerInfo == NULL ) return -4; if( 0 == m_pCloud->makeLayer( x, pLayerInfo->type_layer, pLayerInfo->type_move_dir, pLayerInfo->type_path, pLayerInfo->type_layer_gap ) ) return -5; } m_bShow = true; return 1; } void CCloudMaker::clearCloud() { m_pCloud->clear(); m_bShow = false; } void CCloudMaker::Process( DWORD dwTime ) { DWORD dwFrameTick = dwTime - m_dwTickOld; if(m_bShow) { m_pCloud->Process( dwTime ); if( g_nFadeState != FADE_NONE ) { // int nState = m_pCloud->Process( dwTime ); // if( nState == FADE_IN_COMPLETE ) if( g_nFadeState == FADE_IN_COMPLETE ) { CompleteFadeIn(); m_pCloud->Process( dwTime ); // FadeInOutCloud( FADE_OUT ); // 구름 서서히 불투명하게 나타남 } // else if( nState == FADE_OUT_COMPLETE ) else if( g_nFadeState == FADE_OUT_COMPLETE ) { CompleteFadeOut(); m_pCloud->UpdateAlphaBrightLayer(); m_pCloud->Process( dwTime ); // FadeInOutCloud( FADE_NONE ); } else if( g_nFadeState == FADE_IN ) { m_fAlpha -= (float)dwFrameTick / FADE_ALPHA_TIME; if( m_fAlpha < 0.0f ) { m_fAlpha = 0.0f; g_nFadeState = FADE_IN_COMPLETE; } m_pCloud->UpdateAlpha( m_fAlpha * 255.0f ); } else if( g_nFadeState == FADE_OUT ) { m_fAlpha += (float)dwFrameTick / FADE_ALPHA_TIME; if( m_fAlpha > 1.0f ) { m_fAlpha = 1.0f; g_nFadeState = FADE_OUT_COMPLETE; } m_pCloud->UpdateAlpha( m_fAlpha * 255.0f ); } } } m_dwTickOld = dwTime; } void CCloudMaker::Render( KViewportObject *viewport ) { if(m_bShow) m_pCloud->Render( viewport ); } void CCloudMaker::SetPosition( float fx, float fy, float fz ) { m_pCloud->SetPosition( fx, fy, fz ); } void CCloudMaker::UpdatePosition(float fx, float fy, float fz) { m_pCloud->UpdatePosition(fx, fy, fz); } void CCloudMaker::FadeInOutCloud(int nFadeState) { if( true == CompareCloudID() ) return ; g_nFadeState = nFadeState; if ( g_nFadeState == FADE_IN ) m_fAlpha = 1.0f; else if( g_nFadeState == FADE_OUT ) m_fAlpha = 0.0f; m_bShow = true; } void CCloudMaker::CompleteFadeIn() { if( m_nWillCloudID > -1 && m_nWillCloudID != GetRenderCloudID() ) { m_bShow = false; ClearRenderCloudID(); clearCloud(); makeCloud( m_nWillCloudID ); // 다른 종류의 구름 세트로 바꿈 m_pCloud->SetRenderCloudID( m_nWillCloudID ); g_nFadeState = FADE_OUT; } } void CCloudMaker::CompleteFadeOut() { m_bShow = true; g_nFadeState = FADE_NONE; } bool CCloudMaker::CompareCloudID() { if(m_nWillCloudID == GetRenderCloudID()) return true; return false; } void CCloudMaker::ChangeCloudColor(int nR, int nG, int nB) { m_pCloud->ChangeCloudColor(nR, nG, nB); } #endif