272 lines
7.5 KiB
C++
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;
|
|
}
|
|
}
|
|
} |