Files
Leviathan/Client/Game/game/Player/SGameCircleShadowFx.cpp
T
2026-06-01 12:46:52 +02:00

272 lines
7.5 KiB
C++

#include "stdafx.h"
#include "SGameCircleShadowFX.h"
#include "KRenderObject.h"
#include "SGameViewPort.h"
#include "KResourceManager.h"
#include "SGameWorld.h"
#include "KPrimitive.h"
#include "SGameAvatarEx.h"
#include "SDebug_Util.h"
namespace
{
float getCountPerMesc()
{
LARGE_INTEGER counter;
QueryPerformanceFrequency( &counter);
return (float)counter.LowPart / 1000.f;
}
const float COUNT_PER_MESC = getCountPerMesc();
DWORD getPerformanceCounter()
{
static LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return counter.LowPart;
}
}
class KStopWatch
{
public:
KStopWatch()
: m_dwCount(0), m_dwTime(0), m_dwHoldTime(0), m_bHold(false)
{
}
void Start()
{
if (m_dwCount == 0)
m_dwTime = getPerformanceCounter();
m_dwCount++;
}
void Stop()
{
assert (m_dwCount > 0);
m_dwCount--;
if (m_dwCount == 0)
{
m_dwTime = getPerformanceCounter() - m_dwTime;
}
}
void Hold()
{
m_dwHoldTime = getPerformanceCounter();
m_bHold = true;
}
void Unhold()
{
assert(m_bHold);
// add hold time to start time
m_dwTime += getPerformanceCounter() - m_dwHoldTime;
m_dwHoldTime = 0;
m_bHold = false;
}
void Reset()
{
m_dwCount = m_dwTime = 0;
}
DWORD GetTime() const
{
return m_dwTime;
}
// 1/1000 sec Time
float GetMsecTime() const
{
return (float)m_dwTime / COUNT_PER_MESC;
}
protected:
DWORD m_dwCount;
DWORD m_dwTime;
DWORD m_dwHoldTime;
bool m_bHold;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SGameCircleShadowPrimitive Implement
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class SGameCircleShadowPrimitive : public K3DPrimitive
{
public:
SGameCircleShadowPrimitive(K3DBLENDEDBUMPVERTEX* pVtx, const K3DINDEXED_WATER* pIdx, K3DTexture* pTex)
{
m_pTexBack = pTex;
m_pVertexBufferUP = pVtx;
m_pIndexBufferUP = pIdx;
SetBlendMode(K3DMaterial::MBM_CIRCLE_FX);
SetTransparent(true);
}
virtual void Render( KViewportObject *pViewport, K3DRenderDevice *pDev, bool bUseAccum = true )
{
pDev->SetTransform( K3DRenderDevice::TS_WORLD, &m_RootMat);
pDev->SetVertexShaderConstant( CONSTANT_VISIBILITY, &m_fVisibility, 1 );
pDev->SetTexture( 0, m_pTexBack );
pDev->DrawIndexedPrimitiveUP_VS( 0, m_pVertexBufferUP, (SHADOW_SEGMENT_COUNT*SHADOW_SEGMENT_COUNT),
sizeof(K3DBLENDEDBUMPVERTEX), &m_pIndexBufferUP[0].a, SHADOW_SEGMENET_INDEX_COUNT * 3 );
}
private:
K3DTexture* m_pTexBack;
K3DBLENDEDBUMPVERTEX* m_pVertexBufferUP;
const K3DINDEXED_WATER* m_pIndexBufferUP;
};
SCircleShadowCommonInfo& SCircleShadowCommonInfo::GetInstance()
{
static SCircleShadowCommonInfo indexbuffer;
return indexbuffer;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SGameCircleShadowFX Implement
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SGameCircleShadowFX::SGameCircleShadowFX()
{
m_vPos = K3DVector(0.f,0.f,0.f);
m_nAddOnType = SGAME_CIRCLE_SHADOW_FX;
}
void SGameCircleShadowFX::Initialize()
{
m_fScale = m_pGameObj->GetScale() * m_pGameObj->GetSize() * (float)(GameRule::DEFAULT_UNIT_SIZE);
_oprint("Scale is %f\n", m_fScale);
///가로 세로 거리를 세그먼트로 나눈다
m_fWidthLength = m_fScale / (float)(SHADOW_SEGMENT_COUNT-1);
m_fHeightLength = m_fScale / (float)(SHADOW_SEGMENT_COUNT-1);
m_fWidthCenter = m_fScale / 2.f;
m_fHeightCenter = m_fScale / 2.f;
// Vertex Initialize
m_pVertex = new K3DBLENDEDBUMPVERTEX[SHADOW_SEGMENT_COUNT*SHADOW_SEGMENT_COUNT];
K3DBLENDEDBUMPVERTEX* pVertex = m_pVertex;
for(int h = 0; h < SHADOW_SEGMENT_COUNT; h++ )
{
for( int w = 0; w < SHADOW_SEGMENT_COUNT; w++)
{
pVertex->position = K3DVector( 0.f, 0.f, 0.f );
pVertex->normal = K3DVector( 0.f, 1.f, 0.f );
pVertex->color = 0xffffffff;
pVertex->texcoord.x = (static_cast<float>(w)/ (SHADOW_SEGMENT_COUNT-1) );
pVertex->texcoord.y = (static_cast<float>(h)/ (SHADOW_SEGMENT_COUNT-1) );
pVertex->tangent = K3DVector4( 0.f, 0.f, 0.f, 0.f );
pVertex->matrixIndices = 0;
pVertex->matrixWeights.x = 0.f;
pVertex->matrixWeights.y = 0.f;
++pVertex;
}
}
m_pPrimitive = new SGameCircleShadowPrimitive(m_pVertex, SCircleShadowCommonInfo::GetInstance().GetCircleShadowIndexBuffer(),
SCircleShadowCommonInfo::GetInstance().GetCircleShadowTexture() );
}
SGameCircleShadowFX::~SGameCircleShadowFX()
{
SAFE_DELETE( m_pPrimitive );
SAFE_DELETE_ARRAY( m_pVertex );
}
void SGameCircleShadowFX::Refresh()
{
m_fScale = m_pGameObj->GetScale() * m_pGameObj->GetSize() * (float)(GameRule::DEFAULT_UNIT_SIZE);
_oprint("Scale is %f\n", m_fScale);
///가로 세로 거리를 세그먼트로 나눈다
m_fWidthLength = m_fScale / (float)(SHADOW_SEGMENT_COUNT-1);
m_fHeightLength = m_fScale / (float)(SHADOW_SEGMENT_COUNT-1);
m_fWidthCenter = m_fScale / 2.f;
m_fHeightCenter = m_fScale / 2.f;
// Vertex Initialize
K3DBLENDEDBUMPVERTEX* pVertex = m_pVertex;
for(int h = 0; h < SHADOW_SEGMENT_COUNT; h++ )
{
for( int w = 0; w < SHADOW_SEGMENT_COUNT; w++)
{
pVertex->position = K3DVector( 0.f, 0.f, 0.f );
pVertex->normal = K3DVector( 0.f, 1.f, 0.f );
pVertex->color = 0xffffffff;
pVertex->texcoord.x = (static_cast<float>(w)/ (SHADOW_SEGMENT_COUNT-1) );
pVertex->texcoord.y = (static_cast<float>(h)/ (SHADOW_SEGMENT_COUNT-1) );
pVertex->tangent = K3DVector4( 0.f, 0.f, 0.f, 0.f );
pVertex->matrixIndices = 0;
pVertex->matrixWeights.x = 0.f;
pVertex->matrixWeights.y = 0.f;
++pVertex;
}
}
m_vPos = K3DVector(0.f,0.f,0.f);
}
void SGameCircleShadowFX::Render( class KViewportObject** ppViewportList, int nViewportCount )
{
const float EPSILON = 0.1f;
const float ON_PROP_HEIGHT = 1.f;
const float ON_TERRAIN_HEIGHT = 0.3f;
K3DVector vPos = *m_pGameObj->GetPosition();
if( m_hCreaturehandle )
{
SGameObject* pCreature = m_pGameObj->GetGameObject( m_hCreaturehandle );
if( pCreature ) vPos = *pCreature->GetPosition();
m_hCreaturehandle = 0;
}
// 이동할때만 바꾸3
if( abs(m_vPos.x - vPos.x) > EPSILON || abs(m_vPos.y - vPos.y) > EPSILON )
{
m_vPos = vPos;
m_pPrimitive->GetRootMat()->_41 = m_vPos.x;
m_pPrimitive->GetRootMat()->_42 = m_vPos.y;
float fXPos, fYPos;
K3DBLENDEDBUMPVERTEX* pVertex = m_pVertex;
bool bIsOnProp = false;
WORD wTile = 0;
for( int h = 0; h < SHADOW_SEGMENT_COUNT; h++ )
{
for( int w = 0; w < SHADOW_SEGMENT_COUNT; w++ )
{
fXPos = (-m_fWidthCenter ) + (w*m_fWidthLength);
fYPos = m_fHeightCenter - (h*m_fHeightLength);
//0,0 으로 땡겨 찍은 좌표
pVertex->position.x = fXPos;
pVertex->position.y = fYPos;
//월드로 변환된 좌표
bIsOnProp = m_pGameObj->GetHeight( fXPos + m_vPos.x , fYPos + m_vPos.y, pVertex->position.z, wTile );
pVertex->position.z += bIsOnProp ? ON_PROP_HEIGHT : ON_TERRAIN_HEIGHT;
++pVertex;
}
}
m_vPos.z += bIsOnProp ? ON_PROP_HEIGHT : ON_TERRAIN_HEIGHT;
}
m_pPrimitive->SetVisibility( m_pGameObj->GetVisibility() );
m_pPrimitive->SetCenterPosition( K3DVector( m_vPos.x, m_vPos.y, m_vPos.z) );
for(int vit = 0; vit < nViewportCount; ++vit)
{
if( ppViewportList[vit]->GetAttributes() & KViewportObject::VIEWPORT_GAME )
{
ppViewportList[0]->Register( m_pPrimitive, KRenderObject::RENDEREFX_NONE );
break;
}
}
}