layout: restructure into src/ tests/ android/ scripts/ tools/

- extension/src/{port,platform,codepage} -> src/; native_render -> src/host
  (+ dxt, shaders/); libgr2 -> src/gr2; extension/third_party -> third_party
- extension/tests -> tests/port, libgr2/tests -> tests/gr2
- android-native -> android (build.sh, push-client.sh moved in)
- script -> scripts; tools/40250 -> tools/server; oracle -> tools/granny-oracle;
  perf tools -> tools/perf
- all build trees under build/ (native, release, android, port-gate)
- xrender:: CMake aliases -> mt::; port-map ledger impl paths rewritten

No code changes. ctest 15/15, port_gate macos+android PASS, port_map check 0 errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-29 19:08:19 +09:00
co-authored by Claude Opus 5.5
parent 70710477cf
commit a46093104c
2817 changed files with 13728 additions and 13744 deletions
+200
View File
@@ -0,0 +1,200 @@
#include "StdAfx.h"
#include "../EterBase/Utils.h"
#include "AttributeData.h"
const char c_szAttributeDataFileHeader[] = "AttributeData";
const int c_iAttributeDataFileHeaderLength = 13;
/*DWORD CAttributeData::GetCollisionDataCount() const
{
return m_CollisionDataVector.size();
}
BOOL CAttributeData::GetCollisionDataPointer(DWORD dwIndex, const TCollisionData ** c_ppCollisionData) const
{
if (dwIndex >= GetCollisionDataCount())
return FALSE;
*c_ppCollisionData = &m_CollisionDataVector[dwIndex];
return TRUE;
}
*/
const CStaticCollisionDataVector & CAttributeData::GetCollisionDataVector() const
{
return m_StaticCollisionDataVector;
}
const THeightDataVector & CAttributeData::GetHeightDataVector() const
{
return m_HeightDataVector;
}
DWORD CAttributeData::GetHeightDataCount() const
{
return m_HeightDataVector.size();
}
BOOL CAttributeData::GetHeightDataPointer(DWORD dwIndex, const THeightData ** c_ppHeightData) const
{
if (dwIndex >= GetHeightDataCount())
return FALSE;
*c_ppHeightData = &m_HeightDataVector[dwIndex];
return TRUE;
}
float CAttributeData::GetMaximizeRadius()
{
return m_fMaximizeRadius;
}
size_t CAttributeData::AddCollisionData(const CStaticCollisionData& data)
{
m_StaticCollisionDataVector.push_back(data);
return m_StaticCollisionDataVector.size();
}
bool CAttributeData::OnLoad(int /*iSize*/, const void * c_pvBuf)
{
if (!c_pvBuf)
{
// NOTE: 파일이 존재하지 않으면 다른곳에서 그래픽 모델을 기반으로 충돌 데이터를 생성하니 리소스를 파괴하지 않고 유지시킴.
return true;
}
const BYTE * c_pbBuf = static_cast<const BYTE *> (c_pvBuf);
char szHeader[c_iAttributeDataFileHeaderLength+1];
memcpy(szHeader, c_pbBuf, c_iAttributeDataFileHeaderLength+1);
c_pbBuf += c_iAttributeDataFileHeaderLength+1;
if (strcmp(szHeader, c_szAttributeDataFileHeader))
return FALSE;
DWORD dwCollisionDataCount;
DWORD dwHeightDataCount;
memcpy(&dwCollisionDataCount, c_pbBuf, sizeof(DWORD));
c_pbBuf += sizeof(DWORD);
memcpy(&dwHeightDataCount, c_pbBuf, sizeof(DWORD));
c_pbBuf += sizeof(DWORD);
m_StaticCollisionDataVector.clear();
m_StaticCollisionDataVector.resize(dwCollisionDataCount);
m_HeightDataVector.clear();
m_HeightDataVector.resize(dwHeightDataCount);
for (DWORD i = 0; i < dwCollisionDataCount; ++i)
{
CStaticCollisionData & rCollisionData = m_StaticCollisionDataVector[i];
memcpy(&rCollisionData.dwType, c_pbBuf, sizeof(DWORD));
c_pbBuf += sizeof(DWORD);
memcpy(rCollisionData.szName, c_pbBuf, 32);
c_pbBuf += 32;
memcpy(&rCollisionData.v3Position, c_pbBuf, sizeof(D3DXVECTOR3));
c_pbBuf += sizeof(D3DXVECTOR3);
switch(rCollisionData.dwType)
{
case COLLISION_TYPE_PLANE:
memcpy(rCollisionData.fDimensions, c_pbBuf, 2*sizeof(float));
c_pbBuf += 2*sizeof(float);
break;
case COLLISION_TYPE_BOX:
memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float));
c_pbBuf += 3*sizeof(float);
break;
case COLLISION_TYPE_SPHERE:
memcpy(rCollisionData.fDimensions, c_pbBuf, sizeof(float));
c_pbBuf += sizeof(float);
break;
case COLLISION_TYPE_CYLINDER:
memcpy(rCollisionData.fDimensions, c_pbBuf, 2*sizeof(float));
c_pbBuf += 2*sizeof(float);
break;
case COLLISION_TYPE_AABB:
memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float));
c_pbBuf += 3*sizeof(float);
break;
case COLLISION_TYPE_OBB:
memcpy(rCollisionData.fDimensions, c_pbBuf, 3*sizeof(float));
c_pbBuf += 3*sizeof(float);
break;
}
memcpy(rCollisionData.quatRotation, c_pbBuf, sizeof(D3DXQUATERNION));
c_pbBuf += sizeof(D3DXQUATERNION);
}
for (DWORD j = 0; j < dwHeightDataCount; ++j)
{
THeightData & rHeightData = m_HeightDataVector[j];
memcpy(rHeightData.szName, c_pbBuf, 32);
c_pbBuf += 32;
DWORD dwPrimitiveCount;
memcpy(&dwPrimitiveCount, c_pbBuf, sizeof(DWORD));
c_pbBuf += sizeof(DWORD);
rHeightData.v3VertexVector.clear();
rHeightData.v3VertexVector.resize(dwPrimitiveCount);
memcpy(&rHeightData.v3VertexVector[0], c_pbBuf, dwPrimitiveCount*sizeof(D3DXVECTOR3));
c_pbBuf += dwPrimitiveCount*sizeof(D3DXVECTOR3);
// Getting Maximize Radius
for (DWORD k = 0; k < rHeightData.v3VertexVector.size(); ++k)
{
m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].x)+50.0f);
m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].y)+50.0f);
m_fMaximizeRadius = fMAX(m_fMaximizeRadius, fabs(rHeightData.v3VertexVector[k].z)+50.0f);
}
// Getting Maximize Radius
}
return true;
}
void CAttributeData::OnClear()
{
m_StaticCollisionDataVector.clear();
m_HeightDataVector.clear();
}
bool CAttributeData::OnIsEmpty() const
{
if (!m_StaticCollisionDataVector.empty())
return false;
if (!m_HeightDataVector.empty())
return false;
return true;
}
bool CAttributeData::OnIsType(TType type)
{
if (CAttributeData::Type() == type)
return true;
return CResource::OnIsType(type);
}
CAttributeData::TType CAttributeData::Type()
{
static TType s_type = StringToType("CAttributeData");
return s_type;
}
void CAttributeData::OnSelfDestruct()
{
Clear();
}
CAttributeData::CAttributeData(const char * c_szFileName) : CResource(c_szFileName)
{
m_fMaximizeRadius = 0.0f;
}
CAttributeData::~CAttributeData()
{
}
+71
View File
@@ -0,0 +1,71 @@
#pragma once
#include "Resource.h"
#include "Ref.h"
#include "CollisionData.h"
typedef struct SHeightData
{
char szName[32+1];
std::vector<D3DXVECTOR3> v3VertexVector;
} THeightData;
typedef std::vector<THeightData> THeightDataVector;
class CAttributeData : public CResource
{
public:
typedef CRef<CAttributeData> TRef;
/*
enum ECollisionType
{
COLLISION_TYPE_PLANE,
COLLISION_TYPE_BOX,
COLLISION_TYPE_SPHERE,
COLLISION_TYPE_CYLINDER,
};
typedef struct SCollisionData
{
DWORD dwType;
char szName[32+1];
D3DXVECTOR3 v3Position;
float fDimensions[3];
D3DXQUATERNION quatRotation;
} TCollisionData;*/
public:
static TType Type();
public:
CAttributeData(const char * c_szFileName);
virtual ~CAttributeData();
//DWORD GetCollisionDataCount() const;
//BOOL GetCollisionDataPointer(DWORD dwIndex, const TCollisionData ** c_ppCollisionData) const;
const CStaticCollisionDataVector & GetCollisionDataVector() const;
const THeightDataVector & GetHeightDataVector() const;
size_t AddCollisionData(const CStaticCollisionData& collisionData); // return m_StaticCollisionDataVector.size();
DWORD GetHeightDataCount() const;
BOOL GetHeightDataPointer(DWORD dwIndex, const THeightData ** c_ppHeightData) const;
float GetMaximizeRadius();
protected:
bool OnLoad(int iSize, const void * c_pvBuf);
void OnClear();
bool OnIsEmpty() const;
bool OnIsType(TType type);
void OnSelfDestruct();
protected:
float m_fMaximizeRadius;
//std::vector<TCollisionData> m_CollisionDataVector;
CStaticCollisionDataVector m_StaticCollisionDataVector;
THeightDataVector m_HeightDataVector;
};
+222
View File
@@ -0,0 +1,222 @@
#include "StdAfx.h"
#include "../EterBase/Utils.h"
#include "AttributeInstance.h"
#include "GrpMath.h"
CDynamicPool<CAttributeInstance> CAttributeInstance::ms_kPool;
const float c_fStepSize = 50.0f;
bool CAttributeInstance::Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y)
{
if (IsEmpty())
return FALSE;
//fy *= -1.0f;
bool bPicked = false;
float nx = 0;
float ny = 0;
for (DWORD i = 0; i < m_v3HeightDataVector.size(); ++i)
for (DWORD j = 0; j < m_v3HeightDataVector[i].size(); j+=3)
{
const D3DXVECTOR3 & cv0 = m_v3HeightDataVector[i][j];
const D3DXVECTOR3 & cv2 = m_v3HeightDataVector[i][j+1];
const D3DXVECTOR3 & cv1 = m_v3HeightDataVector[i][j+2];
D3DXVECTOR3 n;
const auto vvv = (cv1 - cv0);
const auto vvv2 = (cv2 - cv0);
const auto vvv3 = (cv2 - cv1);
D3DXVec3Cross(&n,&vvv,&vvv2);
D3DXVECTOR3 x;
float t;
const auto _vv = (v - cv0);
t = - D3DXVec3Dot(&_vv,&n)/D3DXVec3Dot(&dir,&n);
x = v+t*dir;
const auto vvv4 = (x - cv0);
const auto vvv5 = (x - cv1);
const auto vvv6 = (x - cv2);
D3DXVECTOR3 temp;
D3DXVec3Cross(&temp,&vvv,&vvv4);
if (D3DXVec3Dot(&temp,&n)<0) continue;
D3DXVec3Cross(&temp,&vvv3,&vvv5);
if (D3DXVec3Dot(&temp,&n)<0) continue;
const auto _vv_ = (cv0 - cv2);
D3DXVec3Cross(&temp,&_vv_,&vvv6);
if (D3DXVec3Dot(&temp,&n)<0) continue;
if (bPicked)
{
if ((v.x-x.x)*(v.x-x.x)+(v.y-x.y)*(v.y-x.y)<(v.x-nx)*(v.x-nx)+(v.y-ny)*(v.y-ny))
{
nx=x.x;
ny=x.y;
}
}
else
{
nx = x.x;
ny = x.y;
}
bPicked = true;
}
if (bPicked)
{
out_x = nx;
out_y = ny;
}
return bPicked;
}
BOOL CAttributeInstance::GetHeight(float fx, float fy, float * pfHeight)
{
if(IsEmpty())
return FALSE;
fy *= -1.0f;
if (!IsInHeight(fx, fy))
return FALSE;
BOOL bFlag = FALSE;
for (DWORD i = 0; i < m_v3HeightDataVector.size(); ++i)
for (DWORD j = 0; j < m_v3HeightDataVector[i].size(); j+=3)
{
const D3DXVECTOR3 & c_rv3Vertex0 = m_v3HeightDataVector[i][j];
const D3DXVECTOR3 & c_rv3Vertex1 = m_v3HeightDataVector[i][j+1];
const D3DXVECTOR3 & c_rv3Vertex2 = m_v3HeightDataVector[i][j+2];
if (
fx<c_rv3Vertex0.x && fx<c_rv3Vertex1.x && fx<c_rv3Vertex2.x ||
fx>c_rv3Vertex0.x && fx>c_rv3Vertex1.x && fx>c_rv3Vertex2.x ||
fy<c_rv3Vertex0.y && fy<c_rv3Vertex1.y && fy<c_rv3Vertex2.y ||
fy>c_rv3Vertex0.y && fy>c_rv3Vertex1.y && fy>c_rv3Vertex2.y
)
continue;
if (IsInTriangle2D(c_rv3Vertex0.x, c_rv3Vertex0.y,
c_rv3Vertex1.x, c_rv3Vertex1.y,
c_rv3Vertex2.x, c_rv3Vertex2.y, fx, fy))
{
D3DXVECTOR3 v3Line1 = c_rv3Vertex1 - c_rv3Vertex0;
D3DXVECTOR3 v3Line2 = c_rv3Vertex2 - c_rv3Vertex0;
D3DXVECTOR3 v3Cross;
D3DXVec3Cross(&v3Cross, &v3Line1, &v3Line2);
D3DXVec3Normalize(&v3Cross, &v3Cross);
if (0.0f != v3Cross.z)
{
float fd = (v3Cross.x*c_rv3Vertex0.x + v3Cross.y*c_rv3Vertex0.y + v3Cross.z*c_rv3Vertex0.z);
float fm = (v3Cross.x*fx + v3Cross.y*fy);
*pfHeight = fMAX((fd - fm) / v3Cross.z, *pfHeight);
bFlag = TRUE;
}
}
}
return bFlag;
}
CAttributeData * CAttributeInstance::GetObjectPointer() const
{
return m_roAttributeData.GetPointer();
}
BOOL CAttributeInstance::IsInHeight(float fx, float fy)
{
float fdx = m_matGlobal._41 - fx;
float fdy = m_matGlobal._42 - fy;
if (sqrtf(fdx*fdx + fdy*fdy) > m_fHeightRadius)
return FALSE;
return TRUE;
}
void CAttributeInstance::SetObjectPointer(CAttributeData * pAttributeData)
{
Clear();
m_roAttributeData.SetPointer(pAttributeData);
}
void CAttributeInstance::RefreshObject(const D3DXMATRIX & c_rmatGlobal)
{
assert(!m_roAttributeData.IsNull());
m_matGlobal = c_rmatGlobal;
// Height
m_fHeightRadius = m_roAttributeData->GetMaximizeRadius();
DWORD dwHeightDataCount = m_roAttributeData->GetHeightDataCount();
m_v3HeightDataVector.clear();
m_v3HeightDataVector.resize(dwHeightDataCount);
for (DWORD i = 0; i < dwHeightDataCount; ++i)
{
const THeightData * c_pHeightData;
if (!m_roAttributeData->GetHeightDataPointer(i, &c_pHeightData))
continue;
DWORD dwVertexCount = c_pHeightData->v3VertexVector.size();
m_v3HeightDataVector[i].clear();
m_v3HeightDataVector[i].resize(dwVertexCount);
for (DWORD j = 0; j < dwVertexCount; ++j)
{
D3DXVec3TransformCoord(&m_v3HeightDataVector[i][j], &c_pHeightData->v3VertexVector[j], &m_matGlobal);
}
}
}
const char * CAttributeInstance::GetDataFileName() const
{
return m_roAttributeData->GetFileName();
}
void CAttributeInstance::CreateSystem(UINT uCapacity)
{
ms_kPool.Create(uCapacity);
}
void CAttributeInstance::DestroySystem()
{
ms_kPool.Destroy();
}
CAttributeInstance* CAttributeInstance::New()
{
return ms_kPool.Alloc();
}
void CAttributeInstance::Delete(CAttributeInstance* pkInst)
{
ms_kPool.Free(pkInst);
}
BOOL CAttributeInstance::IsEmpty() const
{
if (!m_v3HeightDataVector.empty())
return FALSE;
return TRUE;
}
void CAttributeInstance::Clear()
{
m_fHeightRadius = 0.0f;
m_fCollisionRadius = 0.0f;
D3DXMatrixIdentity(&m_matGlobal);
m_v3HeightDataVector.clear();
m_roAttributeData.SetPointer(NULL);
}
CAttributeInstance::CAttributeInstance()
{
}
CAttributeInstance::~CAttributeInstance()
{
}
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include <vector>
#include "AttributeData.h"
#include "Pool.h"
class CAttributeInstance
{
public:
CAttributeInstance();
virtual ~CAttributeInstance();
void Clear();
BOOL IsEmpty() const;
const char * GetDataFileName() const;
// NOTE : Object 전용
void SetObjectPointer(CAttributeData * pAttributeData);
void RefreshObject(const D3DXMATRIX & c_rmatGlobal);
CAttributeData * GetObjectPointer() const;
bool Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y);
BOOL IsInHeight(float fx, float fy);
BOOL GetHeight(float fx, float fy, float * pfHeight);
BOOL IsHeightData() const;
protected:
void SetGlobalMatrix(const D3DXMATRIX & c_rmatGlobal);
void SetGlobalPosition(const D3DXVECTOR3 & c_rv3Position);
protected:
float m_fCollisionRadius;
float m_fHeightRadius;
D3DXMATRIX m_matGlobal;
std::vector< std::vector<D3DXVECTOR3> > m_v3HeightDataVector;
CAttributeData::TRef m_roAttributeData;
/*
BOOL m_isHeightCached;
struct SHeightCacheData
{
float fxMin;
float fyMin;
float fxMax;
float fyMax;
DWORD dwxStep;
DWORD dwyStep;
std::vector<float> kVec_fHeight;
} m_kHeightCacheData;
*/
public:
static void CreateSystem(UINT uCapacity);
static void DestroySystem();
static CAttributeInstance* New();
static void Delete(CAttributeInstance* pkInst);
static CDynamicPool<CAttributeInstance> ms_kPool;
};
+644
View File
@@ -0,0 +1,644 @@
// Camera.cpp: implementation of the CCamera class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "../EterBase/Utils.h"
#include "Camera.h"
const float c_fDefaultResistance = 0.3f;
CCameraManager aCameraManager; // CCameraManager Instance
void CCamera::SetCameraMaxDistance(float fMax)
{
CAMERA_MAX_DISTANCE = fMax;
}
float CCamera::GetTargetHeight()
{
return m_fTarget_;
}
void CCamera::SetTargetHeight(float fTarget)
{
m_fTarget_=fTarget;
}
//////////////////////////////////////////////////////////////////////////
// CCamera
//////////////////////////////////////////////////////////////////////////
CCamera::CCamera() :
m_fEyeGroundHeightRatio(0.3f),
m_fTargetHeightLimitRatio(2.0f),
m_fResistance(c_fDefaultResistance),
m_isLock(false)
{
m_fDistance = 1.0f;
m_eCameraState = CAMERA_STATE_NORMAL;
m_eCameraStatePrev = CAMERA_STATE_NORMAL;
m_ulNumScreenBuilding = 0;
m_fPitchSum = 0.0f;
m_fRollSum = 0.0f;
m_fTerrainCollisionRadius = 50.0f;
m_fObjectCollisionRadius = 50.0f;
m_bDrag = false;
m_lMousePosX = -1;
m_lMousePosY = -1;
m_fTarget_ = CAMERA_TARGET_STANDARD;
m_v3AngularAcceleration = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v3AngularVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_bProcessTerrainCollision = true;
SetViewParams(D3DXVECTOR3(0.0f,0.0f,1.0f), D3DXVECTOR3(0.0f,0.0f,0.0f), D3DXVECTOR3(0.0f,1.0f,0.0f));
}
CCamera::~CCamera()
{
}
void CCamera::Lock()
{
m_isLock = true;
}
void CCamera::Unlock()
{
m_isLock = false;
}
bool CCamera::IsLock()
{
return m_isLock;
}
void CCamera::SetResistance(float fResistance)
{
m_fResistance = c_fDefaultResistance * fResistance;
}
void CCamera::Wheel(int nLen)
{
if (IsLock())
return;
float fAdd = (float)(nLen) * m_fResistance;
if ((m_v3AngularVelocity.y > 0.0f && fAdd < 0.0f) || (m_v3AngularVelocity.y < 0.0f && fAdd > 0.0f))
m_v3AngularVelocity.y = fAdd;
else
m_v3AngularVelocity.y += fAdd;
if (m_v3AngularVelocity.y > 500.0f)
m_v3AngularVelocity.y = 500.0f;
else if (m_v3AngularVelocity.y < -500.0f)
m_v3AngularVelocity.y = -500.0f;
}
void CCamera::BeginDrag(int nMouseX, int nMouseY)
{
if (IsLock())
return;
m_bDrag = true;
m_lMousePosX = nMouseX;
m_lMousePosY = nMouseY;
m_fPitchSum = 0.0f;
m_fRollSum = 0.0f;
}
bool CCamera::IsDraging()
{
if (IsLock())
return false;
return m_bDrag;
}
bool CCamera::EndDrag()
{
if (IsLock())
return false;
m_bDrag = false;
float fSum=sqrt(m_fPitchSum*m_fPitchSum+m_fRollSum*m_fRollSum);
m_fPitchSum = 0.0f;
m_fRollSum = 0.0f;
if (fSum<1.0f)
return false;
return true;
}
bool CCamera::Drag(int nMouseX, int nMouseY, LPPOINT lpReturnPoint)
{
if (IsLock())
return false;
if (!m_bDrag)
{
m_lMousePosX = nMouseX;
m_lMousePosY = nMouseY;
lpReturnPoint->x = m_lMousePosX;
lpReturnPoint->y = m_lMousePosY;
return false;
}
long lMouseX = nMouseX;
long lMouseY = nMouseY;
float fNewPitchVelocity = (float)(lMouseY - m_lMousePosY) * m_fResistance;
float fNewRotationVelocity = (float)(lMouseX - m_lMousePosX) * m_fResistance;
m_fPitchSum += fNewPitchVelocity;
m_fRollSum += fNewRotationVelocity;
if (CAMERA_STATE_CANTGOLEFT == GetCameraState())
fNewRotationVelocity = fMAX(0.0f, fNewRotationVelocity);
if (CAMERA_STATE_CANTGORIGHT == GetCameraState())
fNewRotationVelocity = fMIN(0.0f, fNewRotationVelocity);
if (CAMERA_STATE_CANTGODOWN == GetCameraState())
fNewPitchVelocity = fMAX(0.0f, fNewPitchVelocity);
m_v3AngularVelocity.x = fNewRotationVelocity;
m_v3AngularVelocity.z = fNewPitchVelocity;
m_lMousePosX = lMouseX;
m_lMousePosY = lMouseY;
lpReturnPoint->x = m_lMousePosX;
lpReturnPoint->y = m_lMousePosY;
return true;
}
//////////////////////////////////////////////////////////////////////////
// Update
void CCamera::SetCameraState(eCameraState eNewCameraState)
{
if (eNewCameraState == m_eCameraState)
return;
m_eCameraStatePrev = m_eCameraState;
m_eCameraState = eNewCameraState;
/*
if ((CAMERA_STATE_NORMAL == m_eCameraStatePrev))
{
m_fDistanceBackup = m_fDistance;
m_fPitchBackup = m_fPitch;
m_fRollBackup = m_fRoll;
}
else if ((CAMERA_STATE_CANTGODOWN == m_eCameraStatePrev) && (CAMERA_STATE_CANTGODOWN == m_eCameraState) )
{
m_v3EyeBackup = m_v3Eye;
}
*/
}
void CCamera::IncreaseNumSrcreenBuilding()
{
++m_ulNumScreenBuilding;
}
void CCamera::ResetNumScreenBuilding()
{
m_ulNumScreenBuilding = 0;
}
//////////////////////////////////////////////////////////////////////////
// Property
void CCamera::SetViewParams( const D3DXVECTOR3 &v3Eye, const D3DXVECTOR3& v3Target, const D3DXVECTOR3& v3Up)
{
if (IsLock())
return;
// Set attributes for the view matrix
m_v3Eye = v3Eye;
m_v3Target = v3Target;
m_v3Up = v3Up;
SetViewMatrix();
}
void CCamera::SetEye(const D3DXVECTOR3 & v3Eye)
{
if (IsLock())
return;
m_v3Eye = v3Eye;
SetViewMatrix();
}
void CCamera::SetTarget(const D3DXVECTOR3 & v3Target)
{
if (IsLock())
return;
m_v3Target = v3Target;
SetViewMatrix();
}
void CCamera::SetUp(const D3DXVECTOR3 & v3Up)
{
if (IsLock())
return;
m_v3Up = v3Up;
SetViewMatrix();
}
void CCamera::SetViewMatrix()
{
m_v3View = m_v3Target - m_v3Eye;
D3DXVECTOR3 v3CenterRay = -m_v3View;
CalculateRoll();
m_fDistance = D3DXVec3Length(&m_v3View);
assert(m_fDistance >= 0);
D3DXVec3Normalize(&m_v3View , &m_v3View);
D3DXVec3Cross(&m_v3Cross, &m_v3Up, &m_v3View);
D3DXVec3Normalize(&m_v3Cross, &m_v3Cross);
D3DXVec3Cross(&m_v3Up, &m_v3View, &m_v3Cross);
D3DXVec3Normalize(&m_v3Up, &m_v3Up);
const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
m_fPitch = D3DXVec3Dot(&m_v3Up, &vv);// / D3DXVec2Length(&v2ViewYZ);
if (m_fPitch >= 1)
m_fPitch = 1;
else if (m_fPitch <= -1)
m_fPitch = -1;
m_fPitch = acosf(m_fPitch);
m_fPitch *= (180.0f / D3DX_PI);
if ( 0 < m_v3View.z )
m_fPitch = -m_fPitch;
D3DXMatrixLookAtRH(&m_matView, &m_v3Eye, &m_v3Target, &m_v3Up);
float fDeterminantD3DMatView = D3DXMatrixfDeterminant(&m_matView);
D3DXMatrixInverse(&m_matInverseView, &fDeterminantD3DMatView, &m_matView);
m_matBillboard = m_matInverseView;
m_matBillboard._41 = 0.0f;
m_matBillboard._42 = 0.0f;
m_matBillboard._43 = 0.0f;
m_ViewRay.SetStartPoint(m_v3Target);
m_ViewRay.SetDirection(v3CenterRay, m_fDistance);
m_kCameraBottomToTerrainRay.SetStartPoint(m_v3Eye);
m_kCameraFrontToTerrainRay.SetStartPoint(m_v3Eye);
m_kCameraBackToTerrainRay.SetStartPoint(m_v3Eye);
m_kCameraLeftToTerrainRay.SetStartPoint(m_v3Eye);
m_kCameraRightToTerrainRay.SetStartPoint(m_v3Eye);
m_kTargetToCameraBottomRay.SetStartPoint(m_v3Target);
m_kCameraBottomToTerrainRay.SetDirection(-m_v3Up, 2.0f * m_fTerrainCollisionRadius);
m_kCameraFrontToTerrainRay.SetDirection(m_v3View, 4.0f * m_fTerrainCollisionRadius);
m_kCameraBackToTerrainRay.SetDirection(-m_v3View, m_fTerrainCollisionRadius);
m_kCameraLeftToTerrainRay.SetDirection(-m_v3Cross, 3.0f * m_fTerrainCollisionRadius);
m_kCameraRightToTerrainRay.SetDirection(m_v3Cross, 3.0f * m_fTerrainCollisionRadius);
const auto vv2 = (v3CenterRay - m_fTerrainCollisionRadius * m_v3Up);
m_kTargetToCameraBottomRay.SetDirection(v3CenterRay - m_fTerrainCollisionRadius * m_v3Up, D3DXVec3Length(&vv2));
m_kLeftObjectCollisionRay.SetStartPoint(m_v3Target);
m_kTopObjectCollisionRay.SetStartPoint(m_v3Target);
m_kRightObjectCollisionRay.SetStartPoint(m_v3Target);
m_kBottomObjectCollisionRay.SetStartPoint(m_v3Target);
const auto vv3 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Cross);
const auto vv4 = (v3CenterRay - m_fObjectCollisionRadius * m_v3Cross);
const auto vv5 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Up);
const auto vv6 = (v3CenterRay + m_fObjectCollisionRadius * m_v3Up);
m_kLeftObjectCollisionRay.SetDirection(v3CenterRay + m_fObjectCollisionRadius * m_v3Cross, D3DXVec3Length(&vv3));
m_kRightObjectCollisionRay.SetDirection(v3CenterRay - m_fObjectCollisionRadius * m_v3Cross, D3DXVec3Length(&vv4));
m_kTopObjectCollisionRay.SetDirection(v3CenterRay + m_fObjectCollisionRadius * m_v3Up, D3DXVec3Length(&vv5));
m_kBottomObjectCollisionRay.SetDirection(v3CenterRay - m_fObjectCollisionRadius * m_v3Up, D3DXVec3Length(&vv6));
}
void CCamera::Move(const D3DXVECTOR3 & v3Displacement)
{
if (IsLock())
return;
m_v3Eye += v3Displacement;
m_v3Target += v3Displacement;
SetViewMatrix();
}
void CCamera::Zoom(float fRatio)
{
if (IsLock())
return;
if (fRatio == 1.0f)
return;
D3DXVECTOR3 v3Temp = m_v3Eye - m_v3Target;
v3Temp *= fRatio;
m_v3Eye = v3Temp + m_v3Target;
SetViewMatrix();
}
void CCamera::MoveAlongView(float fDistance)
{
if (IsLock())
return;
D3DXVECTOR3 v3Temp;
D3DXVec3Normalize(&v3Temp, &m_v3View);
m_v3Eye += v3Temp * fDistance;
m_v3Target += v3Temp * fDistance;
SetViewMatrix();
}
void CCamera::MoveAlongCross(float fDistance)
{
if (IsLock())
return;
D3DXVECTOR3 v3Temp;
D3DXVec3Normalize(&v3Temp, &m_v3Cross);
m_v3Eye += v3Temp * fDistance;
m_v3Target += v3Temp * fDistance;
SetViewMatrix();
}
void CCamera::MoveAlongUp(FLOAT fDistance)
{
if (IsLock())
return;
D3DXVECTOR3 v3Temp ;
D3DXVec3Normalize(&v3Temp, &m_v3Up);
m_v3Target += v3Temp * fDistance;
m_v3Eye += v3Temp * fDistance;
SetViewMatrix();
}
void CCamera::MoveLateral(float fDistance)
{
if (IsLock())
return;
MoveAlongCross(fDistance);
}
void CCamera::MoveFront(float fDistance)
{
if (IsLock())
return;
D3DXVECTOR3 v3Temp = D3DXVECTOR3(m_v3View.x, m_v3View.y, 0.0f);
D3DXVec3Normalize(&v3Temp, &v3Temp);
m_v3Eye += v3Temp * fDistance;
m_v3Target += v3Temp * fDistance;
SetViewMatrix();
}
void CCamera::MoveVertical(float fDistance)
{
if (IsLock())
return;
m_v3Eye.z += fDistance;
m_v3Target.z += fDistance;
SetViewMatrix();
}
//void CCamera::RotateUpper(float fDegree)
//{
// D3DXMATRIX matRot;
// D3DXMatrixRotationAxis(&matRot, &m_v3Cross, -D3DXToRadian(fDegree));
// D3DXVec3TransformCoord(&m_v3View, &m_v3View, &matRot) ;
// D3DXVec3Cross(&m_v3Up, &m_v3View, &m_v3Cross);
//
// m_v3Target = m_v3Eye + m_v3View;
//
// SetViewMatrix() ;
//}
void CCamera::RotateEyeAroundTarget(float fPitchDegree, float fRollDegree)
{
if (IsLock())
return;
D3DXMATRIX matRot, matRotPitch, matRotRoll;
// 머리위로 넘어가기 막기...
if (m_fPitch + fPitchDegree > 80.0f)
{
fPitchDegree = 80.0f - m_fPitch;
}
else if( m_fPitch + fPitchDegree < -80.0f)
{
fPitchDegree = -80.0f - m_fPitch;
}
D3DXMatrixRotationAxis(&matRotPitch, &m_v3Cross, D3DXToRadian(fPitchDegree));
D3DXMatrixRotationZ(&matRotRoll, -D3DXToRadian(fRollDegree));
matRot = matRotPitch * matRotRoll;
D3DXVECTOR3 v3Temp = m_v3Eye - m_v3Target;
D3DXVec3TransformCoord(&m_v3Eye, &v3Temp, &matRot);
m_v3Eye += m_v3Target;
SetUp(D3DXVECTOR3(0.0f, 0.0f, 1.0f));
m_fRoll += fRollDegree;
if (m_fRoll > 360.0f)
m_fRoll -= 360.0f;
else if (m_fRoll < -360.0f)
m_fRoll += 360.0f;
}
void CCamera::RotateEyeAroundPoint(const D3DXVECTOR3 & v3Point, float fPitchDegree, float fRollDegree)
{
// if (IsLock())
// return;
D3DXMATRIX matRot, matRotPitch, matRotRoll;
D3DXMatrixRotationAxis(&matRotPitch, &m_v3Cross, D3DXToRadian(fPitchDegree));
D3DXMatrixRotationZ(&matRotRoll, -D3DXToRadian(fRollDegree));
matRot = matRotPitch * matRotRoll;
D3DXVECTOR3 v3Temp = m_v3Eye - v3Point;
D3DXVec3TransformCoord(&m_v3Eye, &v3Temp, &matRot);
m_v3Eye += v3Point;
const auto vv2 = (v3Temp + m_v3Up);
D3DXVec3TransformCoord(&m_v3Up, &vv2, &matRot);
m_v3Up -= (m_v3Eye - v3Point);
v3Temp = m_v3Target - v3Point;
D3DXVec3TransformCoord(&m_v3Target, &v3Temp, &matRot);
m_v3Target += v3Point;
SetViewMatrix();
}
void CCamera::Pitch(const float fPitchDelta)
{
// if (IsLock())
// return;
RotateEyeAroundTarget(fPitchDelta, 0.0f);
}
void CCamera::Roll(const float fRollDelta)
{
// if (IsLock())
// return;
RotateEyeAroundTarget(0.0f, fRollDelta);
}
void CCamera::SetDistance(const float fdistance)
{
// if (IsLock())
// return;
Zoom(fdistance/m_fDistance);
}
void CCamera::CalculateRoll()
{
D3DXVECTOR2 v2ViewXY;
v2ViewXY.x = m_v3View.x;
v2ViewXY.y = m_v3View.y;
D3DXVec2Normalize(&v2ViewXY, &v2ViewXY);
const auto vv = D3DXVECTOR2(0.0f, 1.0f);
float fDot = D3DXVec2Dot(&v2ViewXY, &vv);
if (fDot >= 1)
fDot = 1;
else if (fDot <= -1)
fDot = -1;
fDot = acosf(fDot);
fDot *= (180.0f / D3DX_PI);
float fCross = D3DXVec2CCW (&v2ViewXY, &vv);
if ( 0 > fCross)
{
fDot = -fDot;
}
m_fRoll = fDot;
}
//////////////////////////////////////////////////////////////////////////
// CCameraMananger
//////////////////////////////////////////////////////////////////////////
CCameraManager::CCameraManager() :
m_pCurrentCamera(NULL),
m_pPreviousCamera(NULL)
{
AddCamera(DEFAULT_PERSPECTIVE_CAMERA);
AddCamera(DEFAULT_ORTHO_CAMERA);
SetCurrentCamera(DEFAULT_PERSPECTIVE_CAMERA);
}
CCameraManager::~CCameraManager()
{
for (TCameraMap::iterator itor = m_CameraMap.begin(); itor != m_CameraMap.end(); ++itor)
{
delete (*itor).second;
}
m_CameraMap.clear();
}
CCamera * CCameraManager::GetCurrentCamera()
{
if (!m_pCurrentCamera)
assert(false);
return m_pCurrentCamera;
}
void CCameraManager::SetCurrentCamera(unsigned char ucCameraNum)
{
if (m_pCurrentCamera != m_CameraMap[ucCameraNum])
m_pPreviousCamera = m_pCurrentCamera;
m_pCurrentCamera = m_CameraMap[ucCameraNum];
}
void CCameraManager::ResetToPreviousCamera()
{
if (!m_pPreviousCamera)
assert(false);
m_pCurrentCamera = m_pPreviousCamera;
m_pPreviousCamera = NULL;
}
bool CCameraManager::isCurrentCamera(unsigned char ucCameraNum)
{
if (m_CameraMap[ucCameraNum] == m_pCurrentCamera)
return true;
return false;
}
// 잡스러운 함수들...
bool CCameraManager::AddCamera(unsigned char ucCameraNum)
{
if(m_CameraMap.end() != m_CameraMap.find(ucCameraNum))
return false;
m_CameraMap.insert(TCameraMap::value_type(ucCameraNum, new CCamera));
return true;
}
bool CCameraManager::RemoveCamera(unsigned char ucCameraNum)
{
TCameraMap::iterator itor = m_CameraMap.find(ucCameraNum);
if(m_CameraMap.end() == itor)
return false;
m_CameraMap.erase(itor);
return true;
}
unsigned char CCameraManager::GetCurrentCameraNum()
{
if (!m_pCurrentCamera)
return NO_CURRENT_CAMERA;
for (TCameraMap::iterator itor = m_CameraMap.begin(); itor != m_CameraMap.end(); ++itor)
if(m_pCurrentCamera == (*itor).second)
return (*itor).first;
return NO_CURRENT_CAMERA;
}
bool CCameraManager::isTerrainCollisionEnable()
{
return m_pCurrentCamera->isTerrainCollisionEnable();
}
void CCameraManager::SetTerrainCollision(bool bEnable)
{
m_pCurrentCamera->SetTerrainCollision(bEnable);
}
+285
View File
@@ -0,0 +1,285 @@
// Camera.h: interface for the CCamera class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_)
#define AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <map>
#include "../EterBase/Singleton.h"
#include "Ray.h"
const float CAMERA_TARGET_STANDARD = 100.0f;
const float CAMERA_TARGET_FACE = 150.0f;
typedef enum _eCameraState_
{
CAMERA_STATE_NORMAL,
CAMERA_STATE_CANTGODOWN,
CAMERA_STATE_CANTGORIGHT,
CAMERA_STATE_CANTGOLEFT,
CAMERA_STATE_SCREEN_BY_BUILDING,
CAMERA_STATE_SCREEN_BY_BUILDING_AND_TOOCLOSE,
} eCameraState;
class CCamera
{
public:
CCamera();
virtual ~CCamera();
static void SetCameraMaxDistance(float fMax);
void Lock();
void Unlock();
bool IsLock();
void Wheel(int nWheelLen);
bool Drag(int nMouseX, int nMouseY, LPPOINT lpReturnPoint);
bool EndDrag();
void BeginDrag(int nMouseX, int nMouseY);
bool IsDraging();
void SetResistance(float fResistance);
private:
const CCamera & operator = (const CCamera &) ; // 지원하지 않음
CCamera (const CCamera & ) ; //지원하지 않음
// Camera Update
eCameraState m_eCameraState;
eCameraState m_eCameraStatePrev;
float m_fPitchBackup;
float m_fRollBackup;
float m_fDistanceBackup;
float m_fTargetZBackUp;
D3DXVECTOR3 m_v3EyeBackup;
unsigned long m_ulNumScreenBuilding;
// protected:
bool m_isLock;
// Attributes for view matrix
D3DXVECTOR3 m_v3Eye;
D3DXVECTOR3 m_v3Target;
D3DXVECTOR3 m_v3Up;
// m_v3View = m_v3Target - m_v3Eye
D3DXVECTOR3 m_v3View;
// m_v3Cross = Cross(m_v3Up, m_v3View)
D3DXVECTOR3 m_v3Cross;
//ViewMatrixes
D3DXMATRIX m_matView;
D3DXMATRIX m_matInverseView;
D3DXMATRIX m_matBillboard; // Special matrix for billboarding effects
//추가분
float m_fPitch;
float m_fRoll;
float m_fDistance;
// 카메라 AI를 위한 Ray 들
// 카메라를 둘러싼 Ray
CRay m_kCameraBottomToTerrainRay;
CRay m_kCameraFrontToTerrainRay;
CRay m_kCameraBackToTerrainRay;
CRay m_kCameraLeftToTerrainRay;
CRay m_kCameraRightToTerrainRay;
CRay m_kTargetToCameraBottomRay;
CRay m_ViewRay;
CRay m_kLeftObjectCollisionRay;
CRay m_kTopObjectCollisionRay;
CRay m_kRightObjectCollisionRay;
CRay m_kBottomObjectCollisionRay;
float m_fTerrainCollisionRadius;
float m_fObjectCollisionRadius;
// protected:
float m_fTarget_;
float m_fEyeGroundHeightRatio;
float m_fTargetHeightLimitRatio;
float m_fPitchSum;
float m_fRollSum;
long m_lMousePosX;
long m_lMousePosY;
bool m_bDrag;
// protected:
// 물리
D3DXVECTOR3 m_v3AngularAcceleration;
D3DXVECTOR3 m_v3AngularVelocity;
float m_fResistance;
public:
//////////////////////////////////////////////////////////////////////////
// 물리
//////////////////////////////////////////////////////////////////////////
void SetAngularAcceleration(D3DXVECTOR3 v3AngularAcceleration) { m_v3AngularAcceleration = v3AngularAcceleration; }
//////////////////////////////////////////////////////////////////////////
// AI
//////////////////////////////////////////////////////////////////////////
void SetTerrainCollisionRadius(float fTerrainCollisionRadius) { m_fTerrainCollisionRadius = fTerrainCollisionRadius; }
void SetObjectCollisionRadius(float fObjectCollisionRadius) { m_fObjectCollisionRadius = fObjectCollisionRadius; }
CRay & GetViewRay() { return m_ViewRay; }
CRay & GetLeftObjectCollisionRay() { return m_kLeftObjectCollisionRay; }
CRay & GetRightObjectCollisionRay() { return m_kRightObjectCollisionRay; }
CRay & GetTopObjectCollisionRay() { return m_kTopObjectCollisionRay; }
CRay & GetBottomObjectCollisionRay() { return m_kBottomObjectCollisionRay; }
//////////////////////////////////////////////////////////////////////////
// Update
//////////////////////////////////////////////////////////////////////////
void Update();
eCameraState GetCameraState() {return m_eCameraState;}
void SetCameraState(eCameraState eNewCameraState);
void IncreaseNumSrcreenBuilding();
void ResetNumScreenBuilding();
unsigned long & GetNumScreenBuilding() { return m_ulNumScreenBuilding; }
const float & GetPitchBackUp() { return m_fPitchBackup; }
const float & GetRollBackUp() { return m_fRollBackup; }
const float & GetDistanceBackUp() { return m_fDistanceBackup; }
//////////////////////////////////////////////////////////////////////////
// properties
//////////////////////////////////////////////////////////////////////////
const D3DXVECTOR3 & GetEye() const { return m_v3Eye; }
const D3DXVECTOR3 & GetTarget() const { return m_v3Target; }
const D3DXVECTOR3 & GetUp() const { return m_v3Up; }
const D3DXVECTOR3 & GetView() const { return m_v3View; }
const D3DXVECTOR3 & GetCross() const { return m_v3Cross; }
const D3DXMATRIX & GetViewMatrix() const { return m_matView; }
const D3DXMATRIX & GetInverseViewMatrix() const { return m_matInverseView; }
const D3DXMATRIX & GetBillboardMatrix()const { return m_matBillboard; }
void SetViewParams(const D3DXVECTOR3 & v3Eye, const D3DXVECTOR3& v3Target, const D3DXVECTOR3& v3Up );
void SetEye(const D3DXVECTOR3 & v3Eye);
void SetTarget(const D3DXVECTOR3 & v3Target);
void SetUp(const D3DXVECTOR3 & v3Up);
float GetPitch() const { return m_fPitch; }
float GetRoll() const { return m_fRoll; }
float GetDistance() const { return m_fDistance; }
void Pitch(const float fPitchDelta); //돌아가는 각도를 넣는다.
void Roll(const float fRollDelta);
void SetDistance(const float fdistance);
//////////////////////////////////////////////////////////////////////////
// camera movement
//////////////////////////////////////////////////////////////////////////
// 말그대로 이동... 카메라 위치와 타겟 위치가 모두 달라진다.
void Move(const D3DXVECTOR3 & v3Displacement);
// 줌.. 카메라 위치만 이동.. 타겟 위치는 고정...
void Zoom(float fRatio);
// 뷰 방향으로 이동.. 타겟위치가 달라지므로 줌과는 다르다...
void MoveAlongView(float fDistance);
// 카메라 옆 방향으로 이동..
void MoveAlongCross(float fDistance);
// 카메라 업벡터 방향으로 이동...
void MoveAlongUp(float fDistance);
// 카메라 옆 방향으로 이동... MoveAlongCross과 동일..
void MoveLateral(float fDistance);
// 뷰 방향의 Z 성분을 무시한 XY평면 방향으로 이동..
void MoveFront(float fDistance);
// Z방향(연직 방향)으로 이동...
void MoveVertical(float fDistance);
// //카메라 위치는 고정시키고 머리만 든다. 타겟이 달라지겠죠?
// //회전각을 라디안이 아닌 "도(Degree)"로 넣는다.
// void RotateUpper(float fDegree);
// 타겟 중심으로 돈다. Eterlib의 SetAroundCamera의 기능과 유사...
// fPitchDegree는 수평(0도)로부터 아랫쪽으로 꺽어지는 각도...
// fRollDegree는 타겟 중심으로 시계방향으로 도는 각도...
void RotateEyeAroundTarget(float fPitchDegree, float fRollDegree);
// 도는 중심점을 따로 지정 그 점을 중심으로 돈다. 타겟 점도 달라지겠죠?
void RotateEyeAroundPoint(const D3DXVECTOR3 & v3Point, float fPitchDegree, float fRollDegree);
protected:
void SetViewMatrix();
void CalculateRoll();
public:
float GetTargetHeight();
void SetTargetHeight(float fTarget);
bool isTerrainCollisionEnable() { return m_bProcessTerrainCollision; }
void SetTerrainCollision(bool bEnable) { m_bProcessTerrainCollision = bEnable; }
private:
void ProcessTerrainCollision();
void ProcessBuildingCollision();
private:
bool m_bProcessTerrainCollision;
static float CAMERA_MIN_DISTANCE;
static float CAMERA_MAX_DISTANCE;
};
typedef std::map<BYTE, CCamera *> TCameraMap;
class CCameraManager : public CSingleton<CCameraManager>
{
public:
enum ECameraNum
{
NO_CURRENT_CAMERA,
DEFAULT_PERSPECTIVE_CAMERA,
DEFAULT_ORTHO_CAMERA,
CAMERA_MAX = 255
};
CCameraManager();
virtual ~CCameraManager();
bool AddCamera(unsigned char ucCameraNum);
bool RemoveCamera(unsigned char ucCameraNum);
CCamera * GetCurrentCamera();
void SetCurrentCamera(unsigned char ucCameraNum);
void ResetToPreviousCamera();
bool isCurrentCamera(unsigned char ucCameraNum);
unsigned char GetCurrentCameraNum();
bool isTerrainCollisionEnable();
void SetTerrainCollision(bool bEnable);
private:
TCameraMap m_CameraMap;
CCamera * m_pCurrentCamera;
CCamera * m_pPreviousCamera;
};
#endif // !defined(AFX_CAMERA_H__C5D086BE_7A03_4246_9145_336747C47D9E__INCLUDED_)
+840
View File
@@ -0,0 +1,840 @@
#include "StdAfx.h"
#include "CollisionData.h"
#include "Pool.h"
#include "GrpScreen.h"
#include "GrpMath.h"
#include "lineintersect_utils.h"
#include "StateManager.h"
const float gc_fReduceMove = 0.5f;
//const float gc_fSlideMoveSpeed = 5.0f;
/*inline D3DXVECTOR3 FitAtSpecifiedLength(const D3DXVECTOR3 & v3Vector, float length)
{
D3DXVECTOR3 v;
D3DXVec3Normalize(&v,&v3Vector);
return v*length;
}
*/
CDynamicPool<CSphereCollisionInstance> gs_sci;
CDynamicPool<CCylinderCollisionInstance> gs_cci;
CDynamicPool<CPlaneCollisionInstance> gs_pci;
CDynamicPool<CAABBCollisionInstance> gs_aci;
CDynamicPool<COBBCollisionInstance> gs_oci;
void DestroyCollisionInstanceSystem()
{
gs_sci.Destroy();
gs_cci.Destroy();
gs_pci.Destroy();
gs_aci.Destroy();
gs_oci.Destroy();
}
/////////////////////////////////////////////
// Base
CBaseCollisionInstance * CBaseCollisionInstance::BuildCollisionInstance(const CStaticCollisionData * c_pCollisionData, const D3DXMATRIX * pMat)
{
switch(c_pCollisionData->dwType)
{
case COLLISION_TYPE_PLANE:
{
CPlaneCollisionInstance * ppci = gs_pci.Alloc();
D3DXMATRIX matRotation;
D3DXMATRIX matTranslationLocal;
D3DXMatrixRotationQuaternion(&matRotation, &c_pCollisionData->quatRotation);
D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
D3DXMATRIX matTransform = matRotation * matTranslationLocal * *pMat;
TPlaneData & PlaneData = ppci->GetAttribute();
D3DXVec3TransformCoord(&PlaneData.v3Position, &c_pCollisionData->v3Position, pMat);
float fHalfWidth = c_pCollisionData->fDimensions[0] / 2.0f;
float fHalfLength = c_pCollisionData->fDimensions[1] / 2.0f;
PlaneData.v3QuadPosition[0].x = -fHalfWidth;
PlaneData.v3QuadPosition[0].y = -fHalfLength;
PlaneData.v3QuadPosition[0].z = 0.0f;
PlaneData.v3QuadPosition[1].x = +fHalfWidth;
PlaneData.v3QuadPosition[1].y = -fHalfLength;
PlaneData.v3QuadPosition[1].z = 0.0f;
PlaneData.v3QuadPosition[2].x = -fHalfWidth;
PlaneData.v3QuadPosition[2].y = +fHalfLength;
PlaneData.v3QuadPosition[2].z = 0.0f;
PlaneData.v3QuadPosition[3].x = +fHalfWidth;
PlaneData.v3QuadPosition[3].y = +fHalfLength;
PlaneData.v3QuadPosition[3].z = 0.0f;
for (DWORD i = 0; i < 4; ++i)
D3DXVec3TransformCoord(&PlaneData.v3QuadPosition[i], &PlaneData.v3QuadPosition[i], &matTransform);
D3DXVECTOR3 v3Line0 = PlaneData.v3QuadPosition[1] - PlaneData.v3QuadPosition[0];
D3DXVECTOR3 v3Line1 = PlaneData.v3QuadPosition[2] - PlaneData.v3QuadPosition[0];
D3DXVECTOR3 v3Line2 = PlaneData.v3QuadPosition[1] - PlaneData.v3QuadPosition[3];
D3DXVECTOR3 v3Line3 = PlaneData.v3QuadPosition[2] - PlaneData.v3QuadPosition[3];
D3DXVec3Normalize(&v3Line0, &v3Line0);
D3DXVec3Normalize(&v3Line1, &v3Line1);
D3DXVec3Normalize(&v3Line2, &v3Line2);
D3DXVec3Normalize(&v3Line3, &v3Line3);
D3DXVec3Cross(&PlaneData.v3Normal, &v3Line0, &v3Line1);
D3DXVec3Normalize(&PlaneData.v3Normal, &PlaneData.v3Normal);
D3DXVec3Cross(&PlaneData.v3InsideVector[0], &PlaneData.v3Normal, &v3Line0 );
D3DXVec3Cross(&PlaneData.v3InsideVector[1], &v3Line1, &PlaneData.v3Normal);
D3DXVec3Cross(&PlaneData.v3InsideVector[2], &v3Line2, &PlaneData.v3Normal);
D3DXVec3Cross(&PlaneData.v3InsideVector[3], &PlaneData.v3Normal, &v3Line3);
return ppci;
}
break;
case COLLISION_TYPE_BOX:
assert(false && "COLLISION_TYPE_BOX not implemented");
break;
case COLLISION_TYPE_AABB:
{
CAABBCollisionInstance * paci = gs_aci.Alloc();
D3DXMATRIX matTranslationLocal;
D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
D3DXMATRIX matTransform = *pMat;
D3DXVECTOR3 v3Pos;
v3Pos.x = matTranslationLocal._41;
v3Pos.y = matTranslationLocal._42;
v3Pos.z = matTranslationLocal._43;
TAABBData & AABBData = paci->GetAttribute();
AABBData.v3Min.x = v3Pos.x - c_pCollisionData->fDimensions[0];
AABBData.v3Min.y = v3Pos.y - c_pCollisionData->fDimensions[1];
AABBData.v3Min.z = v3Pos.z - c_pCollisionData->fDimensions[2];
AABBData.v3Max.x = v3Pos.x + c_pCollisionData->fDimensions[0];
AABBData.v3Max.y = v3Pos.y + c_pCollisionData->fDimensions[1];
AABBData.v3Max.z = v3Pos.z + c_pCollisionData->fDimensions[2];
D3DXVec3TransformCoord(&AABBData.v3Min, &AABBData.v3Min, &matTransform);
D3DXVec3TransformCoord(&AABBData.v3Max, &AABBData.v3Max, &matTransform);
return paci;
}
break;
case COLLISION_TYPE_OBB:
{
COBBCollisionInstance * poci = gs_oci.Alloc();
D3DXMATRIX matTranslationLocal; D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
D3DXMATRIX matRotation; D3DXMatrixRotationQuaternion(&matRotation, &c_pCollisionData->quatRotation);
D3DXMATRIX matTranslationWorld; D3DXMatrixIdentity(&matTranslationWorld);
matTranslationWorld._41 = pMat->_41; matTranslationWorld._42 = pMat->_42; matTranslationWorld._43 = pMat->_43; matTranslationWorld._44 = pMat->_44;
D3DXVECTOR3 v3Min, v3Max;
v3Min.x = c_pCollisionData->v3Position.x - c_pCollisionData->fDimensions[0];
v3Min.y = c_pCollisionData->v3Position.y - c_pCollisionData->fDimensions[1];
v3Min.z = c_pCollisionData->v3Position.z - c_pCollisionData->fDimensions[2];
v3Max.x = c_pCollisionData->v3Position.x + c_pCollisionData->fDimensions[0];
v3Max.y = c_pCollisionData->v3Position.y + c_pCollisionData->fDimensions[1];
v3Max.z = c_pCollisionData->v3Position.z + c_pCollisionData->fDimensions[2];
D3DXVec3TransformCoord(&v3Min, &v3Min, pMat);
D3DXVec3TransformCoord(&v3Max, &v3Max, pMat);
D3DXVECTOR3 v3Position = (v3Min + v3Max) * 0.5f;
TOBBData & OBBData = poci->GetAttribute();
OBBData.v3Min.x = v3Position.x - c_pCollisionData->fDimensions[0];
OBBData.v3Min.y = v3Position.y - c_pCollisionData->fDimensions[1];
OBBData.v3Min.z = v3Position.z - c_pCollisionData->fDimensions[2];
OBBData.v3Max.x = v3Position.x + c_pCollisionData->fDimensions[0];
OBBData.v3Max.y = v3Position.y + c_pCollisionData->fDimensions[1];
OBBData.v3Max.z = v3Position.z + c_pCollisionData->fDimensions[2];
D3DXMATRIX matTransform = *pMat;
D3DXMatrixIdentity(&OBBData.matRot); OBBData.matRot = *pMat;
OBBData.matRot._41 = 0; OBBData.matRot._42 = 0; OBBData.matRot._43 = 0; OBBData.matRot._44 = 1;
return poci;
}
break;
case COLLISION_TYPE_SPHERE:
{
CSphereCollisionInstance * psci = gs_sci.Alloc();
D3DXMATRIX matTranslationLocal;
D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
matTranslationLocal = matTranslationLocal * *pMat;
TSphereData & SphereData = psci->GetAttribute();
SphereData.v3Position.x = matTranslationLocal._41;
SphereData.v3Position.y = matTranslationLocal._42;
SphereData.v3Position.z = matTranslationLocal._43;
SphereData.fRadius = c_pCollisionData->fDimensions[0];
return psci;
}
break;
case COLLISION_TYPE_CYLINDER:
{
CCylinderCollisionInstance * pcci = gs_cci.Alloc();
D3DXMATRIX matTranslationLocal;
D3DXMatrixTranslation(&matTranslationLocal, c_pCollisionData->v3Position.x, c_pCollisionData->v3Position.y, c_pCollisionData->v3Position.z);
matTranslationLocal = matTranslationLocal * *pMat;
TCylinderData & CylinderData = pcci->GetAttribute();
CylinderData.fRadius = c_pCollisionData->fDimensions[0];
CylinderData.fHeight = c_pCollisionData->fDimensions[1];
CylinderData.v3Position.x = matTranslationLocal._41;
CylinderData.v3Position.y = matTranslationLocal._42;
CylinderData.v3Position.z = matTranslationLocal._43 /*+ CylinderData.fHeight/2.0f*/;
return pcci;
}
break;
}
assert(false && "NOT_REACHED");
return 0;
}
void CBaseCollisionInstance::Destroy()
{
OnDestroy();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*------------------------------------------------------Sphere---------------------------------------------------------------*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TSphereData & CSphereCollisionInstance::GetAttribute()
{
return m_attribute;
}
const TSphereData & CSphereCollisionInstance::GetAttribute() const
{
return m_attribute;
}
void CSphereCollisionInstance::Render(D3DFILLMODE d3dFillMode)
{
static CScreen s;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
s.RenderSphere(NULL, m_attribute.v3Position.x, m_attribute.v3Position.y, m_attribute.v3Position.z, m_attribute.fRadius, d3dFillMode);
}
void CSphereCollisionInstance::OnDestroy()
{
gs_sci.Free(this);
}
bool CSphereCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
if (square_distance_between_linesegment_and_point(s.v3LastPosition,s.v3Position,m_attribute.v3Position) < (m_attribute.fRadius+s.fRadius)*(m_attribute.fRadius+s.fRadius))
{
// NOTE : 거리가 가까워 졌을때만.. - [levites]
if (GetVector3Distance(s.v3Position, m_attribute.v3Position) <
GetVector3Distance(s.v3LastPosition, m_attribute.v3Position))
return true;
}
return false;
}
bool CSphereCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
//Tracef("OnCollisionDynamicSphere\n");
if (square_distance_between_linesegment_and_point(s.v3LastPosition,s.v3Position,m_attribute.v3Position)<(m_attribute.fRadius+s.fRadius)*(m_attribute.fRadius+s.fRadius))
{
return true;
}
return false;
}
D3DXVECTOR3 CSphereCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
{
const auto _vv__ = (s.v3Position - m_attribute.v3Position);
if (D3DXVec3LengthSq(&_vv__)>=(s.fRadius+m_attribute.fRadius)*(m_attribute.fRadius+s.fRadius))
return D3DXVECTOR3(0.0f,0.0f,0.0f);
D3DXVECTOR3 c;
const auto _vv__2 = (s.v3Position - s.v3LastPosition);
const auto _vv_s_2 = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
D3DXVec3Cross(&c, &_vv__2, &_vv_s_2);
float sum = - D3DXVec3Dot(&c,&_vv__);
float mul = (s.fRadius+m_attribute.fRadius)*(s.fRadius+m_attribute.fRadius)-D3DXVec3LengthSq(&_vv__);
if (sum*sum-4*mul<=0)
return D3DXVECTOR3(0.0f,0.0f,0.0f);
float sq = sqrt(sum*sum-4*mul);
float t1=-sum-sq, t2=-sum+sq;
t1*=0.5f;
t2*=0.5f;
if (fabs(t1)<=fabs(t2))
{
return (gc_fReduceMove*t1)*c;
}
else
return (gc_fReduceMove*t2)*c;
/*
D3DXVECTOR3 p1 = s.v3Position+t1*c;
D3DXVECTOR3 p2 = s.v3Position+t2*c;
if (D3DXVec3LengthSq(&(p2-s.v3Position))>D3DXVec3LengthSq(&(p1-s.v3Position)))
{
return p1-s.v3Position;
}
else
{
return p2-s.v3Position;
}
*/
}
/////////////////////////////////////////////
// Plane
TPlaneData & CPlaneCollisionInstance::GetAttribute()
{
return m_attribute;
}
const TPlaneData & CPlaneCollisionInstance::GetAttribute() const
{
return m_attribute;
}
bool CPlaneCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
D3DXVECTOR3 v3SpherePosition = s.v3Position - m_attribute.v3Position;
D3DXVECTOR3 v3SphereLastPosition = s.v3LastPosition - m_attribute.v3Position;
float fPosition1 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SpherePosition);
float fPosition2 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SphereLastPosition);
if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f
|| (fPosition1) <= s.fRadius && fPosition1 >= -s.fRadius)
{
D3DXVECTOR3 v3QuadPosition1 = s.v3Position - m_attribute.v3QuadPosition[0];
D3DXVECTOR3 v3QuadPosition2 = s.v3Position - m_attribute.v3QuadPosition[3];
if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[0]) > - s.fRadius/*0.0f*/)
if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[1]) > -s.fRadius/*0.0f*/)
if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[2]) > - s.fRadius/*0.0f*/)
if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[3]) > - s.fRadius/*0.0f*/)
{
// NOTE : 거리가 가까워 졌을때만.. - [levites]
const auto _vv__3 = (s.v3Position - m_attribute.v3Position);
const auto _vv__4 = (s.v3LastPosition - m_attribute.v3Position);
if (fabs(D3DXVec3Dot(&_vv__3, &m_attribute.v3Normal)) <
fabs(D3DXVec3Dot(&_vv__4, &m_attribute.v3Normal)))
return true;
}
}
return false;
}
bool CPlaneCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
//Tracef("OnCollisionDynamicSphere\n");
D3DXVECTOR3 v3SpherePosition = s.v3Position - m_attribute.v3Position;
D3DXVECTOR3 v3SphereLastPosition = s.v3LastPosition - m_attribute.v3Position;
float fPosition1 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SpherePosition);
float fPosition2 = D3DXVec3Dot(&m_attribute.v3Normal, &v3SphereLastPosition);
if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f
|| (fPosition1) <= s.fRadius && fPosition1 >= -s.fRadius)
{
D3DXVECTOR3 v3QuadPosition1 = s.v3Position - m_attribute.v3QuadPosition[0];
D3DXVECTOR3 v3QuadPosition2 = s.v3Position - m_attribute.v3QuadPosition[3];
if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[0]) > - s.fRadius/*0.0f*/)
if (D3DXVec3Dot(&v3QuadPosition1, &m_attribute.v3InsideVector[1]) > -s.fRadius/*0.0f*/)
if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[2]) > - s.fRadius/*0.0f*/)
if (D3DXVec3Dot(&v3QuadPosition2, &m_attribute.v3InsideVector[3]) > - s.fRadius/*0.0f*/)
{
return true;
}
}
return false;
}
D3DXVECTOR3 CPlaneCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
{
D3DXVECTOR3 advance = s.v3Position-s.v3LastPosition;
float d = D3DXVec3Dot(&m_attribute.v3Normal, &advance);
if (d>=-0.0001 && d<=0.0001)
return D3DXVECTOR3(0.0f,0.0f,0.0f);
const auto vv = (s.v3Position - m_attribute.v3Position);
float t= - D3DXVec3Dot(&m_attribute.v3Normal, &vv)/d;
//D3DXVECTOR3 onplane = s.v3Position+t*advance;
if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0)
{
//return m_attribute.v3Normal*((-s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove);
return t*advance -s.fRadius*m_attribute.v3Normal;
}
else
{
//return m_attribute.v3Normal*((s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove);
return t*advance +s.fRadius*m_attribute.v3Normal;
}
/*if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0)
{
Tracef("%f %f\n",s.fRadius,-(D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position))));
return m_attribute.v3Normal*((-s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove);
}
else
{
Tracef("%f %f\n",(s.fRadius),(D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position))));
return m_attribute.v3Normal*((s.fRadius+D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position-m_attribute.v3Position)))*gc_fReduceMove);
}*/
/*
D3DXVECTOR3 advance = s.v3Position-s.v3LastPosition;
D3DXVECTOR3 slide(-advance.y,advance.x,advance.z);
slide = m_attribute.v3Normal;
D3DXVECTOR3 radius_adjust = advance;
D3DXVec3Normalize(&radius_adjust,&radius_adjust);
radius_adjust*=s.fRadius;
float d = D3DXVec3Dot(&m_attribute.v3Normal, &slide);
if (d>=-0.0001 && d<=0.0001)
return D3DXVECTOR3(0.0f,0.0f,0.0f);
float t= - D3DXVec3Dot(&m_attribute.v3Normal, &(s.v3Position+radius_adjust-m_attribute.v3Position))
/ d;*/
//D3DXVECTOR3 nextposition;
//nextposition = s.v3Position + t*slide;
//Tracef("$T %f",t);
//if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0)
// return (t*slide - m_attribute.v3Normal * s.fRadius)/**gc_fReduceMove*/;
//else
// return (t*slide + m_attribute.v3Normal * s.fRadius)/*gc_fReduceMove*/;
//if (D3DXVec3Dot(&m_attribute.v3Normal, &advance)>=0)
// return (t*slide + m_attribute.v3Normal * D3DXVec3Dot(&m_attribute.v3Normal,&(s.v3LastPosition-m_attribute.v3Position))/** s.fRadius*/)*gc_fReduceMove;
//else
// return (t*slide + m_attribute.v3Normal * D3DXVec3Dot(&m_attribute.v3Normal,&(s.v3LastPosition-m_attribute.v3Position))/*s.fRadius*/)*gc_fReduceMove;
//
}
void CPlaneCollisionInstance::Render(D3DFILLMODE /*d3dFillMode*/)
{
static CScreen s;
s.RenderBar3d(m_attribute.v3QuadPosition);
}
void CPlaneCollisionInstance::OnDestroy()
{
gs_pci.Free(this);
}
/////////////////////////////////////////////
// Cylinder
TCylinderData & CCylinderCollisionInstance::GetAttribute()
{
return m_attribute;
}
const TCylinderData & CCylinderCollisionInstance::GetAttribute() const
{
return m_attribute;
}
bool CCylinderCollisionInstance::CollideCylinderVSDynamicSphere(const TCylinderData & c_rattribute, const CDynamicSphereInstance & s) const
{
if (s.v3Position.z + s.fRadius < c_rattribute.v3Position.z)
return false;
if (s.v3Position.z - s.fRadius > c_rattribute.v3Position.z + c_rattribute.fHeight)
return false;
/*D3DXVECTOR2 v2curDistance(s.v3Position.x - c_rattribute.v3Position.x, s.v3Position.y - c_rattribute.v3Position.y);
float fDistance = D3DXVec2Length(&v2curDistance);
if (fDistance <= s.fRadius + c_rattribute.fRadius)
return true;
*/
D3DXVECTOR3 oa, ob;
IntersectLineSegments(c_rattribute.v3Position, D3DXVECTOR3(c_rattribute.v3Position.x,c_rattribute.v3Position.y,c_rattribute.v3Position.z+c_rattribute.fHeight), s.v3LastPosition, s.v3Position, oa, ob);
const auto vv = (oa - ob);
return (D3DXVec3LengthSq(&vv)<=(c_rattribute.fRadius+s.fRadius)*(c_rattribute.fRadius+s.fRadius));
}
bool CCylinderCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
if (CollideCylinderVSDynamicSphere(m_attribute, s))
{
// NOTE : 거리가 가까워 졌을때만.. - [levites]
if (GetVector3Distance(s.v3Position, m_attribute.v3Position) <
GetVector3Distance(s.v3LastPosition, m_attribute.v3Position))
return true;
}
// NOTE : 이동 거리가 클 경우 빈틈없이 (원 크기 단위로) 이동하면서 전부 체크 해 본다 - [levites]
D3DXVECTOR3 v3Distance = s.v3Position - s.v3LastPosition;
float fDistance = D3DXVec3Length(&v3Distance);
if (s.fRadius<=0.0001f)
return false;
if (fDistance >= s.fRadius*2.0f)
{
TCylinderData cylinder;
cylinder = m_attribute;
cylinder.v3Position = s.v3LastPosition;
int iStep = fDistance / s.fRadius*2.0f;
D3DXVECTOR3 v3Step = v3Distance / float(iStep);
for (int i = 0; i < iStep; ++i)
{
cylinder.v3Position += v3Step;
if (CollideCylinderVSDynamicSphere(cylinder, s))
return true;
}
}
return false;
}
bool CCylinderCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
//Tracef("OnCollisionDynamicSphere\n");
return (CollideCylinderVSDynamicSphere(m_attribute, s));
}
D3DXVECTOR3 CCylinderCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
{
D3DXVECTOR3 v3Position = m_attribute.v3Position;
v3Position.z = s.v3Position.z;
const auto vv = (s.v3Position - v3Position);
if (D3DXVec3LengthSq(&vv)>=(s.fRadius+m_attribute.fRadius)*(m_attribute.fRadius+s.fRadius))
return D3DXVECTOR3(0.0f,0.0f,0.0f);
D3DXVECTOR3 c;
D3DXVECTOR3 advance = s.v3Position - s.v3LastPosition;
advance.z = 0;
const auto vssa = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
D3DXVec3Cross(&c, &advance, &vssa);
const auto svsvs = (s.v3Position - v3Position);
float sum = - D3DXVec3Dot(&c,&svsvs);
float mul = (s.fRadius+m_attribute.fRadius)*(s.fRadius+m_attribute.fRadius)-D3DXVec3LengthSq(&svsvs);
if (sum*sum-4*mul<=0)
return D3DXVECTOR3(0.0f,0.0f,0.0f);
float sq = sqrt(sum*sum-4*mul);
float t1=-sum-sq, t2=-sum+sq;
t1*=0.5f;
t2*=0.5f;
if (fabs(t1)<=fabs(t2))
{
return (gc_fReduceMove*t1)*c;
}
else
return (gc_fReduceMove*t2)*c;
/*D3DXVECTOR3 p1 = s.v3Position+t1*c;
D3DXVECTOR3 p2 = s.v3Position+t2*c;
if (D3DXVec3LengthSq(&(p2-s.v3Position))>D3DXVec3LengthSq(&(p1-s.v3Position)))
{
return p1-s.v3Position;
}
else
{
return p2-s.v3Position;
}*/
}
void CCylinderCollisionInstance::Render(D3DFILLMODE d3dFillMode)
{
static CScreen s;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
s.RenderCylinder(NULL, m_attribute.v3Position.x, m_attribute.v3Position.y, m_attribute.v3Position.z+m_attribute.fHeight/2, m_attribute.fRadius, m_attribute.fHeight, d3dFillMode);
}
void CCylinderCollisionInstance::OnDestroy()
{
gs_cci.Free(this);
}
/////////////////////////////////////////////
// AABB (Aligned Axis Bounding Box)
TAABBData & CAABBCollisionInstance::GetAttribute()
{
return m_attribute;
}
const TAABBData & CAABBCollisionInstance::GetAttribute() const
{
return m_attribute;
}
bool CAABBCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
D3DXVECTOR3 v;
D3DXVECTOR3 v3center = (m_attribute.v3Min + m_attribute.v3Max) * 0.5f;
memcpy(&v, &s.v3Position, sizeof(D3DXVECTOR3));
if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x;
if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x;
if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y;
if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y;
if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z;
if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z;
if(GetVector3Distance(v, s.v3Position) <= s.fRadius * s.fRadius)
{
return true;
}
memcpy(&v, &s.v3LastPosition, sizeof(D3DXVECTOR3));
if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x;
if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x;
if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y;
if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y;
if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z;
if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z;
if(GetVector3Distance(v, s.v3LastPosition) <= s.fRadius * s.fRadius)
{
return true;
}
return false;
}
bool CAABBCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
D3DXVECTOR3 v;
memcpy(&v, &s.v3Position, sizeof(D3DXVECTOR3));
if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x;
if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x;
if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y;
if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y;
if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z;
if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z;
if(v.x > m_attribute.v3Min.x && v.x < m_attribute.v3Max.x &&
v.y > m_attribute.v3Min.y && v.y < m_attribute.v3Max.y &&
v.z > m_attribute.v3Min.z && v.z < m_attribute.v3Max.z) { return true; }
if(GetVector3Distance(v, s.v3Position) <= s.fRadius * s.fRadius) { return true; }
memcpy(&v, &s.v3LastPosition, sizeof(D3DXVECTOR3));
if(v.x < m_attribute.v3Min.x) v.x = m_attribute.v3Min.x;
if(v.x > m_attribute.v3Max.x) v.x = m_attribute.v3Max.x;
if(v.y < m_attribute.v3Min.y) v.x = m_attribute.v3Min.y;
if(v.y > m_attribute.v3Max.y) v.x = m_attribute.v3Max.y;
if(v.z < m_attribute.v3Min.z) v.z = m_attribute.v3Min.z;
if(v.z > m_attribute.v3Max.z) v.z = m_attribute.v3Max.z;
if(v.x > m_attribute.v3Min.x && v.x < m_attribute.v3Max.x &&
v.y > m_attribute.v3Min.y && v.y < m_attribute.v3Max.y &&
v.z > m_attribute.v3Min.z && v.z < m_attribute.v3Max.z) { return true; }
if(GetVector3Distance(v, s.v3LastPosition) <= s.fRadius * s.fRadius) { return true; }
return false;
}
D3DXVECTOR3 CAABBCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
{
//Tracef("OnGetCollisionMovementAdjust v3Min.x = %f, v3Max.x = %f\n", m_attribute.v3Min.x, m_attribute.v3Max.x);
/*
float fARadius = D3DXVec3Length(&(m_attribute.v3Min - m_attribute.v3Max));
if (D3DXVec3LengthSq(&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min)))>=(s.fRadius+fARadius)*(fARadius+s.fRadius))
return D3DXVECTOR3(0.0f,0.0f,0.0f);
D3DXVECTOR3 c;
D3DXVec3Cross(&c, &(s.v3Position-s.v3LastPosition), &D3DXVECTOR3(0.0f,0.0f,1.0f) );
float sum = - D3DXVec3Dot(&c,&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min)));
float mul = (s.fRadius+fARadius)*(s.fRadius+fARadius)-D3DXVec3LengthSq(&(s.v3Position-(m_attribute.v3Max + m_attribute.v3Min)));
if (sum*sum-4*mul<=0)
return D3DXVECTOR3(0.0f,0.0f,0.0f);
float sq = sqrt(sum*sum-4*mul);
float t1=-sum-sq, t2=-sum+sq;
t1*=0.5f;
t2*=0.5f;
if (fabs(t1)<=fabs(t2))
{
return (gc_fReduceMove*t1)*c;
}
else
return (gc_fReduceMove*t2)*c;
*/
D3DXVECTOR3 v3Temp;
if(s.v3Position.x + s.fRadius <= m_attribute.v3Min.x) { v3Temp.x = m_attribute.v3Min.x; }
else if(s.v3Position.x - s.fRadius >= m_attribute.v3Max.x) { v3Temp.x = m_attribute.v3Max.x; }
else if(s.v3Position.x + s.fRadius >= m_attribute.v3Min.x && s.v3Position.x + s.fRadius <= m_attribute.v3Max.x) { v3Temp.x = s.v3Position.x + s.fRadius; }
else { v3Temp.x = s.v3Position.x - s.fRadius; }
if(s.v3Position.y + s.fRadius <= m_attribute.v3Min.y) { v3Temp.y = m_attribute.v3Min.y; }
else if(s.v3Position.y - s.fRadius >= m_attribute.v3Max.y) { v3Temp.y = m_attribute.v3Max.y; }
else if(s.v3Position.y + s.fRadius >= m_attribute.v3Min.y && s.v3Position.y + s.fRadius <= m_attribute.v3Max.y) { v3Temp.y = s.v3Position.y + s.fRadius; }
else { v3Temp.y = s.v3Position.y - s.fRadius; }
if(s.v3Position.z + s.fRadius <= m_attribute.v3Min.z) { v3Temp.z = m_attribute.v3Min.z; }
else if(s.v3Position.z - s.fRadius >= m_attribute.v3Max.z) { v3Temp.z = m_attribute.v3Max.z; }
else if(s.v3Position.z + s.fRadius >= m_attribute.v3Min.z && s.v3Position.z + s.fRadius <= m_attribute.v3Max.z) { v3Temp.z = s.v3Position.z + s.fRadius; }
else { v3Temp.z = s.v3Position.z - s.fRadius; }
const auto vv = (v3Temp - s.v3Position);
if(D3DXVec3LengthSq(&vv) < s.fRadius * s.fRadius)
return D3DXVECTOR3(.0f, .0f, .0f);
return D3DXVECTOR3(.0f, .0f, .0f);
}
void CAABBCollisionInstance::Render(D3DFILLMODE d3dFillMode)
{
static CScreen s;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
s.RenderCube(m_attribute.v3Min.x, m_attribute.v3Min.y, m_attribute.v3Min.z, m_attribute.v3Max.x, m_attribute.v3Max.y, m_attribute.v3Max.z);
return;
}
void CAABBCollisionInstance::OnDestroy()
{
gs_aci.Free(this);
}
/////////////////////////////////////////////
// OBB
TOBBData & COBBCollisionInstance::GetAttribute()
{
return m_attribute;
}
const TOBBData & COBBCollisionInstance::GetAttribute() const
{
return m_attribute;
}
bool COBBCollisionInstance::OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
D3DXVECTOR3 v3Center = 0.5f * (m_attribute.v3Min + m_attribute.v3Max);
D3DXVECTOR3 v3Sphere = s.v3Position - v3Center;
D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot);
v3Sphere = v3Sphere + v3Center;
D3DXVECTOR3 v3Point = v3Sphere;
if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; }
if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; }
if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; }
if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; }
if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; }
if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; }
if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; }
v3Sphere = s.v3LastPosition - v3Center;
D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot);
v3Sphere = v3Sphere + v3Center;
v3Point = v3Sphere;
if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; }
if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; }
if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; }
if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; }
if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; }
if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; }
if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; }
return false;
}
bool COBBCollisionInstance::OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
D3DXVECTOR3 v3Center = 0.5f * (m_attribute.v3Min + m_attribute.v3Max);
D3DXVECTOR3 v3Sphere = s.v3Position - v3Center;
D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot);
v3Sphere = v3Sphere + v3Center;
D3DXVECTOR3 v3Point = v3Sphere;
if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; }
if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; }
if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; }
if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; }
if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; }
if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; }
if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; }
v3Sphere = s.v3LastPosition - v3Center;
D3DXVec3TransformCoord(&v3Sphere, &v3Sphere, &m_attribute.matRot);
v3Sphere = v3Sphere + v3Center;
v3Point = v3Sphere;
if(v3Point.x < m_attribute.v3Min.x) { v3Point.x = m_attribute.v3Min.x; }
if(v3Point.x > m_attribute.v3Max.x) { v3Point.x = m_attribute.v3Max.x; }
if(v3Point.y < m_attribute.v3Min.y) { v3Point.y = m_attribute.v3Min.y; }
if(v3Point.y > m_attribute.v3Max.y) { v3Point.y = m_attribute.v3Max.y; }
if(v3Point.z < m_attribute.v3Min.z) { v3Point.z = m_attribute.v3Min.z; }
if(v3Point.z > m_attribute.v3Max.z) { v3Point.z = m_attribute.v3Max.z; }
if(GetVector3Distance(v3Point, v3Sphere) <= s.fRadius * s.fRadius) { return true; }
return false;
}
D3DXVECTOR3 COBBCollisionInstance::OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
{
return D3DXVECTOR3(.0f, .0f, .0f);
}
void COBBCollisionInstance::Render(D3DFILLMODE d3dFillMode)
{
static CScreen s;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
s.RenderCube(m_attribute.v3Min.x, m_attribute.v3Min.y, m_attribute.v3Min.z, m_attribute.v3Max.x, m_attribute.v3Max.y, m_attribute.v3Max.z, m_attribute.matRot);
return;
}
void COBBCollisionInstance::OnDestroy()
{
gs_oci.Free(this);
}
+206
View File
@@ -0,0 +1,206 @@
#pragma once
// Collision Detection
typedef struct SSphereData
{
D3DXVECTOR3 v3Position;
float fRadius;
} TSphereData;
typedef struct SPlaneData
{
D3DXVECTOR3 v3Position;
D3DXVECTOR3 v3Normal;
D3DXVECTOR3 v3QuadPosition[4];
D3DXVECTOR3 v3InsideVector[4];
} TPlaneData;
typedef struct SAABBData
{
D3DXVECTOR3 v3Min;
D3DXVECTOR3 v3Max;
} TAABBData;
typedef struct SOBBData
{
D3DXVECTOR3 v3Min;
D3DXVECTOR3 v3Max;
D3DXMATRIX matRot;
} TOBBData;
typedef struct SCylinderData
{
D3DXVECTOR3 v3Position;
float fRadius;
float fHeight;
} TCylinderData;
enum ECollisionType
{
COLLISION_TYPE_PLANE,
COLLISION_TYPE_BOX,
COLLISION_TYPE_SPHERE,
COLLISION_TYPE_CYLINDER,
COLLISION_TYPE_AABB,
COLLISION_TYPE_OBB,
};
struct CDynamicSphereInstance
{
D3DXVECTOR3 v3Position;
D3DXVECTOR3 v3LastPosition;
float fRadius;
};
class CStaticCollisionData
{
public:
DWORD dwType;
char szName[32+1];
D3DXVECTOR3 v3Position;
float fDimensions[3];
D3DXQUATERNION quatRotation;
};
void DestroyCollisionInstanceSystem();
typedef std::vector<CStaticCollisionData> CStaticCollisionDataVector;
/////////////////////////////////////////////
// Base
class CBaseCollisionInstance
{
public:
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID) = 0;
bool MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
return OnMovementCollisionDynamicSphere(s);
}
bool CollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
return OnCollisionDynamicSphere(s);
}
D3DXVECTOR3 GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
{
return OnGetCollisionMovementAdjust(s);
}
void Destroy();
static CBaseCollisionInstance * BuildCollisionInstance(const CStaticCollisionData * c_pCollisionData, const D3DXMATRIX * pMat);
protected:
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const = 0;
virtual bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const = 0;
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const = 0;
virtual void OnDestroy() = 0;
};
/////////////////////////////////////////////
// Sphere
class CSphereCollisionInstance : public CBaseCollisionInstance
{
public:
TSphereData & GetAttribute();
const TSphereData & GetAttribute() const;
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
protected:
void OnDestroy();
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
protected:
TSphereData m_attribute;
};
/////////////////////////////////////////////
// Plane
class CPlaneCollisionInstance : public CBaseCollisionInstance
{
public:
TPlaneData & GetAttribute();
const TPlaneData & GetAttribute() const;
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
protected:
void OnDestroy();
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
protected:
TPlaneData m_attribute;
};
/////////////////////////////////////////////
// AABB (Aligned Axis Bounding Box)
class CAABBCollisionInstance : public CBaseCollisionInstance
{
public:
TAABBData & GetAttribute();
const TAABBData & GetAttribute() const;
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
protected:
void OnDestroy();
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
protected:
TAABBData m_attribute;
};
/////////////////////////////////////////////
// OBB
class COBBCollisionInstance : public CBaseCollisionInstance
{
public:
TOBBData & GetAttribute();
const TOBBData & GetAttribute() const;
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
protected:
void OnDestroy();
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
protected:
TOBBData m_attribute;
};
/////////////////////////////////////////////
// Cylinder
class CCylinderCollisionInstance : public CBaseCollisionInstance
{
public:
TCylinderData & GetAttribute();
const TCylinderData & GetAttribute() const;
virtual void Render(D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
protected:
void OnDestroy();
bool OnMovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual bool OnCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
virtual D3DXVECTOR3 OnGetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
bool CollideCylinderVSDynamicSphere(const TCylinderData & c_rattribute, const CDynamicSphereInstance & s) const;
protected:
TCylinderData m_attribute;
};
typedef std::vector<CSphereCollisionInstance> CSphereCollisionInstanceVector;
typedef std::vector<CDynamicSphereInstance> CDynamicSphereInstanceVector;
typedef std::vector<CBaseCollisionInstance*> CCollisionInstanceVector;
+104
View File
@@ -0,0 +1,104 @@
#include "StdAfx.h"
#include "ColorTransitionHelper.h"
void CColorTransitionHelper::Clear(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha)
{
m_fSrcRed = c_rfRed;
m_fSrcGreen = c_rfGreen;
m_fSrcBlue = c_rfBlue;
m_fSrcAlpha = c_rfAlpha;
m_fDstRed = c_rfRed;
m_fDstGreen = c_rfGreen;
m_fDstBlue = c_rfBlue;
m_fDstAlpha = c_rfAlpha;
m_dwCurColor = 0x00000000;
m_dwStartTime = m_dwDuration = 0;
}
void CColorTransitionHelper::SetSrcColor(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha)
{
m_fSrcRed = c_rfRed;
m_fSrcGreen = c_rfGreen;
m_fSrcBlue = c_rfBlue;
m_fSrcAlpha = c_rfAlpha;
}
void CColorTransitionHelper::SetTransition(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha,
const DWORD & dwDuration)
{
m_fDstRed = c_rfRed;
m_fDstGreen = c_rfGreen;
m_fDstBlue = c_rfBlue;
m_fDstAlpha = c_rfAlpha;
m_dwDuration = dwDuration;
}
void CColorTransitionHelper::StartTransition()
{
m_bTransitionStarted = true;
m_dwStartTime = GetCurrentTime();
}
bool CColorTransitionHelper::Update()
{
// if (!m_bTransitionStarted)
// return false;
DWORD dwCurTime = GetCurrentTime();
DWORD dwElapsedTime = dwCurTime - m_dwStartTime;
float fpercent = (float)(dwElapsedTime) / (float)(m_dwDuration);
if (fpercent <= 0.0f)
fpercent = 0.0f;
if (fpercent >= 1.0f)
fpercent = 1.0f;
float fCurRed, fCurGreen, fCurBlue, fCurAlpha;
fCurRed = m_fSrcRed + (m_fDstRed - m_fSrcRed) * fpercent;
fCurGreen = m_fSrcGreen + (m_fDstGreen - m_fSrcGreen) * fpercent;
fCurBlue = m_fSrcBlue + (m_fDstBlue - m_fSrcBlue) * fpercent;
fCurAlpha = m_fSrcAlpha + (m_fDstAlpha - m_fSrcAlpha) * fpercent;
// Tracef("%f, %f, %f, %f\n", fCurRed, fCurGreen, fCurBlue, fCurAlpha);
m_dwCurColor = (((DWORD)(fCurAlpha * 255.0f)&0xff)<< 24) |
(((DWORD)(fCurRed * 255.0f)&0xff) << 16) |
(((DWORD)(fCurGreen * 255.0f)&0xff) << 8) |
((DWORD)(fCurBlue * 255.0f)&0xff);
if ( (1.0f == fpercent) && (fCurAlpha == m_fDstAlpha) && (fCurRed == m_fDstRed) && (fCurGreen == m_fDstGreen) && (fCurBlue == m_fDstBlue) )
{
m_bTransitionStarted = false;
return false;
}
return true;
}
const D3DCOLOR & CColorTransitionHelper::GetCurColor()
{
return m_dwCurColor;
}
CColorTransitionHelper::CColorTransitionHelper():m_bTransitionStarted(false)
{
Clear(0.0f, 0.0f, 0.0f, 0.0f);
}
CColorTransitionHelper::~CColorTransitionHelper()
{
Clear(0.0f, 0.0f, 0.0f, 0.0f);
}
+39
View File
@@ -0,0 +1,39 @@
#pragma once
class CColorTransitionHelper
{
public:
CColorTransitionHelper();
~CColorTransitionHelper();
void Clear(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha);
void SetSrcColor(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha);
void SetTransition(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha,
const DWORD & dwDuration);
const D3DCOLOR & GetCurColor();// { return m_dwCurColor; }
void StartTransition();
bool Update();
bool isTransitionStarted() { return m_bTransitionStarted; }
private:
D3DCOLOR m_dwCurColor; // 현재 색
DWORD m_dwStartTime; // 바뀌기 시작하는 시간
DWORD m_dwDuration; // 얼마 동안에 바뀌는가?
bool m_bTransitionStarted;
float m_fSrcRed, m_fSrcGreen, m_fSrcBlue, m_fSrcAlpha;
float m_fDstRed, m_fDstGreen, m_fDstBlue, m_fDstAlpha;
};
+176
View File
@@ -0,0 +1,176 @@
#include "StdAfx.h"
#include "CullingManager.h"
#include "GrpObjectInstance.h"
//#define COUNT_SHOWING_SPHERE
#ifdef COUNT_SHOWING_SPHERE
int showingcount = 0;
#endif
void CCullingManager::RayTraceCallback(const Vector3d &/*p1*/, // source pos of ray
const Vector3d &/*dir*/, // dest pos of ray
float distance,
const Vector3d &/*sect*/,
SpherePack *sphere)
{
//if (state!=VS_OUTSIDE)
//{
if (m_RayFarDistance<=0.0f || m_RayFarDistance>=distance)
{
#ifdef SPHERELIB_STRICT
if (sphere->IS_SPHERE)
puts("CCullingManager::RayTraceCallback");
#endif
m_list.push_back((CGraphicObjectInstance *)sphere->GetUserData());
}
//f((CGraphicObjectInstance *)sphere->GetUserData());
//}
}
void CCullingManager::VisibilityCallback(const Frustum &/*f*/,SpherePack *sphere,ViewState state)
{
#ifdef SPHERELIB_STRICT
if (sphere->IS_SPHERE)
puts("CCullingManager::VisibilityCallback");
#endif
CGraphicObjectInstance * pInstance = (CGraphicObjectInstance*)sphere->GetUserData();
/*if (state == VS_PARTIAL)
{
Vector3d v;
float r;
pInstance->GetBoundingSphere(v,r);
state = f.ViewVolumeTest(v,r);
}*/
if (state == VS_OUTSIDE)
{
#ifdef COUNT_SHOWING_SPHERE
if (pInstance->isShow())
{
Tracef("SH : %p ",sphere->GetUserData());
showingcount--;
Tracef("show size : %5d\n",showingcount);
}
#endif
pInstance->Hide();
}
else
{
#ifdef COUNT_SHOWING_SPHERE
if (!pInstance->isShow())
{
Tracef("HS : %p ",sphere->GetUserData());
showingcount++;
Tracef("show size : %5d\n",showingcount);
}
#endif
pInstance->Show();
}
}
void CCullingManager::RangeTestCallback(const Vector3d &/*p*/,float /*distance*/,SpherePack *sphere,ViewState state)
{
#ifdef SPHERELIB_STRICT
if (sphere->IS_SPHERE)
puts("CCullingManager::RangeTestCallback");
#endif
if (state!=VS_OUTSIDE)
{
m_list.push_back((CGraphicObjectInstance *)sphere->GetUserData());
//f((CGraphicObjectInstance *)sphere->GetUserData());
}
//assert(false && "NOT REACHED");
}
void CCullingManager::Reset()
{
m_Factory->Reset();
}
void CCullingManager::Update()
{
// TODO : update each object
// ÇÏÁö¸»°í °¢ÀÚ ÇÏ°Ô ÇØº¸ÀÚ
//DWORD time = ELTimer_GetMSec();
//Reset();
m_Factory->Process();
//Tracef("cull update : %3d ",ELTimer_GetMSec()-time);
}
void CCullingManager::Process()
{
//DWORD time = ELTimer_GetMSec();
//Frustum f;
UpdateViewMatrix();
UpdateProjMatrix();
BuildViewFrustum();
m_Factory->FrustumTest(GetFrustum(), this);
//Tracef("cull process : %3d ",ELTimer_GetMSec()-time);
}
CCullingManager::CullingHandle CCullingManager::Register(CGraphicObjectInstance * obj)
{
assert(obj);
#ifdef COUNT_SHOWING_SPHERE
Tracef("CR : %p ",obj);
showingcount++;
Tracef("show size : %5d\n",showingcount);
#endif
Vector3d center;
float radius;
obj->GetBoundingSphere(center,radius);
return m_Factory->AddSphere_(center,radius,obj, false);
}
void CCullingManager::Unregister(CullingHandle h)
{
#ifdef COUNT_SHOWING_SPHERE
if (((CGraphicObjectInstance*)h->GetUserData())->isShow())
{
Tracef("DE : %p ",h->GetUserData());
showingcount--;
Tracef("show size : %5d\n",showingcount);
}
#endif
m_Factory->Remove(h);
}
CCullingManager::CCullingManager()
{
m_Factory = new SpherePackFactory(
10000, // maximum count
6400, // root radius
1600, // leaf radius
400 // extra radius
);
}
CCullingManager::~CCullingManager()
{
delete m_Factory;
}
void CCullingManager::FindRange(const Vector3d &p, float radius)
{
m_list.clear();
m_Factory->RangeTest(p, radius, this);
}
void CCullingManager::FindRay(const Vector3d &p1, const Vector3d &dir)
{
m_RayFarDistance = -1;
m_list.clear();
m_Factory->RayTrace(p1,dir,this);
}
void CCullingManager::FindRayDistance(const Vector3d &p1, const Vector3d &dir, float distance)
{
m_RayFarDistance = distance;
m_list.clear();
m_Factory->RayTrace(p1,dir,this);
}
+149
View File
@@ -0,0 +1,149 @@
#pragma once
#include "GrpScreen.h"
#include "../EterBase/Singleton.h"
#include "../SphereLib/spherepack.h"
class CGraphicObjectInstance;
template <class T>
struct RangeTester : public SpherePackCallback
{
T * f;
float dist;
RangeTester(T * fn, float distance=-1)
: f(fn), dist(distance)
{}
virtual ~RangeTester()
{}
virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray
const Vector3d &dir, // dest pos of ray
float distance,
const Vector3d &sect,
SpherePack *sphere)
{
#ifdef SPHERELIB_STRICT
if (sphere->IS_SPHERE)
puts("RangeTester::RayTraceCallback");
#endif
if (dist<=0.0f || dist>=distance)
(*f)((CGraphicObjectInstance *)sphere->GetUserData());
};
virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state){};
virtual void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state)
{
#ifdef SPHERELIB_STRICT
if (sphere->IS_SPHERE)
puts("RangeTester::RangeTestCallback");
#endif
if (state!=VS_OUTSIDE)
(*f)((CGraphicObjectInstance *)sphere->GetUserData());
}
virtual void PointTest2dCallback(const Vector3d &p, SpherePack *sphere,ViewState state)
{
#ifdef SPHERELIB_STRICT
if (sphere->IS_SPHERE)
puts("RangeTester::PointTest2dCallback");
#endif
if (state!=VS_OUTSIDE)
{
#ifdef SPHERELIB_STRICT
puts("FIND!!");
#endif
(*f)((CGraphicObjectInstance *)sphere->GetUserData());
}
}
};
class CCullingManager : public CSingleton<CCullingManager>, public SpherePackCallback, private CScreen
{
public:
typedef SpherePack * CullingHandle;
typedef std::vector<CGraphicObjectInstance *> TRangeList;
CCullingManager();
virtual ~CCullingManager();
virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray
const Vector3d &dir, // dest pos of ray
float distance,
const Vector3d &sect,
SpherePack *sphere);
virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state);
void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state);
void Reset();
void Update();
void Process();
void FindRange(const Vector3d &p, float radius);
void FindRay(const Vector3d &p1, const Vector3d &dir);
void FindRayDistance(const Vector3d &p1, const Vector3d &dir, float distance);
void RangeTest(const Vector3d& p, float radius, SpherePackCallback* callback)
{
m_Factory->RangeTest(p, radius, callback);
}
void PointTest2d(const Vector3d& p, SpherePackCallback* callback)
{
m_Factory->PointTest2d(p, callback);
}
template <class T>
void ForInRange2d(const Vector3d& p, T* pFunc)
{
RangeTester<T> r(pFunc);
m_Factory->PointTest2d(p, &r);
}
template <class T>
void ForInRange(const Vector3d &p, float radius, T* pFunc)
{
RangeTester<T> r(pFunc);
m_Factory->RangeTest(p, radius, &r/*this*/);
}
template <class T>
void ForInRay(const Vector3d &p1, const Vector3d &dir, T* pFunc)
{
RangeTester<T> r(pFunc);
/*Vector3d p2;
//p2.Set(p.x+(dir.x*50000.0f),p.y+(dir.y*50000.0f),p.z+(dir.z*50000.0f));
p2.x = p.x+50000.0f*dir.x;
p2.y = p.y+50000.0f*dir.y;
p2.z = p.z+50000.0f*dir.z;
// p + (50000.0f*dir);//(p.x+(dir.x*50000.0f),p.y+(dir.y*50000.0f),p.z+(dir.z*50000.0f));*/
m_Factory->RayTrace(p1, dir, &r/*this*/);
}
template <class T>
void ForInRayDistance(const Vector3d &p, const Vector3d &dir, float distance, T* pFunc)
{
RangeTester<T> r(pFunc, distance);
m_Factory->RayTrace(p, dir, &r/*this*/);
}
CullingHandle Register(CGraphicObjectInstance * ob);
void Unregister(CullingHandle h);
TRangeList::iterator begin() { return m_list.begin(); }
TRangeList::iterator end() { return m_list.end(); }
protected:
TRangeList m_list;
float m_RayFarDistance;
SpherePackFactory * m_Factory;
};
+287
View File
@@ -0,0 +1,287 @@
// Decal.cpp: implementation of the CDecal class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "Decal.h"
#include "StateManager.h"
//////////////////////////////////////////////////////////////////////
// CDecal
//////////////////////////////////////////////////////////////////////
CDecal::CDecal():m_cfDecalEpsilon(0.25f)
{
Clear();
}
CDecal::~CDecal()
{
Clear();
}
void CDecal::Clear()
{
m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v3Normal = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v4LeftPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
m_v4RightPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
m_v4TopPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
m_v4BottomPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
m_v4FrontPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
m_v4BackPlane = D3DXPLANE(0.0f, 0.0f, 0.0f, 0.0f);
m_dwVertexCount = 0;
m_dwPrimitiveCount = 0;
m_TriangleFanStructVector.clear();
memset(m_Vertices, 0, sizeof(m_Vertices));
memset(m_Indices, 0, sizeof(m_Indices));
}
void CDecal::ClipMesh(DWORD dwPrimitiveCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal)
{
D3DXVECTOR3 v3NewVertex[9];
D3DXVECTOR3 v3NewNormal[9];
// Clip one triangle at a time
for(DWORD dwi = 0; dwi < dwPrimitiveCount; ++dwi)
{
const D3DXVECTOR3 & v3_1 = c_pv3Vertex[3 * dwi];
const D3DXVECTOR3 & v3_2 = c_pv3Vertex[3 * dwi + 1];
const D3DXVECTOR3 & v3_3 = c_pv3Vertex[3 * dwi + 2];
D3DXVECTOR3 v3Cross;
const auto vv_ = (v3_2 - v3_1);
const auto vv_2 = (v3_3 - v3_1);
D3DXVec3Cross(&v3Cross, &vv_, &vv_2);
if (D3DXVec3Dot(&m_v3Normal, &v3Cross) > ( m_cfDecalEpsilon ) * D3DXVec3Length(&v3Cross))
{
v3NewVertex[0] = v3_1;
v3NewVertex[1] = v3_2;
v3NewVertex[2] = v3_3;
v3NewNormal[0] = c_pv3Normal[3 * dwi];
v3NewNormal[1] = c_pv3Normal[3 * dwi + 1];
v3NewNormal[2] = c_pv3Normal[3 * dwi + 2];
DWORD dwCount = ClipPolygon(3, v3NewVertex, v3NewNormal, v3NewVertex, v3NewNormal);
if ((dwCount != 0) && (!AddPolygon(dwCount, v3NewVertex, v3NewNormal))) break;
}
}
}
bool CDecal::AddPolygon(DWORD dwAddCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 * /*c_pv3Normal */)
{
if (m_dwVertexCount + dwAddCount >= MAX_DECAL_VERTICES)
return false;
TTRIANGLEFANSTRUCT aTriangleFanStruct;
aTriangleFanStruct.m_wMinIndex = m_dwVertexCount;
aTriangleFanStruct.m_dwVertexCount = dwAddCount;
aTriangleFanStruct.m_dwPrimitiveCount = dwAddCount - 2;
aTriangleFanStruct.m_dwVBOffset = m_dwVertexCount;
m_TriangleFanStructVector.push_back(aTriangleFanStruct);
DWORD dwCount = m_dwVertexCount;
// Add polygon as a triangle fan
WORD * wIndex = m_Indices + dwCount;
m_dwPrimitiveCount += dwAddCount - 2;
//float fOne_over_1MinusDecalEpsilon = 1.0f / (1.0f - m_cfDecalEpsilon);
// Assign vertex colors
for (DWORD dwVertexNum = 0; dwVertexNum < dwAddCount; ++dwVertexNum)
{
*wIndex++ = (WORD) dwCount;
m_Vertices[dwCount].position = c_pv3Vertex[dwVertexNum];
//const D3DXVECTOR3 & v3Normal = c_pv3Normal[dwVertexNum];
//float fAlpha = (D3DXVec3Dot(&m_v3Normal, &v3Normal) / D3DXVec3Length(&v3Normal) - m_cfDecalEpsilon) * fOne_over_1MinusDecalEpsilon;
//m_Vertices[dwCount].diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, (fAlpha > 0.0f) ? fAlpha : 0.0f);
m_Vertices[dwCount].diffuse = 0xFFFFFFFF;
++dwCount;
}
m_dwVertexCount = dwCount;
return true;
}
DWORD CDecal::ClipPolygon(DWORD dwVertexCount,
const D3DXVECTOR3 *c_pv3Vertex,
const D3DXVECTOR3 *c_pv3Normal,
D3DXVECTOR3 *c_pv3NewVertex,
D3DXVECTOR3 *c_pv3NewNormal) const
{
D3DXVECTOR3 v3TempVertex[9];
D3DXVECTOR3 v3TempNormal[9];
// Clip against all six planes
DWORD dwCount = ClipPolygonAgainstPlane(m_v4LeftPlane, dwVertexCount, c_pv3Vertex, c_pv3Normal, v3TempVertex, v3TempNormal);
if (dwCount != 0)
{
dwCount = ClipPolygonAgainstPlane(m_v4RightPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal);
if (dwCount != 0)
{
dwCount = ClipPolygonAgainstPlane(m_v4BottomPlane, dwCount, c_pv3NewVertex, c_pv3NewNormal, v3TempVertex, v3TempNormal);
if (dwCount != 0)
{
dwCount = ClipPolygonAgainstPlane(m_v4TopPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal);
if (dwCount != 0)
{
dwCount = ClipPolygonAgainstPlane(m_v4BackPlane, dwCount, c_pv3NewVertex, c_pv3NewNormal, v3TempVertex, v3TempNormal);
if (dwCount != 0)
{
dwCount = ClipPolygonAgainstPlane(m_v4FrontPlane, dwCount, v3TempVertex, v3TempNormal, c_pv3NewVertex, c_pv3NewNormal);
}
}
}
}
}
return dwCount;
}
DWORD CDecal::ClipPolygonAgainstPlane(const D3DXPLANE& c_rv4Plane,
DWORD dwVertexCount,
const D3DXVECTOR3 *c_pv3Vertex,
const D3DXVECTOR3 *c_pv3Normal,
D3DXVECTOR3 *c_pv3NewVertex,
D3DXVECTOR3 *c_pv3NewNormal)
{
bool bNegative[10];
// Classify vertices
DWORD dwNegativeCount = 0;
for (DWORD dwi = 0; dwi < dwVertexCount; ++dwi)
{
bool bNeg = (D3DXPlaneDotCoord(&c_rv4Plane, &c_pv3Vertex[dwi]) < 0.0F);
bNegative[dwi] = bNeg;
dwNegativeCount += bNeg;
}
// Discard this polygon if it's completely culled
if (dwNegativeCount == dwVertexCount)
return 0;
DWORD dwCount = 0;
for (DWORD dwCurIndex = 0; dwCurIndex < dwVertexCount; ++dwCurIndex)
{
// dwPrevIndex is the index of the previous vertex
DWORD dwPrevIndex = (dwCurIndex != 0) ? dwCurIndex - 1 : dwVertexCount - 1;
if (bNegative[dwCurIndex])
{
if (!bNegative[dwPrevIndex])
{
// Current vertex is on negative side of plane,
// but previous vertex is on positive side.
const D3DXVECTOR3& v3_1 = c_pv3Vertex[dwPrevIndex];
const D3DXVECTOR3& v3_2 = c_pv3Vertex[dwCurIndex];
float ft = D3DXPlaneDotCoord(&c_rv4Plane, &v3_1) / (c_rv4Plane.a * (v3_1.x - v3_2.x) + c_rv4Plane.b * (v3_1.y - v3_2.y) + c_rv4Plane.c * (v3_1.z - v3_2.z));
c_pv3NewVertex[dwCount] = v3_1 * (1.0f - ft) + v3_2 * ft;
const D3DXVECTOR3& v3_n1 = c_pv3Normal[dwPrevIndex];
const D3DXVECTOR3& v3_n2 = c_pv3Normal[dwCurIndex];
c_pv3NewNormal[dwCount] = v3_n1 * (1.0f - ft) + v3_n2 * ft;
++dwCount;
}
}
else
{
if (bNegative[dwPrevIndex])
{
// Current vertex is on positive side of plane,
// but previous vertex is on negative side.
const D3DXVECTOR3& v3_1 = c_pv3Vertex[dwCurIndex];
const D3DXVECTOR3& v3_2 = c_pv3Vertex[dwPrevIndex];
float ft = D3DXPlaneDotCoord(&c_rv4Plane, &v3_1) / (c_rv4Plane.a * (v3_1.x - v3_2.x) + c_rv4Plane.b * (v3_1.y - v3_2.y) + c_rv4Plane.c * (v3_1.z - v3_2.z));
c_pv3NewVertex[dwCount] = v3_1 * (1.0f - ft) + v3_2 * ft;
const D3DXVECTOR3& v3_n1 = c_pv3Normal[dwCurIndex];
const D3DXVECTOR3& v3_n2 = c_pv3Normal[dwPrevIndex];
c_pv3NewNormal[dwCount] = v3_n1 * (1.0f - ft) + v3_n2 * ft;
++dwCount;
}
// Include current vertex
c_pv3NewVertex[dwCount] = c_pv3Vertex[dwCurIndex];
c_pv3NewNormal[dwCount] = c_pv3Normal[dwCurIndex];
++dwCount;
}
}
// Return number of vertices in clipped polygon
return dwCount;
}
/*
void CDecal::Update()
{
}
*/
void CDecal::Render()
{
D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld);
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
for (DWORD dwi = 0; dwi < m_TriangleFanStructVector.size(); ++dwi)
STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN,
m_TriangleFanStructVector[dwi].m_wMinIndex,
m_TriangleFanStructVector[dwi].m_dwVertexCount,
m_TriangleFanStructVector[dwi].m_dwPrimitiveCount,
m_Indices + m_TriangleFanStructVector[dwi].m_wMinIndex,
D3DFMT_INDEX16,
m_Vertices,
sizeof(TPDTVertex));
}
/*
//////////////////////////////////////////////////////////////////////////
// CDecalManager
//////////////////////////////////////////////////////////////////////////
CDecalManager aDecalManager;
CDecalManager::CDecalManager()
{
m_DecalPtrVector.clear();
}
CDecalManager::~CDecalManager()
{
m_DecalPtrVector.clear();
}
void CDecalManager::Add(CDecal * pDecal)
{
m_DecalPtrVector.push_back(pDecal);
}
void CDecalManager::Remove(CDecal * pDecal)
{
std::vector<CDecal *>::iterator aIterator;
for (aIterator = m_DecalPtrVector.begin(); aIterator != m_DecalPtrVector.end();)
{
if (*aIterator == pDecal)
aIterator = m_DecalPtrVector.erase(aIterator);
else
++aIterator;
}
}
void CDecalManager::Update()
{
for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi)
m_DecalPtrVector[dwi]->Update();
}
void CDecalManager::Render()
{
for (DWORD dwi = 0; dwi < m_DecalPtrVector.size(); ++dwi)
m_DecalPtrVector[dwi]->Render();
}
*/
+103
View File
@@ -0,0 +1,103 @@
// Decal.h: interface for the CDecal class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_)
#define AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "GrpBase.h"
class CDecal
{
public:
enum
{
MAX_DECAL_VERTICES = 256,
};
CDecal();
virtual ~CDecal();
void Clear();
virtual void Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth) = 0;
// virtual void Update();
virtual void Render();
protected:
//
D3DXVECTOR3 m_v3Center;
D3DXVECTOR3 m_v3Normal;
// Clip Plane
D3DXPLANE m_v4LeftPlane;
D3DXPLANE m_v4RightPlane;
D3DXPLANE m_v4BottomPlane;
D3DXPLANE m_v4TopPlane;
D3DXPLANE m_v4FrontPlane;
D3DXPLANE m_v4BackPlane;
// 개수
DWORD m_dwVertexCount;
DWORD m_dwPrimitiveCount;
// 버택스 버퍼와 인댁스 버퍼
// CGraphicVertexBuffer m_GraphicVertexBuffer;
// CGraphicIndexBuffer m_GraphicIndexBuffer;
// 버택스 버퍼와 인댁스 버퍼 대신에 배열 만들고 DrawIndexedPrimitiveUP로 그리자.
typedef struct
{
WORD m_wMinIndex;
DWORD m_dwVertexCount;
DWORD m_dwPrimitiveCount;
DWORD m_dwVBOffset;
} TTRIANGLEFANSTRUCT;
std::vector<TTRIANGLEFANSTRUCT> m_TriangleFanStructVector;
TPDTVertex m_Vertices[MAX_DECAL_VERTICES];
WORD m_Indices[MAX_DECAL_VERTICES];
const float m_cfDecalEpsilon;
protected:
bool AddPolygon(DWORD dwAddCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal);
void ClipMesh(DWORD dwPrimitiveCount, const D3DXVECTOR3 *c_pv3Vertex, const D3DXVECTOR3 *c_pv3Normal);
DWORD ClipPolygon(DWORD dwVertexCount,
const D3DXVECTOR3 *c_pv3Vertex,
const D3DXVECTOR3 *c_pv3Normal,
D3DXVECTOR3 *c_pv3NewVertex,
D3DXVECTOR3 *c_pv3NewNormal) const;
static DWORD ClipPolygonAgainstPlane(const D3DXPLANE& v4Plane,
DWORD dwVertexCount,
const D3DXVECTOR3 *c_pv3Vertex,
const D3DXVECTOR3 *c_pv3Normal,
D3DXVECTOR3 *c_pv3NewVertex,
D3DXVECTOR3 *c_pv3NewNormal);
};
/*
class CDecalManager : public CSingleton<CDecalManager>
{
public:
CDecalManager();
~CDecalManager();
void Add(CDecal * pDecal);
void Remove(CDecal * pDecal);
void Update();
void Render();
private:
std::vector<CDecal *> m_DecalPtrVector;
};
*/
#endif // !defined(AFX_DECAL_H__E3D27DFC_30CB_4995_B9B9_396B5E8A5F02__INCLUDED_)
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include "GrpDIB.h"
class CBlockTexture;
class CDibBar
{
public:
CDibBar();
virtual ~CDibBar();
bool Create(HDC hdc, DWORD dwWidth, DWORD dwHeight);
void Invalidate();
void SetClipRect(const RECT & c_rRect);
void ClearBar();
void Render(int ix, int iy);
protected:
DWORD __NearTextureSize(DWORD dwSize);
void __DivideTextureSize(DWORD dwSize, DWORD dwMax, DWORD * pdwxStep, DWORD * pdwxCount, DWORD * pdwxRest);
CBlockTexture * __BuildTextureBlock(DWORD dwxPos, DWORD dwyPos, DWORD dwImageWidth, DWORD dwImageHeight, DWORD dwTextureWidth, DWORD dwTextureHeight);
void __BuildTextureBlockList(DWORD dwWidth, DWORD dwHeight, DWORD dwMax=256);
virtual void OnCreate(){}
protected:
CGraphicDib m_dib;
std::vector<CBlockTexture *> m_kVec_pkBlockTexture;
DWORD m_dwWidth;
DWORD m_dwHeight;
};
+63
View File
@@ -0,0 +1,63 @@
#ifndef __INC_YMIR_ETERLIB_FILELOADERTHREAD_H__
#define __INC_YMIR_ETERLIB_FILELOADERTHREAD_H__
#include <deque>
#include "Thread.h"
#include "Mutex.h"
#include "../EterBase/MappedFile.h"
class CFileLoaderThread
{
public:
typedef struct SData
{
std::string stFileName;
CMappedFile File;
LPVOID pvBuf;
DWORD dwSize;
} TData;
public:
CFileLoaderThread();
~CFileLoaderThread();
int Create(void * arg);
public:
void Request(std::string & c_rstFileName);
bool Fetch(TData ** ppData);
void Shutdown();
protected:
static UINT CALLBACK EntryPoint(void * pThis);
UINT Run(void * arg);
void * Arg() const { return m_pArg; }
void Arg(void * arg) { m_pArg = arg; }
HANDLE m_hThread;
private:
void * m_pArg;
unsigned m_uThreadID;
protected:
UINT Setup();
UINT Execute(void * pvArg);
void Destroy();
void Process();
private:
std::deque<TData *> m_pRequestDeque;
Mutex m_RequestMutex;
std::deque<TData *> m_pCompleteDeque;
Mutex m_CompleteMutex;
HANDLE m_hSemaphore;
int m_iRestSemCount;
bool m_bShutdowned;
};
#endif
+49
View File
@@ -0,0 +1,49 @@
#pragma once
template<typename T>
class CFuncObject
{
public:
CFuncObject()
{
Clear();
}
virtual ~CFuncObject()
{
}
void Clear()
{
m_pSelfObject = NULL;
m_pFuncObject = NULL;
}
void Set(T* pSelfObject, void (T::*pFuncObject)())
{
m_pSelfObject = pSelfObject;
m_pFuncObject = pFuncObject;
}
bool IsEmpty()
{
if (m_pSelfObject != NULL)
return false;
if (m_pFuncObject != NULL)
return false;
return true;
}
void Run()
{
if (m_pSelfObject)
if (m_pFuncObject)
(m_pSelfObject->*m_pFuncObject)();
}
protected:
T * m_pSelfObject;
void (T::*m_pFuncObject) ();
};
+522
View File
@@ -0,0 +1,522 @@
#include "StdAfx.h"
#include "../EterBase/Utils.h"
#include "../EterBase/Timer.h"
#include "GrpBase.h"
#include "Camera.h"
#include "StateManager.h"
void PixelPositionToD3DXVECTOR3(const D3DXVECTOR3& c_rkPPosSrc, D3DXVECTOR3* pv3Dst)
{
pv3Dst->x=+c_rkPPosSrc.x;
pv3Dst->y=-c_rkPPosSrc.y;
pv3Dst->z=+c_rkPPosSrc.z;
}
void D3DXVECTOR3ToPixelPosition(const D3DXVECTOR3& c_rv3Src, D3DXVECTOR3* pv3Dst)
{
pv3Dst->x=+c_rv3Src.x;
pv3Dst->y=-c_rv3Src.y;
pv3Dst->z=+c_rv3Src.z;
}
UINT CGraphicBase::ms_iD3DAdapterInfo=0;
UINT CGraphicBase::ms_iD3DDevInfo=0;
UINT CGraphicBase::ms_iD3DModeInfo=0;
D3D_CDisplayModeAutoDetector CGraphicBase::ms_kD3DDetector;
HWND CGraphicBase::ms_hWnd;
HDC CGraphicBase::ms_hDC;
LPDIRECT3D8 CGraphicBase::ms_lpd3d = NULL;
LPDIRECT3DDEVICE8 CGraphicBase::ms_lpd3dDevice = NULL;
ID3DXMatrixStack * CGraphicBase::ms_lpd3dMatStack = NULL;
D3DPRESENT_PARAMETERS CGraphicBase::ms_d3dPresentParameter;
D3DVIEWPORT8 CGraphicBase::ms_Viewport;
HRESULT CGraphicBase::ms_hLastResult = NULL;
int CGraphicBase::ms_iWidth;
int CGraphicBase::ms_iHeight;
DWORD CGraphicBase::ms_faceCount = 0;
D3DCAPS8 CGraphicBase::ms_d3dCaps;
DWORD CGraphicBase::ms_dwD3DBehavior = 0;
DWORD CGraphicBase::ms_ptVS = 0;
DWORD CGraphicBase::ms_pntVS = 0;
DWORD CGraphicBase::ms_pnt2VS = 0;
D3DXMATRIX CGraphicBase::ms_matIdentity;
D3DXMATRIX CGraphicBase::ms_matView;
D3DXMATRIX CGraphicBase::ms_matProj;
D3DXMATRIX CGraphicBase::ms_matInverseView;
D3DXMATRIX CGraphicBase::ms_matInverseViewYAxis;
D3DXMATRIX CGraphicBase::ms_matWorld;
D3DXMATRIX CGraphicBase::ms_matWorldView;
D3DXMATRIX CGraphicBase::ms_matScreen0;
D3DXMATRIX CGraphicBase::ms_matScreen1;
D3DXMATRIX CGraphicBase::ms_matScreen2;
D3DXVECTOR3 CGraphicBase::ms_vtPickRayOrig;
D3DXVECTOR3 CGraphicBase::ms_vtPickRayDir;
float CGraphicBase::ms_fFieldOfView;
float CGraphicBase::ms_fNearY;
float CGraphicBase::ms_fFarY;
float CGraphicBase::ms_fAspect;
DWORD CGraphicBase::ms_dwWavingEndTime;
int CGraphicBase::ms_iWavingPower;
DWORD CGraphicBase::ms_dwFlashingEndTime;
D3DXCOLOR CGraphicBase::ms_FlashingColor;
// Terrain picking용 Ray... CCamera 이용하는 버전.. 기존의 Ray와 통합 필요...
CRay CGraphicBase::ms_Ray;
bool CGraphicBase::ms_bSupportDXT = true;
bool CGraphicBase::ms_isLowTextureMemory = false;
bool CGraphicBase::ms_isHighTextureMemory = false;
// 2004.11.18.myevan.DynamicVertexBuffer로 교체
/*
std::vector<TIndex> CGraphicBase::ms_lineIdxVector;
std::vector<TIndex> CGraphicBase::ms_lineTriIdxVector;
std::vector<TIndex> CGraphicBase::ms_lineRectIdxVector;
std::vector<TIndex> CGraphicBase::ms_lineCubeIdxVector;
std::vector<TIndex> CGraphicBase::ms_fillTriIdxVector;
std::vector<TIndex> CGraphicBase::ms_fillRectIdxVector;
std::vector<TIndex> CGraphicBase::ms_fillCubeIdxVector;
*/
LPD3DXMESH CGraphicBase::ms_lpSphereMesh = NULL;
LPD3DXMESH CGraphicBase::ms_lpCylinderMesh = NULL;
LPDIRECT3DVERTEXBUFFER8 CGraphicBase::ms_alpd3dPDTVB[PDT_VERTEXBUFFER_NUM];
LPDIRECT3DINDEXBUFFER8 CGraphicBase::ms_alpd3dDefIB[DEFAULT_IB_NUM];
bool CGraphicBase::IsLowTextureMemory()
{
return ms_isLowTextureMemory;
}
bool CGraphicBase::IsHighTextureMemory()
{
return ms_isHighTextureMemory;
}
bool CGraphicBase::IsFastTNL()
{
if (ms_dwD3DBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ||
ms_dwD3DBehavior & D3DCREATE_MIXED_VERTEXPROCESSING)
{
if (ms_d3dCaps.VertexShaderVersion>D3DVS_VERSION(1,0))
return true;
}
return false;
}
bool CGraphicBase::IsTLVertexClipping()
{
if (ms_d3dCaps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
return true;
return false;
}
void CGraphicBase::GetBackBufferSize(UINT* puWidth, UINT* puHeight)
{
*puWidth=ms_d3dPresentParameter.BackBufferWidth;
*puHeight=ms_d3dPresentParameter.BackBufferHeight;
}
void CGraphicBase::SetBackBufferSize(UINT uWidth, UINT uHeight)
{
ms_d3dPresentParameter.BackBufferWidth = uWidth;
ms_d3dPresentParameter.BackBufferHeight = uHeight;
ms_iWidth = uWidth;
ms_iHeight = uHeight;
ms_Viewport.Width = uWidth;
ms_Viewport.Height = uHeight;
}
void CGraphicBase::SetDefaultIndexBuffer(UINT eDefIB)
{
if (eDefIB>=DEFAULT_IB_NUM)
return;
STATEMANAGER.SetIndices(ms_alpd3dDefIB[eDefIB], 0);
}
bool CGraphicBase::SetPDTStream(SPDTVertex* pVertices, UINT uVtxCount)
{
return SetPDTStream((SPDTVertexRaw*)pVertices, uVtxCount);
}
bool CGraphicBase::SetPDTStream(SPDTVertexRaw* pSrcVertices, UINT uVtxCount)
{
if (!uVtxCount)
return false;
static DWORD s_dwVBPos=0;
if (s_dwVBPos>=PDT_VERTEXBUFFER_NUM)
s_dwVBPos=0;
IDirect3DVertexBuffer8* plpd3dFillRectVB=ms_alpd3dPDTVB[s_dwVBPos];
++s_dwVBPos;
assert(PDT_VERTEX_NUM>=uVtxCount);
if (uVtxCount >= PDT_VERTEX_NUM)
return false;
TPDTVertex* pDstVertices;
if (FAILED(
plpd3dFillRectVB->Lock(0, sizeof(TPDTVertex)*uVtxCount, (BYTE**)&pDstVertices, D3DLOCK_DISCARD)
))
{
STATEMANAGER.SetStreamSource(0, NULL, 0);
return false;
}
memcpy(pDstVertices, pSrcVertices, sizeof(TPDTVertex)*uVtxCount);
plpd3dFillRectVB->Unlock();
STATEMANAGER.SetStreamSource(0, plpd3dFillRectVB, sizeof(TPDTVertex));
return true;
}
DWORD CGraphicBase::GetAvailableTextureMemory()
{
assert(ms_lpd3dDevice!=NULL && "CGraphicBase::GetAvailableTextureMemory - D3DDevice is EMPTY");
static DWORD s_dwNextUpdateTime=0;
static DWORD s_dwTexMemSize=0;//ms_lpd3dDevice->GetAvailableTextureMem();
DWORD dwCurTime=ELTimer_GetMSec();
if (s_dwNextUpdateTime<dwCurTime)
{
s_dwNextUpdateTime=dwCurTime+5000;
s_dwTexMemSize=ms_lpd3dDevice->GetAvailableTextureMem();
}
return s_dwTexMemSize;
}
const D3DXMATRIX& CGraphicBase::GetViewMatrix()
{
return ms_matView;
}
const D3DXMATRIX & CGraphicBase::GetIdentityMatrix()
{
return ms_matIdentity;
}
void CGraphicBase::SetEyeCamera(float xEye, float yEye, float zEye,
float xCenter, float yCenter, float zCenter,
float xUp, float yUp, float zUp)
{
D3DXVECTOR3 vectorEye(xEye, yEye, zEye);
D3DXVECTOR3 vectorCenter(xCenter, yCenter, zCenter);
D3DXVECTOR3 vectorUp(xUp, yUp, zUp);
// CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
CCameraManager::Instance().GetCurrentCamera()->SetViewParams(vectorEye, vectorCenter, vectorUp);
UpdateViewMatrix();
}
void CGraphicBase::SetSimpleCamera(float x, float y, float z, float pitch, float roll)
{
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
D3DXVECTOR3 vectorEye(x, y, z);
pCamera->SetViewParams(D3DXVECTOR3(0.0f, y, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f));
pCamera->RotateEyeAroundTarget(pitch, roll);
pCamera->Move(vectorEye);
UpdateViewMatrix();
// This is levites's virtual(?) code which you should not trust.
ms_lpd3dDevice->GetTransform(D3DTS_WORLD, &ms_matWorld);
D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView);
}
void CGraphicBase::SetAroundCamera(float distance, float pitch, float roll, float lookAtZ)
{
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
pCamera->SetViewParams(D3DXVECTOR3(0.0f, -distance, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f));
pCamera->RotateEyeAroundTarget(pitch, roll);
D3DXVECTOR3 v3Target = pCamera->GetTarget();
v3Target.z = lookAtZ;
pCamera->SetTarget(v3Target);
// pCamera->Move(v3Target);
UpdateViewMatrix();
// This is levites's virtual(?) code which you should not trust.
ms_lpd3dDevice->GetTransform(D3DTS_WORLD, &ms_matWorld);
D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView);
}
void CGraphicBase::SetPositionCamera(float fx, float fy, float fz, float distance, float pitch, float roll)
{
// I wanna downward this code to the game control level. - [levites]
if (ms_dwWavingEndTime > CTimer::Instance().GetCurrentMillisecond())
{
if (ms_iWavingPower>0)
{
fx += float(rand() % ms_iWavingPower) / 10.0f;
fy += float(rand() % ms_iWavingPower) / 10.0f;
fz += float(rand() % ms_iWavingPower) / 10.0f;
}
}
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
if (!pCamera)
return;
pCamera->SetViewParams(D3DXVECTOR3(0.0f, -distance, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 1.0f));
pitch = fMIN(80.0f, fMAX(-80.0f, pitch) );
// Tracef("SetPosition Camera : %f, %f\n", pitch, roll);
pCamera->RotateEyeAroundTarget(pitch, roll);
pCamera->Move(D3DXVECTOR3(fx, fy, fz));
UpdateViewMatrix();
// This is levites's virtual(?) code which you should not trust.
STATEMANAGER.GetTransform(D3DTS_WORLD, &ms_matWorld);
D3DXMatrixMultiply(&ms_matWorldView, &ms_matWorld, &ms_matView);
}
void CGraphicBase::SetOrtho2D(float hres, float vres, float zres)
{
//CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_ORTHO_CAMERA);
D3DXMatrixOrthoOffCenterRH(&ms_matProj, 0, hres, vres, 0, 0, zres);
//UpdatePipeLineMatrix();
UpdateProjMatrix();
}
void CGraphicBase::SetOrtho3D(float hres, float vres, float zmin, float zmax)
{
//CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
D3DXMatrixOrthoRH(&ms_matProj, hres, vres, zmin, zmax);
//UpdatePipeLineMatrix();
UpdateProjMatrix();
}
void CGraphicBase::SetPerspective(float fov, float aspect, float nearz, float farz)
{
ms_fFieldOfView = fov;
//if (ms_d3dPresentParameter.BackBufferWidth>0 && ms_d3dPresentParameter.BackBufferHeight>0)
// ms_fAspect = float(ms_d3dPresentParameter.BackBufferWidth)/float(ms_d3dPresentParameter.BackBufferHeight);
//else
ms_fAspect = aspect;
ms_fNearY = nearz;
ms_fFarY = farz;
//CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
D3DXMatrixPerspectiveFovRH(&ms_matProj, D3DXToRadian(fov), ms_fAspect, nearz, farz);
//UpdatePipeLineMatrix();
UpdateProjMatrix();
}
void CGraphicBase::UpdateProjMatrix()
{
STATEMANAGER.SetTransform(D3DTS_PROJECTION, &ms_matProj);
}
void CGraphicBase::UpdateViewMatrix()
{
CCamera* pkCamera=CCameraManager::Instance().GetCurrentCamera();
if (!pkCamera)
return;
ms_matView = pkCamera->GetViewMatrix();
STATEMANAGER.SetTransform(D3DTS_VIEW, &ms_matView);
D3DXMatrixInverse(&ms_matInverseView, NULL, &ms_matView);
ms_matInverseViewYAxis._11 = ms_matInverseView._11;
ms_matInverseViewYAxis._12 = ms_matInverseView._12;
ms_matInverseViewYAxis._21 = ms_matInverseView._21;
ms_matInverseViewYAxis._22 = ms_matInverseView._22;
}
void CGraphicBase::UpdatePipeLineMatrix()
{
UpdateProjMatrix();
UpdateViewMatrix();
}
void CGraphicBase::SetViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight, float fMinZ, float fMaxZ)
{
ms_Viewport.X = dwX;
ms_Viewport.Y = dwY;
ms_Viewport.Width = dwWidth;
ms_Viewport.Height = dwHeight;
ms_Viewport.MinZ = fMinZ;
ms_Viewport.MaxZ = fMaxZ;
}
void CGraphicBase::GetTargetPosition(float * px, float * py, float * pz)
{
*px = CCameraManager::Instance().GetCurrentCamera()->GetTarget().x;
*py = CCameraManager::Instance().GetCurrentCamera()->GetTarget().y;
*pz = CCameraManager::Instance().GetCurrentCamera()->GetTarget().z;
}
void CGraphicBase::GetCameraPosition(float * px, float * py, float * pz)
{
*px = CCameraManager::Instance().GetCurrentCamera()->GetEye().x;
*py = CCameraManager::Instance().GetCurrentCamera()->GetEye().y;
*pz = CCameraManager::Instance().GetCurrentCamera()->GetEye().z;
}
void CGraphicBase::GetMatrix(D3DXMATRIX* pRetMatrix) const
{
assert(ms_lpd3dMatStack != NULL);
*pRetMatrix = *ms_lpd3dMatStack->GetTop();
}
const D3DXMATRIX* CGraphicBase::GetMatrixPointer() const
{
assert(ms_lpd3dMatStack!=NULL);
return ms_lpd3dMatStack->GetTop();
}
void CGraphicBase::GetSphereMatrix(D3DXMATRIX * pMatrix, float fValue)
{
D3DXMatrixIdentity(pMatrix);
pMatrix->_11 = fValue * ms_matWorldView._11;
pMatrix->_21 = fValue * ms_matWorldView._21;
pMatrix->_31 = fValue * ms_matWorldView._31;
pMatrix->_41 = fValue;
pMatrix->_12 = -fValue * ms_matWorldView._12;
pMatrix->_22 = -fValue * ms_matWorldView._22;
pMatrix->_32 = -fValue * ms_matWorldView._32;
pMatrix->_42 = -fValue;
}
float CGraphicBase::GetFOV()
{
return ms_fFieldOfView;
}
void CGraphicBase::PushMatrix()
{
ms_lpd3dMatStack->Push();
}
void CGraphicBase::Scale(float x, float y, float z)
{
ms_lpd3dMatStack->Scale(x, y, z);
}
void CGraphicBase::Rotate(float degree, float x, float y, float z)
{
D3DXVECTOR3 vec(x, y, z);
ms_lpd3dMatStack->RotateAxis(&vec, D3DXToRadian(degree));
}
void CGraphicBase::RotateLocal(float degree, float x, float y, float z)
{
D3DXVECTOR3 vec(x, y, z);
ms_lpd3dMatStack->RotateAxisLocal(&vec, D3DXToRadian(degree));
}
void CGraphicBase::MultMatrix( const D3DXMATRIX* pMat)
{
ms_lpd3dMatStack->MultMatrix(pMat);
}
void CGraphicBase::MultMatrixLocal( const D3DXMATRIX* pMat)
{
ms_lpd3dMatStack->MultMatrixLocal(pMat);
}
void CGraphicBase::RotateYawPitchRollLocal(float fYaw, float fPitch, float fRoll)
{
ms_lpd3dMatStack->RotateYawPitchRollLocal(D3DXToRadian(fYaw), D3DXToRadian(fPitch), D3DXToRadian(fRoll));
}
void CGraphicBase::Translate(float x, float y, float z)
{
ms_lpd3dMatStack->Translate(x, y, z);
}
void CGraphicBase::LoadMatrix(const D3DXMATRIX& c_rSrcMatrix)
{
ms_lpd3dMatStack->LoadMatrix(&c_rSrcMatrix);
}
void CGraphicBase::PopMatrix()
{
ms_lpd3dMatStack->Pop();
}
DWORD CGraphicBase::GetColor(float r, float g, float b, float a)
{
BYTE argb[4] =
{
(BYTE) (255.0f * b),
(BYTE) (255.0f * g),
(BYTE) (255.0f * r),
(BYTE) (255.0f * a)
};
return *((DWORD *) argb);
}
void CGraphicBase::InitScreenEffect()
{
ms_dwWavingEndTime = 0;
ms_dwFlashingEndTime = 0;
ms_iWavingPower = 0;
ms_FlashingColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f);
}
void CGraphicBase::SetScreenEffectWaving(float fDuringTime, int iPower)
{
ms_dwWavingEndTime = CTimer::Instance().GetCurrentMillisecond() + long(fDuringTime * 1000.0f);
ms_iWavingPower = iPower;
}
void CGraphicBase::SetScreenEffectFlashing(float fDuringTime, const D3DXCOLOR & c_rColor)
{
ms_dwFlashingEndTime = CTimer::Instance().GetCurrentMillisecond() + long(fDuringTime * 1000.0f);
ms_FlashingColor = c_rColor;
}
DWORD CGraphicBase::GetFaceCount()
{
return ms_faceCount;
}
void CGraphicBase::ResetFaceCount()
{
ms_faceCount = 0;
}
HRESULT CGraphicBase::GetLastResult()
{
return ms_hLastResult;
}
CGraphicBase::CGraphicBase()
{
}
CGraphicBase::~CGraphicBase()
{
}
+313
View File
@@ -0,0 +1,313 @@
#pragma once
#include "GrpDetector.h"
#include "Ray.h"
#include <vector>
void PixelPositionToD3DXVECTOR3(const D3DXVECTOR3& c_rkPPosSrc, D3DXVECTOR3* pv3Dst);
void D3DXVECTOR3ToPixelPosition(const D3DXVECTOR3& c_rv3Src, D3DXVECTOR3* pv3Dst);
class CGraphicTexture;
typedef WORD TIndex;
typedef struct SFace
{
TIndex indices[3];
} TFace;
typedef D3DXVECTOR3 TPosition;
typedef D3DXVECTOR3 TNormal;
typedef D3DXVECTOR2 TTextureCoordinate;
typedef DWORD TDiffuse;
typedef DWORD TAmbient;
typedef DWORD TSpecular;
typedef union UDepth
{
float f;
long l;
DWORD dw;
} TDepth;
typedef struct SVertex
{
float x, y, z;
DWORD color;
float u, v;
} TVertex;
struct STVertex
{
float x, y, z, rhw;
};
struct SPVertex
{
float x, y, z;
};
typedef struct SPDVertex
{
float x, y, z;
DWORD color;
} TPDVertex;
struct SPDTVertexRaw
{
float px, py, pz;
DWORD diffuse;
float u, v;
};
typedef struct SPTVertex
{
TPosition position;
TTextureCoordinate texCoord;
} TPTVertex;
typedef struct SPDTVertex
{
TPosition position;
TDiffuse diffuse;
TTextureCoordinate texCoord;
} TPDTVertex;
typedef struct SPNTVertex
{
TPosition position;
TNormal normal;
TTextureCoordinate texCoord;
} TPNTVertex;
typedef struct SPNT2Vertex
{
TPosition position;
TNormal normal;
TTextureCoordinate texCoord;
TTextureCoordinate texCoord2;
} TPNT2Vertex;
typedef struct SPDT2Vertex
{
TPosition position;
DWORD diffuse;
TTextureCoordinate texCoord;
TTextureCoordinate texCoord2;
} TPDT2Vertex;
typedef struct SNameInfo
{
DWORD name;
TDepth depth;
} TNameInfo;
typedef struct SBoundBox
{
float sx, sy, sz;
float ex, ey, ez;
int meshIndex;
int boneIndex;
} TBoundBox;
const WORD c_FillRectIndices[6] = { 0, 2, 1, 2, 3, 1 };
/*
enum EIndexCount
{
LINE_INDEX_COUNT = 2,
TRIANGLE_INDEX_COUNT = 2*3,
RECTANGLE_INDEX_COUNT = 2*4,
CUBE_INDEX_COUNT = 2*4*3,
FILLED_TRIANGLE_INDEX_COUNT = 3,
FILLED_RECTANGLE_INDEX_COUNT = 3*2,
FILLED_CUBE_INDEX_COUNT = 3*2*6,
};
*/
class CGraphicBase
{
public:
static DWORD GetAvailableTextureMemory();
static const D3DXMATRIX& GetViewMatrix();
static const D3DXMATRIX & GetIdentityMatrix();
enum
{
DEFAULT_IB_LINE,
DEFAULT_IB_LINE_TRI,
DEFAULT_IB_LINE_RECT,
DEFAULT_IB_LINE_CUBE,
DEFAULT_IB_FILL_TRI,
DEFAULT_IB_FILL_RECT,
DEFAULT_IB_FILL_CUBE,
DEFAULT_IB_NUM,
};
public:
CGraphicBase();
virtual ~CGraphicBase();
void SetSimpleCamera(float x, float y, float z, float pitch, float roll);
void SetEyeCamera(float xEye, float yEye, float zEye, float xCenter, float yCenter, float zCenter, float xUp, float yUp, float zUp);
void SetAroundCamera(float distance, float pitch, float roll, float lookAtZ = 0.0f);
void SetPositionCamera(float fx, float fy, float fz, float fDistance, float fPitch, float fRotation);
void MoveCamera(float fdeltax, float fdeltay, float fdeltaz);
void GetTargetPosition(float * px, float * py, float * pz);
void GetCameraPosition(float * px, float * py, float * pz);
void SetOrtho2D(float hres, float vres, float zres);
void SetOrtho3D(float hres, float vres, float zmin, float zmax);
void SetPerspective(float fov, float aspect, float nearz, float farz);
float GetFOV();
void GetClipPlane(float * fNearY, float * fFarY)
{
*fNearY = ms_fNearY;
*fFarY = ms_fFarY;
}
////////////////////////////////////////////////////////////////////////
void PushMatrix();
void MultMatrix( const D3DXMATRIX* pMat );
void MultMatrixLocal( const D3DXMATRIX* pMat );
void Translate(float x, float y, float z);
void Rotate(float degree, float x, float y, float z);
void RotateLocal(float degree, float x, float y, float z);
void RotateYawPitchRollLocal(float fYaw, float fPitch, float fRoll);
void Scale(float x, float y, float z);
void PopMatrix();
void LoadMatrix(const D3DXMATRIX & c_rSrcMatrix);
void GetMatrix(D3DXMATRIX * pRetMatrix) const;
const D3DXMATRIX * GetMatrixPointer() const;
// Special Routine
void GetSphereMatrix(D3DXMATRIX * pMatrix, float fValue = 0.1f);
////////////////////////////////////////////////////////////////////////
void InitScreenEffect();
void SetScreenEffectWaving(float fDuringTime, int iPower);
void SetScreenEffectFlashing(float fDuringTime, const D3DXCOLOR & c_rColor);
////////////////////////////////////////////////////////////////////////
DWORD GetColor(float r, float g, float b, float a = 1.0f);
DWORD GetFaceCount();
void ResetFaceCount();
HRESULT GetLastResult();
void UpdateProjMatrix();
void UpdateViewMatrix();
void SetViewport(DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight, float fMinZ, float fMaxZ);
static void GetBackBufferSize(UINT* puWidth, UINT* puHeight);
static void SetBackBufferSize(UINT uWidth, UINT uHeight);
static bool IsTLVertexClipping();
static bool IsFastTNL();
static bool IsLowTextureMemory();
static bool IsHighTextureMemory();
static void SetDefaultIndexBuffer(UINT eDefIB);
static bool SetPDTStream(SPDTVertexRaw* pVertices, UINT uVtxCount);
static bool SetPDTStream(SPDTVertex* pVertices, UINT uVtxCount);
protected:
static D3DXMATRIX ms_matIdentity;
static D3DXMATRIX ms_matView;
static D3DXMATRIX ms_matProj;
static D3DXMATRIX ms_matInverseView;
static D3DXMATRIX ms_matInverseViewYAxis;
static D3DXMATRIX ms_matWorld;
static D3DXMATRIX ms_matWorldView;
protected:
//void UpdatePrePipeLineMatrix();
void UpdatePipeLineMatrix();
protected:
// 각종 D3DX Mesh 들 (컬루젼 데이터 등을 표시활 때 쓴다)
static LPD3DXMESH ms_lpSphereMesh;
static LPD3DXMESH ms_lpCylinderMesh;
protected:
static HRESULT ms_hLastResult;
static int ms_iWidth;
static int ms_iHeight;
static UINT ms_iD3DAdapterInfo;
static UINT ms_iD3DDevInfo;
static UINT ms_iD3DModeInfo;
static D3D_CDisplayModeAutoDetector ms_kD3DDetector;
static HWND ms_hWnd;
static HDC ms_hDC;
static LPDIRECT3D8 ms_lpd3d;
static LPDIRECT3DDEVICE8 ms_lpd3dDevice;
static ID3DXMatrixStack* ms_lpd3dMatStack;
static D3DVIEWPORT8 ms_Viewport;
static DWORD ms_faceCount;
static D3DCAPS8 ms_d3dCaps;
static D3DPRESENT_PARAMETERS ms_d3dPresentParameter;
static DWORD ms_dwD3DBehavior;
static DWORD ms_ptVS;
static DWORD ms_pntVS;
static DWORD ms_pnt2VS;
static D3DXMATRIX ms_matScreen0;
static D3DXMATRIX ms_matScreen1;
static D3DXMATRIX ms_matScreen2;
//static D3DXMATRIX ms_matPrePipeLine;
static D3DXVECTOR3 ms_vtPickRayOrig;
static D3DXVECTOR3 ms_vtPickRayDir;
static float ms_fFieldOfView;
static float ms_fAspect;
static float ms_fNearY;
static float ms_fFarY;
// 2004.11.18.myevan.DynamicVertexBuffer로 교체
/*
static std::vector<TIndex> ms_lineIdxVector;
static std::vector<TIndex> ms_lineTriIdxVector;
static std::vector<TIndex> ms_lineRectIdxVector;
static std::vector<TIndex> ms_lineCubeIdxVector;
static std::vector<TIndex> ms_fillTriIdxVector;
static std::vector<TIndex> ms_fillRectIdxVector;
static std::vector<TIndex> ms_fillCubeIdxVector;
*/
// Screen Effect - Waving, Flashing and so on..
static DWORD ms_dwWavingEndTime;
static int ms_iWavingPower;
static DWORD ms_dwFlashingEndTime;
static D3DXCOLOR ms_FlashingColor;
// Terrain picking용 Ray... CCamera 이용하는 버전.. 기존의 Ray와 통합 필요...
static CRay ms_Ray;
//
static bool ms_bSupportDXT;
static bool ms_isLowTextureMemory;
static bool ms_isHighTextureMemory;
enum
{
PDT_VERTEX_NUM = 16,
PDT_VERTEXBUFFER_NUM = 100,
};
static LPDIRECT3DVERTEXBUFFER8 ms_alpd3dPDTVB[PDT_VERTEXBUFFER_NUM];
static LPDIRECT3DINDEXBUFFER8 ms_alpd3dDefIB[DEFAULT_IB_NUM];
};
+240
View File
@@ -0,0 +1,240 @@
#include "StdAfx.h"
#include "GrpCollisionObject.h"
bool CGraphicCollisionObject::IntersectBoundBox(const D3DXMATRIX* c_pmatWorld, const TBoundBox& c_rboundBox, float* pu, float* pv, float* pt)
{
return IntersectCube(c_pmatWorld, c_rboundBox.sx, c_rboundBox.sy, c_rboundBox.sz, c_rboundBox.ex, c_rboundBox.ey, c_rboundBox.ez, ms_vtPickRayOrig, ms_vtPickRayDir, pu, pv, pt);
}
bool CGraphicCollisionObject::IntersectCube(const D3DXMATRIX* c_pmatWorld, float sx, float sy, float sz, float ex, float ey, float ez,
D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt)
{
TPosition posVertices[8];
posVertices[0] = TPosition(sx, sy, sz);
posVertices[1] = TPosition(ex, sy, sz);
posVertices[2] = TPosition(sx, ey, sz);
posVertices[3] = TPosition(ex, ey, sz);
posVertices[4] = TPosition(sx, sy, ez);
posVertices[5] = TPosition(ex, sy, ez);
posVertices[6] = TPosition(sx, ey, ez);
posVertices[7] = TPosition(ex, ey, ez);
static const WORD c_awFillCubeIndices[36] = {
0, 1, 2, 1, 3, 2,
2, 0, 6, 0, 4, 6,
0, 1, 4, 1, 5, 4,
1, 3, 5, 3, 7, 5,
3, 2, 7, 2, 6, 7,
4, 5, 6, 5, 7, 6,
};
return IntersectIndexedMesh(
c_pmatWorld,
posVertices,
sizeof(TPosition),
8,
c_awFillCubeIndices,
36,
RayOriginal,
RayDirection,
pu,
pv,
pt
);
}
const int c_iLimitVertexCount = 1024;
bool CGraphicCollisionObject::IntersectIndexedMesh(const D3DXMATRIX* c_pmatWorld, const void* vertices, int step, int vtxCount, const void* indices, int idxCount,
D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt)
{
static D3DXVECTOR3 s_v3PositionArray[c_iLimitVertexCount];
static DWORD s_dwPositionCount;
if (vtxCount > c_iLimitVertexCount)
{
Tracef("The vertex count of mesh which is worked collision detection is too much : %d / %d", vtxCount, c_iLimitVertexCount);
return false;
}
s_dwPositionCount = 0;
char* pcurVtx = (char*)vertices;
while (vtxCount--)
{
float* pos = (float*)pcurVtx;
D3DXVec3TransformCoord(&s_v3PositionArray[s_dwPositionCount++], (D3DXVECTOR3*)pos, c_pmatWorld);
pcurVtx += step;
}
WORD* pcurIdx = (WORD*)indices;
int triCount = idxCount / 3;
while (triCount--)
{
if (IntersectTriangle(RayOriginal, RayDirection,
s_v3PositionArray[pcurIdx[0]],
s_v3PositionArray[pcurIdx[1]],
s_v3PositionArray[pcurIdx[2]],
pu, pv, pt))
{
return true;
}
pcurIdx += 3;
}
return false;
}
bool CGraphicCollisionObject::IntersectMesh(const D3DXMATRIX * c_pmatWorld, const void * vertices, DWORD dwStep, DWORD dwvtxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt)
{
char * pcurVtx = (char *) vertices;
D3DXVECTOR3 v3Vertex[3];
for (DWORD i = 0; i < dwvtxCount; i += 3)
{
D3DXVec3TransformCoord(&v3Vertex[0], (D3DXVECTOR3*)pcurVtx, c_pmatWorld);
pcurVtx += dwStep;
D3DXVec3TransformCoord(&v3Vertex[1], (D3DXVECTOR3*)pcurVtx, c_pmatWorld);
pcurVtx += dwStep;
D3DXVec3TransformCoord(&v3Vertex[2], (D3DXVECTOR3*)pcurVtx, c_pmatWorld);
pcurVtx += dwStep;
if (IntersectTriangle(RayOriginal, RayDirection,
v3Vertex[0], v3Vertex[1], v3Vertex[2],
pu, pv, pt))
{
return true;
}
}
return false;
}
bool CGraphicCollisionObject::IntersectTriangle(const D3DXVECTOR3& c_orig,
const D3DXVECTOR3& c_dir,
const D3DXVECTOR3& c_v0,
const D3DXVECTOR3& c_v1,
const D3DXVECTOR3& c_v2,
float * pu,
float * pv,
float * pt)
{
D3DXVECTOR3 edge1 = c_v1 - c_v0;
D3DXVECTOR3 edge2 = c_v2 - c_v0;
D3DXVECTOR3 pvec;
D3DXVec3Cross(&pvec, &c_dir, &edge2);
FLOAT det = D3DXVec3Dot(&edge1, &pvec);
D3DXVECTOR3 tvec;
if (det > 0)
{
tvec = c_orig - c_v0;
}
else
{
tvec = c_v0 - c_orig;
det = -det;
}
if (det < 0.0001f)
return false;
float u, v, t;
u = D3DXVec3Dot(&tvec, &pvec);
if (u < 0.0f || u > det)
return false;
D3DXVECTOR3 qvec;
D3DXVec3Cross(&qvec, &tvec, &edge1);
v = D3DXVec3Dot(&c_dir, &qvec);
if (v < 0.0f || u + v > det)
return false;
t = D3DXVec3Dot(&edge2, &qvec);
FLOAT fInvDet = 1.0f / det;
t *= fInvDet;
u *= fInvDet;
v *= fInvDet;
D3DXVECTOR3 spot = edge1 * u + edge2 * v;
spot += c_v0;
*pu = spot.x;
*pv = spot.y;
*pt = t;
return true;
}
bool CGraphicCollisionObject::IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection)
{
D3DXVECTOR3 v3RayOriginal = c_rv3RayOriginal - c_rv3Position;
float a = D3DXVec3Dot(&c_rv3RayDirection, &c_rv3RayDirection);
float b = 2 * D3DXVec3Dot(&v3RayOriginal, &c_rv3RayDirection);
float c = D3DXVec3Dot(&v3RayOriginal, &v3RayOriginal) - fRadius * fRadius;
float D = b * b - 4 * a * c;
if (D >= 0)
return true;
return false;
}
bool CGraphicCollisionObject::IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection)
{
D3DXVECTOR3 v3RayOriginal = c_rv3RayOriginal - c_rv3Position;
float a = c_rv3RayDirection.x * c_rv3RayDirection.x + c_rv3RayDirection.y * c_rv3RayDirection.y;
float b = 2 * (v3RayOriginal.x * c_rv3RayDirection.x + v3RayOriginal.y * c_rv3RayDirection.y);
float c = v3RayOriginal.x * v3RayOriginal.x + v3RayOriginal.y * v3RayOriginal.y - fRadius*fRadius;
float D = b * b - 4 * a * c;
if (D > 0)
if (0.0f != a)
{
float tPlus = (-b + sqrtf(D)) / (2 * a);
float tMinus = (-b - sqrtf(D)) / (2 * a);
float fzPlus = v3RayOriginal.z + tPlus * c_rv3RayDirection.z;
float fzMinus = v3RayOriginal.z + tMinus * c_rv3RayDirection.z;
if (fzPlus > 0.0f && fzPlus <= fHeight)
return true;
if (fzMinus > 0.0f && fzMinus <= fHeight)
return true;
if (fzMinus * fzPlus < 0.0f)
return true;
}
return false;
}
bool CGraphicCollisionObject::IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius)
{
return CGraphicCollisionObject::IntersectSphere(c_rv3Position, fRadius, ms_vtPickRayOrig, ms_vtPickRayDir);
}
bool CGraphicCollisionObject::IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight)
{
return CGraphicCollisionObject::IntersectCylinder(c_rv3Position, fRadius, fHeight, ms_vtPickRayOrig, ms_vtPickRayDir);
}
CGraphicCollisionObject::CGraphicCollisionObject()
{
}
CGraphicCollisionObject::~CGraphicCollisionObject()
{
}
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include "GrpBase.h"
class CGraphicCollisionObject : public CGraphicBase
{
public:
CGraphicCollisionObject();
virtual ~CGraphicCollisionObject();
protected:
bool IntersectTriangle(const D3DXVECTOR3& c_orig, const D3DXVECTOR3& c_dir, const D3DXVECTOR3& c_v0, const D3DXVECTOR3& c_v1, const D3DXVECTOR3& c_v2, float* pu, float* pv, float* pt);
bool IntersectBoundBox(const D3DXMATRIX* c_pmatWorld, const TBoundBox& c_rboundBox, float* pu, float* pv, float* pt);
bool IntersectCube(const D3DXMATRIX* c_pmatWorld, float sx, float sy, float sz, float ex, float ey, float ez, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt);
bool IntersectIndexedMesh(const D3DXMATRIX* c_pmatWorld, const void* vertices, int step, int vtxCount, const void* indices, int idxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt);
bool IntersectMesh(const D3DXMATRIX * c_pmatWorld, const void * vertices, DWORD dwStep, DWORD dwvtxCount, D3DXVECTOR3 & RayOriginal, D3DXVECTOR3 & RayDirection, float* pu, float* pv, float* pt);
bool IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection);
bool IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight, const D3DXVECTOR3 & c_rv3RayOriginal, const D3DXVECTOR3 & c_rv3RayDirection);
// NOTE : ms_vtPickRayOrig와 ms_vtPickRayDir를 CGraphicBGase가 가지고 있는데
// 굳이 인자로 넣어줘야 하는 이유가 있는가? Customize를 위해서? - [levites]
bool IntersectSphere(const D3DXVECTOR3 & c_rv3Position, float fRadius);
bool IntersectCylinder(const D3DXVECTOR3 & c_rv3Position, float fRadius, float fHeight);
};
+28
View File
@@ -0,0 +1,28 @@
#pragma once
class CGraphicColor
{
public:
CGraphicColor(const CGraphicColor& c_rSrcColor);
CGraphicColor(float r, float g, float b, float a);
CGraphicColor(DWORD color);
CGraphicColor();
~CGraphicColor();
void Clear();
void Set(float r, float g, float b, float a);
void Set(const CGraphicColor& c_rSrcColor);
void Set(DWORD color);
void Blend(float p, const CGraphicColor& c_rSrcColor, const CGraphicColor& c_rDstColor);
DWORD GetPackValue() const;
protected:
float m_r;
float m_g;
float m_b;
float m_a;
};
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include "GrpColor.h"
#include "Pool.h"
class CGraphicColorInstance
{
public:
CGraphicColorInstance();
virtual ~CGraphicColorInstance();
void Clear();
void SetColorReference(const CGraphicColor& c_rSrcColor);
void BlendColorReference(DWORD blendTime, const CGraphicColor& c_rDstColor);
void Update();
const CGraphicColor& GetCurrentColorReference() const;
protected:
DWORD GetCurrentTime();
protected:
CGraphicColor m_srcColor;
CGraphicColor m_dstColor;
CGraphicColor m_curColor;
DWORD m_baseTime;
DWORD m_blendTime;
};
typedef CDynamicPool<CGraphicColorInstance> TGraphicColorInstancePool;
+35
View File
@@ -0,0 +1,35 @@
#pragma once
class CGraphicDib
{
public:
CGraphicDib();
virtual ~CGraphicDib();
void Destroy();
bool Create(HDC hDC, int width, int height);
void SetBkMode(int iBkMode);
void TextOut(int ix, int iy, const char * c_szText);
void Put(HDC hDC, int x, int y);
int GetWidth();
int GetHeight();
void* GetPointer();
HDC GetDCHandle();
protected:
void Initialize();
protected:
HDC m_hDC;
HBITMAP m_hBmp;
BITMAPINFO m_bmi;
int m_width;
int m_height;
void * m_pvBuf;
};
+166
View File
@@ -0,0 +1,166 @@
#pragma once
#include <d3d8.h>
#include <string>
typedef BOOL (*PFNCONFIRMDEVICE) (D3DCAPS8& rkD3DCaps, UINT uBehavior, D3DFORMAT eD3DFmt);
enum
{
D3DDEVICETYPE_HAL,
D3DDEVICETYPE_REF,
D3DDEVICETYPE_NUM,
};
struct D3D_SModeInfo
{
UINT m_uScrWidth;
UINT m_uScrHeight;
UINT m_uScrDepthBit;
UINT m_dwD3DBehavior;
D3DFORMAT m_eD3DFmtPixel;
D3DFORMAT m_eD3DFmtDepthStencil;
VOID GetString(std::string* pstEnumList);
};
class D3D_CAdapterDisplayModeList
{
public:
D3D_CAdapterDisplayModeList() {}
~D3D_CAdapterDisplayModeList() {}
VOID Build(IDirect3D8& rkD3D, D3DFORMAT eD3DFmtDefault, UINT iAdapter);
UINT GetDisplayModeNum();
UINT GetPixelFormatNum();
const D3DDISPLAYMODE& GetDisplayModer(UINT iD3DDM);
const D3DFORMAT& GetPixelFormatr(UINT iD3DFmt);
protected:
enum
{
D3DDISPLAYMODE_MAX = 100,
D3DFORMAT_MAX = 20,
FILTEROUT_LOWRESOLUTION_WIDTH = 640,
FILTEROUT_LOWRESOLUTION_HEIGHT = 480,
};
protected:
D3DDISPLAYMODE m_akD3DDM[D3DDISPLAYMODE_MAX];
D3DFORMAT m_aeD3DFmt[D3DFORMAT_MAX];
UINT m_uD3DDMNum;
UINT m_uD3DFmtNum;
};
class D3D_CDeviceInfo
{
public:
D3D_CDeviceInfo() {}
~D3D_CDeviceInfo() {}
BOOL Build(IDirect3D8& rkD3D, UINT iAdapter, UINT iDevType, D3D_CAdapterDisplayModeList& rkD3DADMList, PFNCONFIRMDEVICE pfnConfirmDevice);
BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo);
UINT GetD3DModeInfoNum();
VOID GetString(std::string* pstEnumList);
BOOL FindDepthStencilFormat(IDirect3D8& rkD3D, UINT iAdapter, D3DDEVTYPE DeviceType, D3DFORMAT TargetFormat, D3DFORMAT* pDepthStencilFormat);
D3D_SModeInfo& GetD3DModeInfor(UINT iD3DModeInfo);
D3D_SModeInfo* GetD3DModeInfop(UINT iD3DModeInfo);
protected:
enum
{
D3DMODEINFO_NUM = 150,
};
protected:
const TCHAR* m_szDevDesc;
D3DDEVTYPE m_eD3DDevType;
D3DCAPS8 m_kD3DCaps;
BOOL m_canDoWindowed;
UINT m_iCurD3DModeInfo;
UINT m_uD3DModeInfoNum;
D3D_SModeInfo m_akD3DModeInfo[D3DMODEINFO_NUM];
BOOL m_isWindowed;
D3DMULTISAMPLE_TYPE m_eD3DMSTWindowed;
D3DMULTISAMPLE_TYPE m_eD3DMSTFullscreen;
protected:
static const CHAR* msc_aszD3DDevDesc[D3DDEVICETYPE_NUM];
static const D3DDEVTYPE msc_aeD3DDevType[D3DDEVICETYPE_NUM];
};
class D3D_CAdapterInfo
{
public:
D3D_CAdapterInfo() {}
~D3D_CAdapterInfo() {}
BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo);
BOOL Build(IDirect3D8& rkD3D, UINT iAdapter, PFNCONFIRMDEVICE pfnConfirmDevice);
VOID GetString(std::string* pstEnumList);
D3DADAPTER_IDENTIFIER8& GetIdentifier()
{
return m_kD3DAdapterIdentifier;
}
D3DDISPLAYMODE& GetDesktopD3DDisplayModer();
D3DDISPLAYMODE* GetDesktopD3DDisplayModep();
D3D_CDeviceInfo* GetD3DDeviceInfop(UINT iD3DDevInfo);
D3D_SModeInfo* GetD3DModeInfop(UINT iD3DDevInfo, UINT iD3DModeInfo);
protected:
enum
{
D3DDEVICEINFO_NUM = 5,
};
protected:
D3DADAPTER_IDENTIFIER8 m_kD3DAdapterIdentifier;
D3DDISPLAYMODE m_kD3DDMDesktop;
UINT m_iCurD3DDevInfo;
UINT m_uD3DDevInfoNum;
D3D_CDeviceInfo m_akD3DDevInfo[D3DDEVICEINFO_NUM];
};
class D3D_CDisplayModeAutoDetector
{
public:
D3D_CDisplayModeAutoDetector();
~D3D_CDisplayModeAutoDetector();
BOOL Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo, UINT* piD3DAdapterInfo);
BOOL Build(IDirect3D8& rkD3D, PFNCONFIRMDEVICE pfnConfirmDevice);
D3D_CAdapterInfo* GetD3DAdapterInfop(UINT iD3DAdapterInfo);
D3D_SModeInfo* GetD3DModeInfop(UINT iD3DAdapterInfo, UINT iD3DDevInfo, UINT iD3DModeInfo);
VOID GetString(std::string* pstEnumList);
protected:
enum
{
D3DADAPTERINFO_NUM = 10,
};
protected:
D3D_CAdapterInfo m_akD3DAdapterInfo[D3DADAPTERINFO_NUM];
UINT m_uD3DAdapterInfoCount;
};
+74
View File
@@ -0,0 +1,74 @@
#pragma once
#include "GrpBase.h"
#include "GrpDetector.h"
#include "StateManager.h"
class CGraphicDevice : public CGraphicBase
{
public:
enum EDeviceState
{
DEVICESTATE_OK,
DEVICESTATE_BROKEN,
DEVICESTATE_NEEDS_RESET,
DEVICESTATE_NULL
};
enum ECreateReturnValues
{
CREATE_OK = (1 << 0),
CREATE_NO_DIRECTX = (1 << 1),
CREATE_GET_DEVICE_CAPS = (1 << 2),
CREATE_GET_DEVICE_CAPS2 = (1 << 3),
CREATE_DEVICE = (1 << 4),
CREATE_REFRESHRATE = (1 << 5),
CREATE_ENUM = (1 << 6), // 2003. 01. 09. myevan 모드 리스트 얻기 실패
CREATE_DETECT = (1 << 7), // 2003. 01. 09. myevan 모드 선택 실패
CREATE_NO_TNL = (1 << 8),
CREATE_BAD_DRIVER = (1 << 9),
CREATE_FORMAT = (1 << 10),
};
CGraphicDevice();
virtual ~CGraphicDevice();
void InitBackBufferCount(UINT uBackBufferCount);
void Destroy();
int Create(HWND hWnd, int hres, int vres, bool Windowed = true, int bit = 32, int ReflashRate = 0);
EDeviceState GetDeviceState();
bool Reset();
void EnableWebBrowserMode(const RECT& c_rcWebPage);
void DisableWebBrowserMode();
void MoveWebBrowserRect(const RECT& c_rcWebPage);
bool ResizeBackBuffer(UINT uWidth, UINT uHeight);
void RegisterWarningString(UINT uiMsg, const char * c_szString);
protected:
void __Initialize();
bool __IsInDriverBlackList(D3D_CAdapterInfo& rkD3DAdapterInfo);
void __WarningMessage(HWND hWnd, UINT uiMsg);
void __InitializeDefaultIndexBufferList();
void __DestroyDefaultIndexBufferList();
bool __CreateDefaultIndexBufferList();
bool __CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices);
void __InitializePDTVertexBufferList();
void __DestroyPDTVertexBufferList();
bool __CreatePDTVertexBufferList();
DWORD CreatePTStreamVertexShader();
DWORD CreatePNTStreamVertexShader();
DWORD CreatePNT2StreamVertexShader();
DWORD CreateDoublePNTStreamVertexShader();
protected:
DWORD m_uBackBufferCount;
std::map<UINT, std::string> m_kMap_strWarningMessage;
CStateManager* m_pStateManager;
};
@@ -0,0 +1,61 @@
#pragma once
#include "GrpImageInstance.h"
class CGraphicExpandedImageInstance : public CGraphicImageInstance
{
public:
static DWORD Type();
static void DeleteExpandedImageInstance(CGraphicExpandedImageInstance * pkInstance)
{
pkInstance->Destroy();
ms_kPool.Free(pkInstance);
}
enum ERenderingMode
{
RENDERING_MODE_NORMAL,
RENDERING_MODE_SCREEN,
RENDERING_MODE_COLOR_DODGE,
RENDERING_MODE_MODULATE,
};
public:
CGraphicExpandedImageInstance();
virtual ~CGraphicExpandedImageInstance();
void Destroy();
void SetDepth(float fDepth);
void SetOrigin();
void SetOrigin(float fx, float fy);
void SetRotation(float fRotation);
void SetScale(float fx, float fy);
void SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom);
void SetRenderingMode(int iMode);
protected:
void Initialize();
void OnRender();
void OnSetImagePointer();
BOOL OnIsType(DWORD dwType);
protected:
float m_fDepth;
D3DXVECTOR2 m_v2Origin;
D3DXVECTOR2 m_v2Scale;
float m_fRotation;
RECT m_RenderingRect;
int m_iRenderingMode;
public:
static void CreateSystem(UINT uCapacity);
static void DestroySystem();
static CGraphicExpandedImageInstance* New();
static void Delete(CGraphicExpandedImageInstance* pkImgInst);
static CDynamicPool<CGraphicExpandedImageInstance> ms_kPool;
};
+81
View File
@@ -0,0 +1,81 @@
#pragma once
#include "GrpTexture.h"
#include "GrpImageTexture.h"
#include "GrpDIB.h"
#include <vector>
#include <map>
class CGraphicFontTexture : public CGraphicTexture
{
public:
typedef std::pair<WORD,wchar_t> TCharacterKey;
typedef struct SCharacterInfomation
{
short index;
short width;
short height;
float left;
float top;
float right;
float bottom;
float advance;
} TCharacterInfomation;
typedef std::vector<TCharacterInfomation*> TPCharacterInfomationVector;
public:
CGraphicFontTexture();
virtual ~CGraphicFontTexture();
void Destroy();
bool Create(const char* c_szFontName, int fontSize, bool bItalic);
bool CreateDeviceObjects();
void DestroyDeviceObjects();
bool CheckTextureIndex(DWORD dwTexture);
void SelectTexture(DWORD dwTexture);
bool UpdateTexture();
TCharacterInfomation* GetCharacterInfomation(WORD codePage, wchar_t keyValue);
TCharacterInfomation* UpdateCharacterInfomation(TCharacterKey code);
bool IsEmpty() const;
protected:
void Initialize();
bool AppendTexture();
HFONT GetFont(WORD codePage);
protected:
typedef std::vector<CGraphicImageTexture*> TGraphicImageTexturePointerVector;
typedef std::map<TCharacterKey, TCharacterInfomation> TCharacterInfomationMap;
typedef std::map<WORD, HFONT> TFontMap;
protected:
CGraphicDib m_dib;
HFONT m_hFontOld;
HFONT m_hFont;
TGraphicImageTexturePointerVector m_pFontTextureVector;
TCharacterInfomationMap m_charInfoMap;
TFontMap m_fontMap;
int m_x;
int m_y;
int m_step;
bool m_isDirty;
TCHAR m_fontName[LF_FACESIZE];
LONG m_fontSize;
bool m_bItalic;
};
+44
View File
@@ -0,0 +1,44 @@
#ifndef __INC_GRPIMAGE_H__
#define __INC_GRPIMAGE_H__
#include "Ref.h"
#include "Resource.h"
#include "GrpImageTexture.h"
class CGraphicImage : public CResource
{
public:
typedef CRef<CGraphicImage> TRef;
public:
static TType Type();
public:
CGraphicImage(const char* c_szFileName, DWORD dwFilter = D3DX_FILTER_LINEAR);
virtual ~CGraphicImage();
virtual bool CreateDeviceObjects();
virtual void DestroyDeviceObjects();
int GetWidth() const;
int GetHeight() const;
const RECT & GetRectReference() const;
const CGraphicTexture & GetTextureReference() const;
CGraphicTexture * GetTexturePointer();
protected:
bool OnLoad(int iSize, const void * c_pvBuf);
void OnClear();
bool OnIsEmpty() const;
bool OnIsType(TType type);
protected:
CGraphicImageTexture m_imageTexture;
RECT m_rect;
DWORD m_dwFilter;
};
#endif
+60
View File
@@ -0,0 +1,60 @@
#pragma once
#include "GrpImage.h"
#include "GrpIndexBuffer.h"
#include "GrpVertexBufferDynamic.h"
#include "Pool.h"
class CGraphicImageInstance
{
public:
static DWORD Type();
BOOL IsType(DWORD dwType);
public:
CGraphicImageInstance();
virtual ~CGraphicImageInstance();
void Destroy();
void Render();
void SetDiffuseColor(float fr, float fg, float fb, float fa);
void SetPosition(float fx, float fy);
void SetImagePointer(CGraphicImage* pImage);
void ReloadImagePointer(CGraphicImage* pImage);
bool IsEmpty() const;
int GetWidth();
int GetHeight();
CGraphicTexture * GetTexturePointer();
const CGraphicTexture & GetTextureReference() const;
CGraphicImage * GetGraphicImagePointer();
bool operator == (const CGraphicImageInstance & rhs) const;
protected:
void Initialize();
virtual void OnRender();
virtual void OnSetImagePointer();
virtual BOOL OnIsType(DWORD dwType);
protected:
D3DXCOLOR m_DiffuseColor;
D3DXVECTOR2 m_v2Position;
CGraphicImage::TRef m_roImage;
public:
static void CreateSystem(UINT uCapacity);
static void DestroySystem();
static CGraphicImageInstance* New();
static void Delete(CGraphicImageInstance* pkImgInst);
static CDynamicPool<CGraphicImageInstance> ms_kPool;
};
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include "GrpTexture.h"
#include "../EterImageLib/DXTCImage.h"
class CGraphicImageTexture : public CGraphicTexture
{
public:
CGraphicImageTexture();
virtual ~CGraphicImageTexture();
void Destroy();
bool Create(UINT width, UINT height, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR);
bool CreateDeviceObjects();
void CreateFromTexturePointer(const CGraphicTexture* c_pSrcTexture);
bool CreateFromDiskFile(const char* c_szFileName, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR);
bool CreateFromMemoryFile(UINT bufSize, const void* c_pvBuf, D3DFORMAT d3dFmt, DWORD dwFilter = D3DX_FILTER_LINEAR);
bool CreateDDSTexture(CDXTCImage & image, const BYTE * c_pbBuf);
void SetFileName(const char * c_szFileName);
bool Lock(int* pRetPitch, void** ppRetPixels, int level=0);
void Unlock(int level=0);
protected:
void Initialize();
D3DFORMAT m_d3dFmt;
DWORD m_dwFilter;
std::string m_stFileName;
};
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include "GrpBase.h"
class CGraphicIndexBuffer : public CGraphicBase
{
public:
CGraphicIndexBuffer();
virtual ~CGraphicIndexBuffer();
void Destroy();
bool Create(int idxCount, D3DFORMAT d3dFmt);
bool Create(int faceCount, TFace* faces);
bool CreateDeviceObjects();
void DestroyDeviceObjects();
bool Copy(int bufSize, const void* srcIndices);
bool Lock(void** pretIndices) const;
void Unlock() const;
bool Lock(void** pretIndices);
void Unlock();
void SetIndices(int startIndex=0) const;
LPDIRECT3DINDEXBUFFER8 GetD3DIndexBuffer() const;
int GetIndexCount() const {return m_iidxCount;}
protected:
void Initialize();
protected:
LPDIRECT3DINDEXBUFFER8 m_lpd3dIdxBuf;
DWORD m_dwBufferSize;
D3DFORMAT m_d3dFmt;
int m_iidxCount;
};
+345
View File
@@ -0,0 +1,345 @@
#include "StdAfx.h"
#include <algorithm>
#include "../EterBase/Timer.h"
#include "GrpLightManager.h"
#include "StateManager.h"
float CLightBase::ms_fCurTime = 0.0f;
CLightManager::CLightManager()
{
m_v3CenterPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_dwLimitLightCount = LIGHT_LIMIT_DEFAULT;
}
CLightManager::~CLightManager()
{
}
void CLightManager::Destroy()
{
m_LightPool.Destroy();
}
void CLightManager::Initialize()
{
SetSkipIndex(1);
m_NonUsingLightIDDeque.clear();
m_LightMap.clear();
m_LightPool.FreeAll();
}
void CLightManager::RegisterLight(ELightType /*LightType*/, TLightID * poutLightID, D3DLIGHT8 & LightData)
{
CLight * pLight = m_LightPool.Alloc();
TLightID ID = NewLightID();
pLight->SetParameter(ID, LightData);
m_LightMap[ID] = pLight;
*poutLightID = ID;
}
void CLightManager::DeleteLight(TLightID LightID)
{
TLightMap::iterator itor = m_LightMap.find(LightID);
if (m_LightMap.end() == itor)
{
assert(!"CLightManager::DeleteLight - Failed to find light ID!");
return;
}
CLight * pLight = itor->second;
pLight->Clear();
m_LightPool.Free(pLight);
m_LightMap.erase(itor);
ReleaseLightID(LightID);
}
CLight * CLightManager::GetLight(TLightID LightID)
{
TLightMap::iterator itor = m_LightMap.find(LightID);
if (m_LightMap.end() == itor)
{
assert(!"CLightManager::SetLightData - Failed to find light ID!");
return NULL;
}
return itor->second;
}
void CLightManager::SetCenterPosition(const D3DXVECTOR3 & c_rv3Position)
{
m_v3CenterPosition = c_rv3Position;
}
void CLightManager::SetLimitLightCount(DWORD dwLightCount)
{
m_dwLimitLightCount = dwLightCount;
}
void CLightManager::SetSkipIndex(DWORD dwSkipIndex)
{
m_dwSkipIndex = dwSkipIndex;
}
struct LightComp
{
bool operator () (const CLight * l, const CLight * r) const
{
return l->GetDistance() < r->GetDistance();
}
};
// NOTE : FlushLight후 렌더링
// 그 후 반드시 RestoreLight를 해줘야만 한다.
void CLightManager::FlushLight()
{
Update();
m_LightSortVector.clear();
// NOTE: Dynamic과 Static을 분리 시키고 CenterPosition이 바뀔때마다 Static만
// 다시 Flush 하는 식으로 최적화 할 수 있다. - [levites]
// light들의 거리를 추출해 정렬한다.
TLightMap::iterator itor = m_LightMap.begin();
for (; itor != m_LightMap.end(); ++itor)
{
CLight * pLight = itor->second;
D3DXVECTOR3 v3LightPos(pLight->GetPosition());
D3DXVECTOR3 v3Distance(v3LightPos - m_v3CenterPosition);
pLight->SetDistance(D3DXVec3Length(&v3Distance));
m_LightSortVector.push_back(pLight);
}
// quick sort lights
std::sort(m_LightSortVector.begin(), m_LightSortVector.end(), LightComp());
// NOTE - 거리로 정렬된 라이트를 Limit 갯수 만큼 제한해서 켜준다.
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE);
for (DWORD k = 0; k < min(m_dwLimitLightCount, m_LightSortVector.size()); ++k)
{
m_LightSortVector[k]->Update();
m_LightSortVector[k]->SetDeviceLight(TRUE);
}
}
void CLightManager::RestoreLight()
{
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
for (DWORD k = 0; k < min(m_dwLimitLightCount, m_LightSortVector.size()); ++k)
m_LightSortVector[k]->SetDeviceLight(FALSE);
}
TLightID CLightManager::NewLightID()
{
if (!m_NonUsingLightIDDeque.empty())
{
TLightID id = m_NonUsingLightIDDeque.back();
m_NonUsingLightIDDeque.pop_back();
return (id);
}
return m_dwSkipIndex + m_LightMap.size();
}
void CLightManager::ReleaseLightID(TLightID LightID)
{
m_NonUsingLightIDDeque.push_back(LightID);
}
void CLightManager::Update()
{
//static DWORD s_dwStartTime = ELTimer_GetMSec();
//ms_fCurTime = float(ELTimer_GetMSec() - s_dwStartTime) / 1000.0f;
ms_fCurTime = CTimer::Instance().GetCurrentSecond();
}
//////////////////////////////////////////////////////////////////////////
CLight::CLight()
{
Initialize();
}
CLight::~CLight()
{
Clear();
}
void CLight::Initialize()
{
m_LightID = 0;
m_isEdited = TRUE;
m_fDistance = 0.0f;
memset(&m_d3dLight, 0, sizeof(m_d3dLight));
m_d3dLight.Type = D3DLIGHT_POINT;
m_d3dLight.Attenuation0 = 0.0f;
m_d3dLight.Attenuation1 = 1.0f;
m_d3dLight.Attenuation2 = 0.0f;
}
void CLight::Clear()
{
if (m_LightID)
SetDeviceLight(FALSE);
Initialize();
}
void CLight::SetDeviceLight(BOOL bActive)
{
if (bActive && m_isEdited)
{
if (ms_lpd3dDevice)
ms_lpd3dDevice->SetLight(m_LightID, &m_d3dLight);
}
if (ms_lpd3dDevice)
{
ms_lpd3dDevice->LightEnable(m_LightID, bActive);
}
}
void CLight::SetParameter(TLightID id, const D3DLIGHT8 & c_rLight)
{
m_LightID = id;
m_d3dLight = c_rLight;
}
void CLight::SetDiffuseColor(float fr, float fg, float fb, float fa)
{
if (m_d3dLight.Diffuse.r == fr
&& m_d3dLight.Diffuse.g == fg
&& m_d3dLight.Diffuse.b == fb
&& m_d3dLight.Diffuse.a == fa
)
return;
m_d3dLight.Diffuse.r = fr;
m_d3dLight.Diffuse.g = fg;
m_d3dLight.Diffuse.b = fb;
m_d3dLight.Diffuse.a = fa;
m_isEdited = TRUE;
}
void CLight::SetAmbientColor(float fr, float fg, float fb, float fa)
{
if (m_d3dLight.Ambient.r == fr
&& m_d3dLight.Ambient.g == fg
&& m_d3dLight.Ambient.b == fb
&& m_d3dLight.Ambient.a == fa
)
return;
m_d3dLight.Ambient.r = fr;
m_d3dLight.Ambient.g = fg;
m_d3dLight.Ambient.b = fb;
m_d3dLight.Ambient.a = fa;
m_isEdited = TRUE;
}
void CLight::SetRange(float fRange)
{
if (m_d3dLight.Range == fRange)
return;
m_d3dLight.Range = fRange;
m_isEdited = TRUE;
}
const D3DVECTOR & CLight::GetPosition() const
{
return m_d3dLight.Position;
}
void CLight::SetPosition(float fx, float fy, float fz)
{
if (m_d3dLight.Position.x == fx && m_d3dLight.Position.y == fy && m_d3dLight.Position.z == fz)
return;
m_d3dLight.Position.x = fx;
m_d3dLight.Position.y = fy;
m_d3dLight.Position.z = fz;
m_isEdited = TRUE;
}
void CLight::SetDistance(float fDistance)
{
m_fDistance = fDistance;
}
void CLight::BlendDiffuseColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime)
{
D3DXCOLOR Color(m_d3dLight.Diffuse);
m_DiffuseColorTransitor.SetTransition(Color, c_rColor, ms_fCurTime + fDelayTime, fBlendTime);
}
void CLight::BlendAmbientColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime)
{
D3DXCOLOR Color(m_d3dLight.Ambient);
m_AmbientColorTransitor.SetTransition(Color, c_rColor, ms_fCurTime + fDelayTime, fBlendTime);
}
void CLight::BlendRange(float fRange, float fBlendTime, float fDelayTime)
{
m_RangeTransitor.SetTransition(m_d3dLight.Range, fRange, ms_fCurTime + fDelayTime, fBlendTime);
}
void CLight::Update()
{
if (m_AmbientColorTransitor.isActiveTime(ms_fCurTime))
{
if (!m_AmbientColorTransitor.isActive())
{
m_AmbientColorTransitor.SetActive();
m_AmbientColorTransitor.SetSourceValue(m_d3dLight.Ambient);
}
else
{
D3DXCOLOR Color;
m_AmbientColorTransitor.GetValue(ms_fCurTime, &Color);
SetAmbientColor(Color.r, Color.g, Color.b, Color.a);
}
}
if (m_DiffuseColorTransitor.isActiveTime(ms_fCurTime))
{
if (!m_DiffuseColorTransitor.isActive())
{
m_DiffuseColorTransitor.SetActive();
m_DiffuseColorTransitor.SetSourceValue(m_d3dLight.Diffuse);
}
else
{
D3DXCOLOR Color;
m_DiffuseColorTransitor.GetValue(ms_fCurTime, &Color);
SetDiffuseColor(Color.r, Color.g, Color.b, Color.a);
}
}
if (m_RangeTransitor.isActiveTime(ms_fCurTime))
{
if (!m_RangeTransitor.isActive())
{
m_RangeTransitor.SetActive();
m_RangeTransitor.SetSourceValue(m_d3dLight.Range);
}
else
{
float fRange;
m_RangeTransitor.GetValue(ms_fCurTime, &fRange);
SetRange(fRange);
}
}
}
+127
View File
@@ -0,0 +1,127 @@
#pragma once
#include "../EterBase/Singleton.h"
#include "GrpBase.h"
#include "Util.h"
#include "Pool.h"
#include <deque>
typedef DWORD TLightID;
enum ELightType
{
LIGHT_TYPE_STATIC, // Continuously turning on light
LIGHT_TYPE_DYNAMIC, // Immediately turning off light
};
class CLightBase
{
public:
CLightBase() {};
virtual ~CLightBase() {};
void SetCurrentTime();
protected:
static float ms_fCurTime;
};
class CLight : public CGraphicBase, public CLightBase
{
public:
CLight();
virtual ~CLight();
void Initialize();
void Clear();
void Update();
void SetParameter(TLightID id, const D3DLIGHT8 & c_rLight);
void SetDistance(float fDistance);
float GetDistance() const { return m_fDistance; }
TLightID GetLightID() { return m_LightID; }
BOOL isEdited() { return m_isEdited; }
void SetDeviceLight(BOOL bActive);
void SetDiffuseColor(float fr, float fg, float fb, float fa = 1.0f);
void SetAmbientColor(float fr, float fg, float fb, float fa = 1.0f);
void SetRange(float fRange);
void SetPosition(float fx, float fy, float fz);
const D3DVECTOR & GetPosition() const;
void BlendDiffuseColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime = 0.0f);
void BlendAmbientColor(const D3DXCOLOR & c_rColor, float fBlendTime, float fDelayTime = 0.0f);
void BlendRange(float fRange, float fBlendTime, float fDelayTime = 0.0f);
private:
TLightID m_LightID; // Light ID. equal to D3D light index
D3DLIGHT8 m_d3dLight;
BOOL m_isEdited;
float m_fDistance;
TTransitorColor m_DiffuseColorTransitor;
TTransitorColor m_AmbientColorTransitor;
TTransitorFloat m_RangeTransitor;
};
class CLightManager : public CGraphicBase, public CLightBase, public CSingleton<CLightManager>
{
public:
enum
{
LIGHT_LIMIT_DEFAULT = 3,
// LIGHT_MAX_NUM = 32,
};
typedef std::deque<TLightID> TLightIDDeque;
typedef std::map<TLightID, CLight *> TLightMap;
typedef std::vector<CLight *> TLightSortVector;
public:
CLightManager();
virtual ~CLightManager();
void Destroy();
void Initialize();
// NOTE : FlushLight후 렌더링
// 그 후 반드시 RestoreLight를 해줘야만 한다.
void Update();
void FlushLight();
void RestoreLight();
/////
void RegisterLight(ELightType LightType, TLightID * poutLightID, D3DLIGHT8 & LightData);
CLight * GetLight(TLightID LightID);
void DeleteLight(TLightID LightID);
/////
void SetCenterPosition(const D3DXVECTOR3 & c_rv3Position);
void SetLimitLightCount(DWORD dwLightCount);
void SetSkipIndex(DWORD dwSkipIndex);
protected:
TLightIDDeque m_NonUsingLightIDDeque;
TLightMap m_LightMap;
TLightSortVector m_LightSortVector;
D3DXVECTOR3 m_v3CenterPosition;
DWORD m_dwLimitLightCount;
DWORD m_dwSkipIndex;
protected:
TLightID NewLightID();
void ReleaseLightID(TLightID LightID);
CDynamicPool<CLight> m_LightPool;
};
+256
View File
@@ -0,0 +1,256 @@
#include "StdAfx.h"
#include "GrpMarkInstance.h"
#include "StateManager.h"
#include "ResourceManager.h"
#include "../EterBase/CRC32.h"
CDynamicPool<CGraphicMarkInstance> CGraphicMarkInstance::ms_kPool;
void CGraphicMarkInstance::SetImageFileName(const char* c_szFileName)
{
m_stImageFileName = c_szFileName;
}
const std::string& CGraphicMarkInstance::GetImageFileName()
{
return m_stImageFileName;
}
void CGraphicMarkInstance::CreateSystem(UINT uCapacity)
{
ms_kPool.Create(uCapacity);
}
void CGraphicMarkInstance::DestroySystem()
{
ms_kPool.Destroy();
}
CGraphicMarkInstance* CGraphicMarkInstance::New()
{
return ms_kPool.Alloc();
}
void CGraphicMarkInstance::Delete(CGraphicMarkInstance* pkImgInst)
{
pkImgInst->Destroy();
ms_kPool.Free(pkImgInst);
}
void CGraphicMarkInstance::Render()
{
if (IsEmpty())
return;
assert(!IsEmpty());
OnRender();
}
void CGraphicMarkInstance::OnRender()
{
CGraphicImage * pImage = m_roImage.GetPointer();
CGraphicTexture * pTexture = pImage->GetTexturePointer();
UINT uColCount = pImage->GetWidth() / MARK_WIDTH;
if (uColCount == 0)
return;
UINT uCol = m_uIndex % uColCount;
UINT uRow = m_uIndex / uColCount;
RECT kRect;
kRect.left=uCol*MARK_WIDTH;
kRect.top=uRow*MARK_HEIGHT;
kRect.right=kRect.left+MARK_WIDTH;
kRect.bottom=kRect.top+MARK_HEIGHT;
float texReverseWidth = 1.0f / float(pTexture->GetWidth());
float texReverseHeight = 1.0f / float(pTexture->GetHeight());
float su = kRect.left * texReverseWidth;
float sv = kRect.top * texReverseHeight;
float eu = kRect.right * texReverseWidth;
float ev = kRect.bottom * texReverseHeight;
float fRenderWidth=static_cast<float>(MARK_WIDTH)*m_fScale;
float fRenderHeight= static_cast<float>(MARK_HEIGHT)*m_fScale;
TPDTVertex vertices[4];
vertices[0].position.x = m_v2Position.x-0.5f;
vertices[0].position.y = m_v2Position.y-0.5f;
vertices[0].position.z = 0.0f;
vertices[0].texCoord = TTextureCoordinate(su, sv);
vertices[0].diffuse = m_DiffuseColor;
vertices[1].position.x = m_v2Position.x + fRenderWidth -0.5f;
vertices[1].position.y = m_v2Position.y-0.5f;
vertices[1].position.z = 0.0f;
vertices[1].texCoord = TTextureCoordinate(eu, sv);
vertices[1].diffuse = m_DiffuseColor;
vertices[2].position.x = m_v2Position.x-0.5f;
vertices[2].position.y = m_v2Position.y + fRenderHeight -0.5f;
vertices[2].position.z = 0.0f;
vertices[2].texCoord = TTextureCoordinate(su, ev);
vertices[2].diffuse = m_DiffuseColor;
vertices[3].position.x = m_v2Position.x + fRenderWidth -0.5f;
vertices[3].position.y = m_v2Position.y + fRenderHeight -0.5f;
vertices[3].position.z = 0.0f;
vertices[3].texCoord = TTextureCoordinate(eu, ev);
vertices[3].diffuse = m_DiffuseColor;
if (CGraphicBase::SetPDTStream(vertices, 4))
{
CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT);
STATEMANAGER.SetTexture(0, pTexture->GetD3DTexture());
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2);
//OLD: STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, c_FillRectIndices, D3DFMT_INDEX16, vertices, sizeof(TPDTVertex));
}
}
const CGraphicTexture & CGraphicMarkInstance::GetTextureReference() const
{
return m_roImage->GetTextureReference();
}
CGraphicTexture * CGraphicMarkInstance::GetTexturePointer()
{
return m_roImage->GetTexturePointer();
}
CGraphicImage * CGraphicMarkInstance::GetGraphicImagePointer()
{
return m_roImage.GetPointer();
}
void CGraphicMarkInstance::SetScale(float fScale)
{
m_fScale=fScale;
}
void CGraphicMarkInstance::SetIndex(UINT uIndex)
{
m_uIndex=uIndex;
}
int CGraphicMarkInstance::GetWidth()
{
if (IsEmpty())
return 0;
//return m_roImage->GetWidth();
return 16;
}
int CGraphicMarkInstance::GetHeight()
{
if (IsEmpty())
return 0;
//return m_roImage->GetHeight();
return 12;
}
void CGraphicMarkInstance::SetDiffuseColor(float fr, float fg, float fb, float fa)
{
m_DiffuseColor.r = fr;
m_DiffuseColor.g = fg;
m_DiffuseColor.b = fb;
m_DiffuseColor.a = fa;
}
void CGraphicMarkInstance::SetPosition(float fx, float fy)
{
m_v2Position.x = fx;
m_v2Position.y = fy;
}
void CGraphicMarkInstance::Load()
{
if (GetImageFileName().empty())
return;
CResource * pResource = CResourceManager::Instance().GetResourcePointer(GetImageFileName().c_str());
if (!pResource)
{
TraceError("CGraphicMarkinstance::Load - [%s] NOT EXIST", GetImageFileName().c_str());
return;
}
if (pResource->IsType(CGraphicImage::Type()))
SetImagePointer(static_cast<CGraphicImage*>(pResource));
}
void CGraphicMarkInstance::SetImagePointer(CGraphicImage * pImage)
{
m_roImage.SetPointer(pImage);
OnSetImagePointer();
}
bool CGraphicMarkInstance::IsEmpty() const
{
if (!m_roImage.IsNull() && !m_roImage->IsEmpty())
return false;
return true;
}
bool CGraphicMarkInstance::operator == (const CGraphicMarkInstance & rhs) const
{
return (m_roImage.GetPointer() == rhs.m_roImage.GetPointer());
}
DWORD CGraphicMarkInstance::Type()
{
static DWORD s_dwType = GetCRC32("CGraphicMarkInstance", strlen("CGraphicMarkInstance"));
return (s_dwType);
}
BOOL CGraphicMarkInstance::IsType(DWORD dwType)
{
return OnIsType(dwType);
}
BOOL CGraphicMarkInstance::OnIsType(DWORD dwType)
{
if (CGraphicMarkInstance::Type() == dwType)
return TRUE;
return FALSE;
}
void CGraphicMarkInstance::OnSetImagePointer()
{
}
void CGraphicMarkInstance::Initialize()
{
m_DiffuseColor.r = m_DiffuseColor.g = m_DiffuseColor.b = m_DiffuseColor.a = 1.0f;
m_v2Position.x = m_v2Position.y = 0.0f;
m_uIndex = 0;
m_fScale = 1.0f;
}
void CGraphicMarkInstance::Destroy()
{
m_roImage.SetPointer(NULL); // CRef 에서 레퍼런스 카운트가 떨어져야 함.
Initialize();
}
CGraphicMarkInstance::CGraphicMarkInstance()
{
Initialize();
}
CGraphicMarkInstance::~CGraphicMarkInstance()
{
Destroy();
}
+77
View File
@@ -0,0 +1,77 @@
#pragma once
#include "GrpImage.h"
#include "Pool.h"
class CGraphicMarkInstance
{
public:
static DWORD Type();
BOOL IsType(DWORD dwType);
void SetImageFileName(const char* c_szFileName);
const std::string& GetImageFileName();
public:
CGraphicMarkInstance();
virtual ~CGraphicMarkInstance();
void Destroy();
void Render();
void SetDepth(float fDepth);
void SetDiffuseColor(float fr, float fg, float fb, float fa);
void SetPosition(float fx, float fy);
void SetIndex(UINT uIndex);
void SetScale(float fScale);
void Load();
bool IsEmpty() const;
int GetWidth();
int GetHeight();
CGraphicTexture * GetTexturePointer();
const CGraphicTexture & GetTextureReference() const;
CGraphicImage * GetGraphicImagePointer();
bool operator == (const CGraphicMarkInstance & rhs) const;
protected:
enum
{
MARK_WIDTH = 16,
MARK_HEIGHT = 12,
};
void Initialize();
virtual void OnRender();
virtual void OnSetImagePointer();
virtual BOOL OnIsType(DWORD dwType);
void SetImagePointer(CGraphicImage * pImage);
protected:
D3DXCOLOR m_DiffuseColor;
D3DXVECTOR2 m_v2Position;
UINT m_uIndex;
FLOAT m_fScale;
FLOAT m_fDepth;
CGraphicImage::TRef m_roImage;
std::string m_stImageFileName;
public:
static void CreateSystem(UINT uCapacity);
static void DestroySystem();
static CGraphicMarkInstance* New();
static void Delete(CGraphicMarkInstance* pkImgInst);
static CDynamicPool<CGraphicMarkInstance> ms_kPool;
};
+122
View File
@@ -0,0 +1,122 @@
#pragma once
float CrossProduct2D(float x1, float y1, float x2, float y2);
bool IsInTriangle2D(float ax, float ay, float bx, float by, float cx, float cy, float tx, float ty);
D3DXVECTOR3* D3DXVec3Rotation(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc, const D3DXQUATERNION* c_pqtRot);
D3DXVECTOR3* D3DXVec3Translation(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc, const D3DXVECTOR3* c_pvtTrans);
void GetRotationFromMatrix(D3DXVECTOR3 * pRotation, const D3DXMATRIX * c_pMatrix);
void GetPivotAndRotationFromMatrix(D3DXMATRIX * pMatrix, D3DXVECTOR3 * pPivot, D3DXVECTOR3 * pRotation);
void ExtractMovement(D3DXMATRIX * pTargetMatrix, D3DXMATRIX * pSourceMatrix);
inline D3DXVECTOR3* D3DXVec3Blend(D3DXVECTOR3* pvtOut, const D3DXVECTOR3* c_pvtSrc1, const D3DXVECTOR3* c_pvtSrc2, float d)
{
pvtOut->x=c_pvtSrc1->x+d*(c_pvtSrc2->x-c_pvtSrc1->x);
pvtOut->y=c_pvtSrc1->y+d*(c_pvtSrc2->y-c_pvtSrc1->y);
pvtOut->z=c_pvtSrc1->z+d*(c_pvtSrc2->z-c_pvtSrc1->z);
return pvtOut;
}
inline D3DXQUATERNION* D3DXQuaternionBlend(D3DXQUATERNION* pqtOut, const D3DXQUATERNION* c_pqtSrc1, const D3DXQUATERNION* c_pqtSrc2, float d)
{
pqtOut->x=c_pqtSrc1->x+d*(c_pqtSrc2->x-c_pqtSrc1->x);
pqtOut->y=c_pqtSrc1->y+d*(c_pqtSrc2->y-c_pqtSrc1->y);
pqtOut->z=c_pqtSrc1->z+d*(c_pqtSrc2->z-c_pqtSrc1->z);
pqtOut->w=c_pqtSrc1->w+d*(c_pqtSrc2->w-c_pqtSrc1->w);
return pqtOut;
}
inline float ClampDegree(float fDegree)
{
if (fDegree >= 360.0f)
fDegree -= 360.0f;
if (fDegree < 0.0f)
fDegree += 360.0f;
return fDegree;
}
inline float GetVector3Distance(const D3DXVECTOR3 & c_rv3Source, const D3DXVECTOR3 & c_rv3Target)
{
return (c_rv3Source.x-c_rv3Target.x)*(c_rv3Source.x-c_rv3Target.x) + (c_rv3Source.y-c_rv3Target.y)*(c_rv3Source.y-c_rv3Target.y);
}
inline D3DXQUATERNION SafeRotationNormalizedArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo)
{
if (vFrom == vTo)
return D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f);
if (vFrom == -vTo)
return D3DXQUATERNION(0.0f,0.0f,1.0f,0.0f);
D3DXVECTOR3 c;
D3DXVec3Cross(&c, &vFrom, &vTo);
float d = D3DXVec3Dot(&vFrom, &vTo);
float s = sqrtf((1+d)*2);
return D3DXQUATERNION(c.x/s,c.y/s,c.z/s,s*0.5f);
}
inline D3DXQUATERNION RotationNormalizedArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo)
{
D3DXVECTOR3 c;
D3DXVec3Cross(&c, &vFrom, &vTo);
float d = D3DXVec3Dot(&vFrom, &vTo);
float s = sqrtf((1+d)*2);
return D3DXQUATERNION(c.x/s,c.y/s,c.z/s,s*0.5f);
}
inline D3DXQUATERNION RotationArc(const D3DXVECTOR3 & vFrom , const D3DXVECTOR3 & vTo)
{
D3DXVECTOR3 vnFrom, vnTo;
D3DXVec3Normalize(&vnFrom, &vFrom);
D3DXVec3Normalize(&vnTo, &vTo);
return RotationNormalizedArc(vnFrom, vnTo);
}
inline float square_distance_between_linesegment_and_point(const D3DXVECTOR3& p1,const D3DXVECTOR3& p2,const D3DXVECTOR3& x)
{
const auto v1 = p2 - p1;
float l = D3DXVec3LengthSq(&v1);
const auto v2 = x - p1;
const auto v3 = p2 - p1;
float d = D3DXVec3Dot(&(v2),&(v3));
if (d<=0.0f)
{
return D3DXVec3LengthSq(&(v2));
}
else if (d>=l)
{
const auto v4 = x - p2;
return D3DXVec3LengthSq(&(v4));
}
else
{
D3DXVECTOR3 c;
return D3DXVec3LengthSq(D3DXVec3Cross(&c,&(v2),&(v3)))/l;
}
}
inline D3DXVECTOR3 * Vec3TransformQuaternionSafe(D3DXVECTOR3* pvout, const D3DXVECTOR3* pv, const D3DXQUATERNION* pq)
{
D3DXVECTOR3 v;
D3DXVec3Cross(&v,pv,(D3DXVECTOR3*)pq);
v *= -2*pq->w;
v += (pq->w*pq->w - D3DXVec3LengthSq((D3DXVECTOR3*)pq))*(*pv);
v += 2*D3DXVec3Dot((D3DXVECTOR3*)pq,pv)*(*(D3DXVECTOR3*)pq);
*pvout = v;
return pvout;
}
inline D3DXVECTOR3 * Vec3TransformQuaternion(D3DXVECTOR3* pvout, const D3DXVECTOR3* pv, const D3DXQUATERNION* pq)
{
D3DXVec3Cross(pvout,pv,(D3DXVECTOR3*)pq);
*pvout *= -2*pq->w;
*pvout += (pq->w*pq->w - D3DXVec3LengthSq((D3DXVECTOR3*)pq))*(*pv);
*pvout += 2*D3DXVec3Dot((D3DXVECTOR3*)pq,pv)*(*(D3DXVECTOR3*)pq);
return pvout;
}
+441
View File
@@ -0,0 +1,441 @@
#include "StdAfx.h"
#include "GrpObjectInstance.h"
#include "../EterBase/Timer.h"
void CGraphicObjectInstance::OnInitialize()
{
ZeroMemory(m_abyPortalID, sizeof(m_abyPortalID));
}
void CGraphicObjectInstance::Clear()
{
if (m_CullingHandle)
{
CCullingManager::Instance().Unregister(m_CullingHandle);
m_CullingHandle = NULL;
}
ClearHeightInstance();
m_isVisible = TRUE;
m_v3Position.x = m_v3Position.y = m_v3Position.z = 0.0f;
m_v3Scale.x = m_v3Scale.y = m_v3Scale.z = 0.0f;
//m_fRotation = 0.0f;
m_fYaw = m_fPitch = m_fRoll = 0.0f;
D3DXMatrixIdentity(&m_worldMatrix);
ZeroMemory(m_abyPortalID, sizeof(m_abyPortalID));
OnClear();
}
bool CGraphicObjectInstance::Render()
{
/*
if (m_CullingHandle)
{
SpherePack * ps = m_CullingHandle->GetParent();
CScreen s;
s.SetColorOperation();
//s.SetDiffuseColor(1,isShow()?1:0,0);
//s.RenderCircle2d(m_CullingHandle->GetCenter().x,m_CullingHandle->GetCenter().y,m_CullingHandle->GetCenter().z,m_CullingHandle->GetRadius());
s.SetDiffuseColor(1,isShow()?1:0,ps->HasSpherePackFlag(SPF_PARTIAL)?1:0);
s.RenderCircle2d(ps->GetCenter().x,ps->GetCenter().y,ps->GetCenter().z,ps->GetRadius());
}
//*/
if (!isShow())
return false;
OnRender();
return true;
}
void CGraphicObjectInstance::BlendRender()
{
if (!isShow())
return;
OnBlendRender();
}
void CGraphicObjectInstance::RenderToShadowMap()
{
if (!isShow())
return;
OnRenderToShadowMap();
}
void CGraphicObjectInstance::RenderShadow()
{
if (!isShow())
return;
OnRenderShadow();
}
void CGraphicObjectInstance::RenderPCBlocker()
{
if (!isShow())
return;
OnRenderPCBlocker();
}
void CGraphicObjectInstance::Update()
{
OnUpdate();
UpdateBoundingSphere();
}
void CGraphicObjectInstance::Deform()
{
if (!isShow())
return;
OnDeform();
}
void CGraphicObjectInstance::Transform()
{
m_worldMatrix = m_mRotation;
m_worldMatrix._41 += m_v3Position.x;
m_worldMatrix._42 += m_v3Position.y;
m_worldMatrix._43 += m_v3Position.z;
}
const D3DXVECTOR3 & CGraphicObjectInstance::GetPosition() const
{
return m_v3Position;
}
const D3DXVECTOR3 & CGraphicObjectInstance::GetScale() const
{
return m_v3Scale;
}
float CGraphicObjectInstance::GetRotation()
{
return GetRoll();
}
float CGraphicObjectInstance::GetYaw()
{
return m_fYaw;
}
float CGraphicObjectInstance::GetPitch()
{
return m_fPitch;
}
float CGraphicObjectInstance::GetRoll()
{
return m_fRoll;
}
D3DXMATRIX & CGraphicObjectInstance::GetTransform()
{
return m_worldMatrix;
}
void CGraphicObjectInstance::SetRotationQuaternion(const D3DXQUATERNION &q)
{
D3DXMatrixRotationQuaternion(&m_mRotation, &q);
}
void CGraphicObjectInstance::SetRotationMatrix(const D3DXMATRIX & m)
{
m_mRotation = m;
}
void CGraphicObjectInstance::SetRotation(float fRotation)
{
m_fYaw = 0;
m_fPitch = 0;
m_fRoll = fRotation;
D3DXMatrixRotationZ(&m_mRotation, D3DXToRadian(fRotation));
}
void CGraphicObjectInstance::SetRotation(float fYaw, float fPitch, float fRoll)
{
//m_fRotation = fRotation;
m_fYaw = fYaw;
m_fPitch = fPitch;
m_fRoll = fRoll;
D3DXMatrixRotationYawPitchRoll(&m_mRotation, D3DXToRadian(fYaw), D3DXToRadian(fPitch), D3DXToRadian(fRoll));
}
void CGraphicObjectInstance::SetPosition(float x, float y, float z)
{
m_v3Position.x = x;
m_v3Position.y = y;
m_v3Position.z = z;
}
void CGraphicObjectInstance::SetPosition(const D3DXVECTOR3 & newposition)
{
m_v3Position = newposition;
}
void CGraphicObjectInstance::SetScale(float x, float y, float z)
{
m_v3Scale.x = x;
m_v3Scale.y = y;
m_v3Scale.z = z;
}
void CGraphicObjectInstance::Show()
{
m_isVisible = true;
}
void CGraphicObjectInstance::Hide()
{
m_isVisible = false;
}
bool CGraphicObjectInstance::isShow()
{
return m_isVisible;
}
//
//////////////////////////////////////////////////////////////////////////
D3DXVECTOR4 & CGraphicObjectInstance::GetWTBBoxVertex(const unsigned char & c_rucNumTBBoxVertex)
{
return m_v4TBBox[c_rucNumTBBoxVertex];
}
bool CGraphicObjectInstance::isIntersect(const CRay & c_rRay, float * pu, float * pv, float * pt)
{
D3DXVECTOR3 v3Start, v3Dir;
float fRayRange;
c_rRay.GetStartPoint(&v3Start);
c_rRay.GetDirection(&v3Dir, &fRayRange);
TPosition posVertices[8];
posVertices[0] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMin.y, m_v3TBBoxMin.z);
posVertices[1] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMin.y, m_v3TBBoxMin.z);
posVertices[2] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMax.y, m_v3TBBoxMin.z);
posVertices[3] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMax.y, m_v3TBBoxMin.z);
posVertices[4] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMin.y, m_v3TBBoxMax.z);
posVertices[5] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMin.y, m_v3TBBoxMax.z);
posVertices[6] = TPosition(m_v3TBBoxMin.x, m_v3TBBoxMax.y, m_v3TBBoxMax.z);
posVertices[7] = TPosition(m_v3TBBoxMax.x, m_v3TBBoxMax.y, m_v3TBBoxMax.z);
TIndex Indices[36] = {0, 1, 2, 1, 3, 2,
2, 0, 6, 0, 4, 6,
0, 1, 4, 1, 5, 4,
1, 3, 5, 3, 7, 5,
3, 2, 7, 2, 6, 7,
4, 5, 6, 5, 7, 6};
int triCount = 12;
WORD* pcurIdx = (WORD*)Indices;
while (triCount--)
{
if (IntersectTriangle(v3Start, v3Dir,
posVertices[pcurIdx[0]],
posVertices[pcurIdx[1]],
posVertices[pcurIdx[2]],
pu, pv, pt))
{
return true;
}
pcurIdx += 3;
}
return false;
}
CGraphicObjectInstance::CGraphicObjectInstance()
{
m_CullingHandle = 0;
Initialize();
}
void CGraphicObjectInstance::Initialize()
{
if (m_CullingHandle)
CCullingManager::Instance().Unregister(m_CullingHandle);
m_CullingHandle = 0;
m_pHeightAttributeInstance = NULL;
m_isVisible = TRUE;
m_BlockCamera = false;
m_v3Position.x = m_v3Position.y = m_v3Position.z = 0.0f;
m_v3Scale.x = m_v3Scale.y = m_v3Scale.z = 0.0f;
m_fYaw = m_fPitch = m_fRoll = 0.0f;
D3DXMatrixIdentity(&m_worldMatrix);
D3DXMatrixIdentity(&m_mRotation);
OnInitialize();
}
CGraphicObjectInstance::~CGraphicObjectInstance()
{
Initialize();
}
void CGraphicObjectInstance::UpdateBoundingSphere()
{
if (m_CullingHandle)
{
Vector3d center;
float radius;
GetBoundingSphere(center,radius);
if (radius != m_CullingHandle->GetRadius())
m_CullingHandle->NewPosRadius(center,radius);
else
m_CullingHandle->NewPos(center);
}
}
void CGraphicObjectInstance::RegisterBoundingSphere()
{
if (m_CullingHandle)
CCullingManager::Instance().Unregister(m_CullingHandle);
m_CullingHandle = CCullingManager::Instance().Register(this);
}
void CGraphicObjectInstance::AddCollision(const CStaticCollisionData * pscd, const D3DXMATRIX* pMat)
{
m_StaticCollisionInstanceVector.push_back(CBaseCollisionInstance::BuildCollisionInstance(pscd, pMat));
}
void CGraphicObjectInstance::ClearCollision()
{
CCollisionInstanceVector::iterator it;
for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it)
{
(*it)->Destroy();
}
m_StaticCollisionInstanceVector.clear();
}
bool CGraphicObjectInstance::CollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
CCollisionInstanceVector::const_iterator it;
for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it)
{
if ((*it)->CollisionDynamicSphere(s))
return true;
}
return false;
}
bool CGraphicObjectInstance::MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const
{
CCollisionInstanceVector::const_iterator it;
for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it)
{
if ((*it)->MovementCollisionDynamicSphere(s))
return true;
}
return false;
}
D3DXVECTOR3 CGraphicObjectInstance::GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const
{
CCollisionInstanceVector::const_iterator it;
for(it = m_StaticCollisionInstanceVector.begin();it!=m_StaticCollisionInstanceVector.end();++it)
{
if ((*it)->MovementCollisionDynamicSphere(s))
return (*it)->GetCollisionMovementAdjust(s);
}
return D3DXVECTOR3(0.0f,0.0f,0.0f);
}
void CGraphicObjectInstance::UpdateCollisionData(const CStaticCollisionDataVector * pscdVector)
{
ClearCollision();
OnUpdateCollisionData(pscdVector);
}
DWORD CGraphicObjectInstance::GetCollisionInstanceCount()
{
return m_StaticCollisionInstanceVector.size();
}
CBaseCollisionInstance * CGraphicObjectInstance::GetCollisionInstanceData(DWORD dwIndex)
{
if (dwIndex>m_StaticCollisionInstanceVector.size())
{
return 0;
}
return m_StaticCollisionInstanceVector[dwIndex];
}
//////////////////////////////////////////////////////////////////////////
// Height
void CGraphicObjectInstance::SetHeightInstance(CAttributeInstance * pAttributeInstance)
{
m_pHeightAttributeInstance = pAttributeInstance;
}
void CGraphicObjectInstance::ClearHeightInstance()
{
m_pHeightAttributeInstance = NULL;
}
void CGraphicObjectInstance::UpdateHeightInstance(CAttributeInstance * pAttributeInstance)
{
ClearHeightInstance();
OnUpdateHeighInstance(pAttributeInstance);
}
bool CGraphicObjectInstance::IsObjectHeight()
{
if (m_pHeightAttributeInstance)
return true;
return false;
}
bool CGraphicObjectInstance::GetObjectHeight(float fX, float fY, float * pfHeight)
{
if (!m_pHeightAttributeInstance)
return false;
return OnGetObjectHeight(fX, fY, pfHeight);
}
void CGraphicObjectInstance::SetPortal(DWORD dwIndex, int iID)
{
if (dwIndex >= PORTAL_ID_MAX_NUM)
{
assert(dwIndex < PORTAL_ID_MAX_NUM);
return;
}
m_abyPortalID[dwIndex] = iID;
}
int CGraphicObjectInstance::GetPortal(DWORD dwIndex)
{
if (dwIndex >= PORTAL_ID_MAX_NUM)
{
assert(dwIndex < PORTAL_ID_MAX_NUM);
return 0;
}
return m_abyPortalID[dwIndex];
}
+161
View File
@@ -0,0 +1,161 @@
#pragma once
#include "GrpColorInstance.h"
#include "GrpScreen.h"
#include "CullingManager.h"
#include "CollisionData.h"
#include "AttributeInstance.h"
enum
{
THING_OBJECT = 0xadf21f13,
TREE_OBJECT = 0x8ac9f7a6,
ACTOR_OBJECT = 0x29a76c24,
EFFECT_OBJECT = 0x1cfa97c6,
DUNGEON_OBJECT = 0x18326035,
};
enum
{
PORTAL_ID_MAX_NUM = 8,
};
class CGraphicObjectInstance : public CGraphicCollisionObject
{
public:
CGraphicObjectInstance();
virtual ~CGraphicObjectInstance();
virtual int GetType() const = 0;
public:
const D3DXVECTOR3 & GetPosition() const;
const D3DXVECTOR3 & GetScale() const;
float GetRotation();
float GetYaw();
float GetPitch();
float GetRoll();
void SetPosition(float x, float y, float z);
void SetPosition(const D3DXVECTOR3 & newposition);
void SetScale(float x, float y, float z);
void SetRotation(float fRotation);
void SetRotation(float fYaw, float fPitch, float fRoll);
void SetRotationQuaternion(const D3DXQUATERNION &q);
void SetRotationMatrix(const D3DXMATRIX & m);
void Clear();
void Update();
bool Render();
void BlendRender();
void RenderToShadowMap();
void RenderShadow();
void RenderPCBlocker();
void Deform();
void Transform();
void Show();
void Hide();
bool isShow();
// Camera Block
void BlockCamera(bool bBlock) {m_BlockCamera = bBlock;}
bool BlockCamera() { return m_BlockCamera; }
// Ray Test
bool isIntersect(const CRay & c_rRay, float * pu, float * pv, float * pt);
// Bounding Box
D3DXVECTOR4 & GetWTBBoxVertex(const unsigned char & c_rucNumTBBoxVertex);
D3DXVECTOR3 & GetTBBoxMin() { return m_v3TBBoxMin; }
D3DXVECTOR3 & GetTBBoxMax() { return m_v3TBBoxMax; }
D3DXVECTOR3 & GetBBoxMin() { return m_v3BBoxMin; }
D3DXVECTOR3 & GetBBoxMax() { return m_v3BBoxMax; }
// Matrix
D3DXMATRIX & GetTransform();
const D3DXMATRIX& GetWorldMatrix() { return m_worldMatrix; }
// Portal
void SetPortal(DWORD dwIndex, int iID);
int GetPortal(DWORD dwIndex);
// Initialize
void Initialize();
virtual void OnInitialize();
// Bounding Sphere
public:
void UpdateBoundingSphere();
void RegisterBoundingSphere();
virtual bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius) = 0;
virtual void OnRender() = 0;
virtual void OnBlendRender() = 0;
virtual void OnRenderToShadowMap() = 0;
virtual void OnRenderShadow() = 0;
virtual void OnRenderPCBlocker() = 0;
virtual void OnClear(){}
virtual void OnUpdate(){}
virtual void OnDeform(){}
protected:
D3DXVECTOR3 m_v3Position;
D3DXVECTOR3 m_v3Scale;
float m_fYaw;
float m_fPitch;
float m_fRoll;
D3DXMATRIX m_mRotation;
bool m_isVisible;
D3DXMATRIX m_worldMatrix;
// Camera Block
bool m_BlockCamera;
// Bounding Box
D3DXVECTOR4 m_v4TBBox[8];
D3DXVECTOR3 m_v3TBBoxMin, m_v3TBBoxMax;
D3DXVECTOR3 m_v3BBoxMin, m_v3BBoxMax;
// Portal
BYTE m_abyPortalID[PORTAL_ID_MAX_NUM];
// Culling
CCullingManager::CullingHandle m_CullingHandle;
// Static Collision Data
public:
void AddCollision(const CStaticCollisionData * pscd, const D3DXMATRIX * pMat);
void ClearCollision();
bool CollisionDynamicSphere(const CDynamicSphereInstance & s) const;
bool MovementCollisionDynamicSphere(const CDynamicSphereInstance & s) const;
D3DXVECTOR3 GetCollisionMovementAdjust(const CDynamicSphereInstance & s) const;
void UpdateCollisionData(const CStaticCollisionDataVector * pscdVector = 0);
protected:
CCollisionInstanceVector m_StaticCollisionInstanceVector;
virtual void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector) = 0;
// using in WorldEditor
public:
DWORD GetCollisionInstanceCount();
CBaseCollisionInstance * GetCollisionInstanceData(DWORD dwIndex);
// Height Data
public:
void SetHeightInstance(CAttributeInstance * pAttributeInstance);
void ClearHeightInstance();
void UpdateHeightInstance(CAttributeInstance * pAttributeInstance = 0);
bool IsObjectHeight();
bool GetObjectHeight(float fX, float fY, float * pfHeight);
protected:
CAttributeInstance * m_pHeightAttributeInstance;
virtual void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) = 0;
virtual bool OnGetObjectHeight(float fX, float fY, float * pfHeight) = 0;
};
+82
View File
@@ -0,0 +1,82 @@
#pragma once
#include "GrpCollisionObject.h"
#include "../SphereLib/frustum.h"
class CScreen : public CGraphicCollisionObject
{
public:
CScreen();
virtual ~CScreen();
void ClearDepthBuffer();
void Clear();
bool Begin();
void End();
void Show(HWND hWnd = NULL);
void Show(RECT * pSrcRect);
void Show(RECT * pSrcRect, HWND hWnd);
void RenderLine2d(float sx, float sy, float ex, float ey, float z=0.0f);
void RenderBox2d(float sx, float sy, float ex, float ey, float z=0.0f);
void RenderBar2d(float sx, float sy, float ex, float ey, float z=0.0f);
void RenderGradationBar2d(float sx, float sy, float ex, float ey, DWORD dwStartColor, DWORD dwEndColor, float ez=0.0f);
void RenderCircle2d(float fx, float fy, float fz, float fRadius, int iStep = 50);
void RenderCircle3d(float fx, float fy, float fz, float fRadius, int iStep = 50);
void RenderLine3d(float sx, float sy, float sz, float ex, float ey, float ez);
void RenderBox3d(float sx, float sy, float sz, float ex, float ey, float ez);
void RenderBar3d(float sx, float sy, float sz, float ex, float ey, float ez);
void RenderBar3d(const D3DXVECTOR3 * c_pv3Positions);
void RenderGradationBar3d(float sx, float sy, float sz, float ex, float ey, float ez, DWORD dwStartColor, DWORD dwEndColor);
void RenderLineCube(float sx, float sy, float sz, float ex, float ey, float ez);
void RenderCube(float sx, float sy, float sz, float ex, float ey, float ez);
void RenderCube(float sx, float sy, float sz, float ex, float ey, float ez, D3DXMATRIX matRotation);
void RenderTextureBox(float sx, float sy, float ex, float ey, float z=0.0f, float su=0.0f, float sv=0.0f, float eu=1.0f, float ev=1.0f);
void RenderBillboard(D3DXVECTOR3 * Position, D3DXCOLOR & Color);
void DrawMinorGrid(float xMin, float yMin, float xMax, float yMax, float xminorStep, float yminorStep, float zPos=0);
void DrawGrid(float xMin, float yMin, float xMax, float yMax, float xmajorStep, float ymajorStep, float xminorStep, float yminorStep, float zPos=0);
void RenderD3DXMesh(LPD3DXMESH lpMesh, const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, D3DFILLMODE d3dFillMode);
void RenderSphere(const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
void RenderCylinder(const D3DXMATRIX * c_pmatWorld, float fx, float fy, float fz, float fRadius, float fLength, D3DFILLMODE d3dFillMode = D3DFILL_SOLID);
void SetColorOperation();
void SetDiffuseOperation();
void SetBlendOperation();
void SetOneColorOperation(D3DXCOLOR & rColor);
void SetAddColorOperation(D3DXCOLOR & rColor);
void SetDiffuseColor(DWORD diffuseColor);
void SetDiffuseColor(float r, float g, float b, float a=1.0f);
void SetClearColor(float r, float g, float b, float a=1.0f);
void SetClearDepth(float depth);
void SetClearStencil(DWORD stencil);
void SetCursorPosition(int x, int y, int hres, int vres); // creates picking ray
bool GetCursorPosition(float* px, float* py, float* pz);
bool GetCursorXYPosition(float* px, float* py);
bool GetCursorZPosition(float* pz);
void GetPickingPosition(float t, float* x, float* y, float* z);
void ProjectPosition(float x, float y, float z, float * pfX, float * pfY);
void ProjectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ);
void UnprojectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ);
BOOL IsLostDevice();
BOOL RestoreDevice();
void BuildViewFrustum();
static void Identity();
static Frustum & GetFrustum() { return ms_frustum; }
protected:
static DWORD ms_diffuseColor;
static DWORD ms_clearColor;
static DWORD ms_clearStencil;
static float ms_clearDepth;
static Frustum ms_frustum;
};
+191
View File
@@ -0,0 +1,191 @@
#include "StdAfx.h"
#include "GrpShadowTexture.h"
#include "StateManager.h"
//////////////////////////////////////////////////////////////////////////
void CGraphicShadowTexture::Destroy()
{
CGraphicTexture::Destroy();
if (m_lpd3dShadowSurface)
{
m_lpd3dShadowSurface->Release();
m_lpd3dShadowSurface = NULL;
}
if (m_lpd3dDepthSurface)
{
m_lpd3dDepthSurface->Release();
m_lpd3dDepthSurface = NULL;
}
if (m_lpd3dShadowTexture)
{
m_lpd3dShadowTexture->Release();
m_lpd3dShadowTexture = NULL;
}
Initialize();
}
bool CGraphicShadowTexture::Create(int width, int height)
{
Destroy();
m_width = width;
m_height = height;
if (FAILED(ms_lpd3dDevice->CreateTexture(m_width, m_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_lpd3dShadowTexture)))
return false;
if (FAILED(m_lpd3dShadowTexture->GetSurfaceLevel(0, &m_lpd3dShadowSurface)))
return false;
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_width, m_height, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpd3dDepthSurface)))
return false;
return true;
}
void CGraphicShadowTexture::Set(int stage) const
{
STATEMANAGER.SetTexture(stage, m_lpd3dShadowTexture);
}
const D3DXMATRIX& CGraphicShadowTexture::GetLightVPMatrixReference() const
{
return m_d3dLightVPMatrix;
}
LPDIRECT3DTEXTURE8 CGraphicShadowTexture::GetD3DTexture() const
{
return m_lpd3dShadowTexture;
}
void CGraphicShadowTexture::Begin()
{
D3DXMatrixMultiply(&m_d3dLightVPMatrix, &ms_matView, &ms_matProj);
ms_lpd3dDevice->GetRenderTarget(&m_lpd3dOldBackBufferSurface);
ms_lpd3dDevice->GetDepthStencilSurface(&m_lpd3dOldDepthBufferSurface);
ms_lpd3dDevice->GetViewport(&m_d3dOldViewport);
ms_lpd3dDevice->SetRenderTarget(m_lpd3dShadowSurface, m_lpd3dDepthSurface);
D3DVIEWPORT8 d3dViewport;
d3dViewport.MinZ = 0.0f;
d3dViewport.MaxZ = 1.0f;
d3dViewport.X = 0;
d3dViewport.Y = 0;
d3dViewport.Width = m_width;
d3dViewport.Height = m_height;
ms_lpd3dDevice->SetViewport(&d3dViewport);
ms_lpd3dDevice->BeginScene();
ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
STATEMANAGER.SaveRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, true);
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, true);
STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xbb000000);
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
}
void CGraphicShadowTexture::End()
{
assert(m_lpd3dOldBackBufferSurface != NULL);
assert(m_lpd3dOldDepthBufferSurface != NULL);
ms_lpd3dDevice->EndScene();
ms_lpd3dDevice->SetRenderTarget(m_lpd3dOldBackBufferSurface, m_lpd3dOldDepthBufferSurface);
ms_lpd3dDevice->SetViewport(&m_d3dOldViewport);
m_lpd3dOldBackBufferSurface->Release();
m_lpd3dOldDepthBufferSurface->Release();
m_lpd3dOldBackBufferSurface = NULL;
m_lpd3dOldDepthBufferSurface = NULL;
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG1);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG2);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLOROP);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG1);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG2);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAOP);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MINFILTER);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MAGFILTER);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MIPFILTER);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
}
void CGraphicShadowTexture::Initialize()
{
CGraphicTexture::Initialize();
m_lpd3dShadowSurface = NULL;
m_lpd3dDepthSurface = NULL;
m_lpd3dOldBackBufferSurface = NULL;
m_lpd3dOldDepthBufferSurface = NULL;
m_lpd3dShadowTexture = NULL;
}
CGraphicShadowTexture::CGraphicShadowTexture()
{
Initialize();
}
CGraphicShadowTexture::~CGraphicShadowTexture()
{
Destroy();
}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#include "GrpTexture.h"
class CGraphicShadowTexture : public CGraphicTexture
{
public:
CGraphicShadowTexture();
virtual ~CGraphicShadowTexture();
void Destroy();
bool Create(int width, int height);
void Begin();
void End();
void Set(int stage = 0) const;
const D3DXMATRIX& GetLightVPMatrixReference() const;
LPDIRECT3DTEXTURE8 GetD3DTexture() const;
protected:
void Initialize();
protected:
D3DXMATRIX m_d3dLightVPMatrix;
D3DVIEWPORT8 m_d3dOldViewport;
LPDIRECT3DTEXTURE8 m_lpd3dShadowTexture;
LPDIRECT3DSURFACE8 m_lpd3dShadowSurface;
LPDIRECT3DSURFACE8 m_lpd3dDepthSurface;
LPDIRECT3DSURFACE8 m_lpd3dOldBackBufferSurface;
LPDIRECT3DSURFACE8 m_lpd3dOldDepthBufferSurface;
};
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include "GrpImage.h"
class CGraphicSubImage : public CGraphicImage
{
public:
typedef CRef<CGraphicImage> TRef;
public:
static TType Type();
static char m_SearchPath[256];
public:
CGraphicSubImage(const char* c_szFileName);
virtual ~CGraphicSubImage();
bool CreateDeviceObjects();
bool SetImageFileName(const char* c_szFileName);
void SetRectPosition(int left, int top, int right, int bottom);
void SetRectReference(const RECT& c_rRect);
static void SetSearchPath(const char * c_szFileName);
protected:
void SetImagePointer(CGraphicImage* pImage);
bool OnLoad(int iSize, const void* c_pvBuf);
void OnClear();
bool OnIsEmpty() const;
bool OnIsType(TType type);
protected:
CGraphicImage::TRef m_roImage;
};
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "Resource.h"
#include "Ref.h"
#include "GrpFontTexture.h"
class CGraphicText : public CResource
{
public:
typedef CRef<CGraphicText> TRef;
public:
static TType Type();
public:
CGraphicText(const char* c_szFileName);
virtual ~CGraphicText();
virtual bool CreateDeviceObjects();
virtual void DestroyDeviceObjects();
CGraphicFontTexture * GetFontTexturePointer();
protected:
bool OnLoad(int iSize, const void * c_pvBuf);
void OnClear();
bool OnIsEmpty() const;
bool OnIsType(TType type);
protected:
CGraphicFontTexture m_fontTexture;
};
+134
View File
@@ -0,0 +1,134 @@
#ifndef __INC_ETERLIB_GRPTEXTINSTANCE_H__
#define __INC_ETERLIB_GRPTEXTINSTANCE_H__
#include "Pool.h"
#include "GrpText.h"
class CGraphicTextInstance
{
public:
typedef CDynamicPool<CGraphicTextInstance> TPool;
public:
enum EHorizontalAlign
{
HORIZONTAL_ALIGN_LEFT = 0x01,
HORIZONTAL_ALIGN_CENTER = 0x02,
HORIZONTAL_ALIGN_RIGHT = 0x03,
};
enum EVerticalAlign
{
VERTICAL_ALIGN_TOP = 0x10,
VERTICAL_ALIGN_CENTER = 0x20,
VERTICAL_ALIGN_BOTTOM = 0x30
};
public:
static void Hyperlink_UpdateMousePos(int x, int y);
static int Hyperlink_GetText(char* buf, int len);
public:
CGraphicTextInstance();
virtual ~CGraphicTextInstance();
void Destroy();
void Update();
void Render(RECT * pClipRect = NULL);
void ShowCursor();
void HideCursor();
void ShowOutLine();
void HideOutLine();
void SetColor(DWORD color);
void SetColor(float r, float g, float b, float a = 1.0f);
void SetOutLineColor(DWORD color);
void SetOutLineColor(float r, float g, float b, float a = 1.0f);
void SetHorizonalAlign(int hAlign);
void SetVerticalAlign(int vAlign);
void SetMax(int iMax);
void SetTextPointer(CGraphicText* pText);
void SetValueString(const std::string& c_stValue);
void SetValue(const char* c_szValue, size_t len = -1);
void SetPosition(float fx, float fy, float fz = 0.0f);
void SetSecret(bool Value);
void SetOutline(bool Value);
void SetFeather(bool Value);
void SetMultiLine(bool Value);
void SetLimitWidth(float fWidth);
void GetTextSize(int* pRetWidth, int* pRetHeight);
const std::string& GetValueStringReference();
WORD GetTextLineCount();
int PixelPositionToCharacterPosition(int iPixelPosition);
int GetHorizontalAlign();
protected:
void __Initialize();
int __DrawCharacter(CGraphicFontTexture * pFontTexture, WORD codePage, wchar_t text, DWORD dwColor);
void __GetTextPos(DWORD index, float* x, float* y);
int __GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo);
protected:
struct SHyperlink
{
short sx;
short ex;
std::wstring text;
SHyperlink() : sx(0), ex(0) { }
};
protected:
DWORD m_dwTextColor;
DWORD m_dwOutLineColor;
WORD m_textWidth;
WORD m_textHeight;
BYTE m_hAlign;
BYTE m_vAlign;
WORD m_iMax;
float m_fLimitWidth;
bool m_isCursor;
bool m_isSecret;
bool m_isMultiLine;
bool m_isOutline;
float m_fFontFeather;
/////
std::string m_stText;
D3DXVECTOR3 m_v3Position;
private:
bool m_isUpdate;
bool m_isUpdateFontTexture;
CGraphicText::TRef m_roText;
CGraphicFontTexture::TPCharacterInfomationVector m_pCharInfoVector;
std::vector<DWORD> m_dwColorInfoVector;
std::vector<SHyperlink> m_hyperlinkVector;
public:
static void CreateSystem(UINT uCapacity);
static void DestroySystem();
static CGraphicTextInstance* New();
static void Delete(CGraphicTextInstance* pkInst);
static CDynamicPool<CGraphicTextInstance> ms_kPool;
};
extern const char* FindToken(const char* begin, const char* end);
extern int ReadToken(const char* token);
#endif
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "GrpBase.h"
class CGraphicTexture : public CGraphicBase
{
public:
virtual bool IsEmpty() const;
int GetWidth() const;
int GetHeight() const;
void SetTextureStage(int stage) const;
LPDIRECT3DTEXTURE8 GetD3DTexture() const;
void DestroyDeviceObjects();
protected:
CGraphicTexture();
virtual ~CGraphicTexture();
void Destroy();
void Initialize();
protected:
bool m_bEmpty;
int m_width;
int m_height;
LPDIRECT3DTEXTURE8 m_lpd3dTexture;
};
+50
View File
@@ -0,0 +1,50 @@
#pragma once
#include "GrpBase.h"
class CGraphicVertexBuffer : public CGraphicBase
{
public:
CGraphicVertexBuffer();
virtual ~CGraphicVertexBuffer();
void Destroy();
virtual bool Create(int vtxCount, DWORD fvf, DWORD usage, D3DPOOL d3dPool);
bool CreateDeviceObjects();
void DestroyDeviceObjects();
bool Copy(int bufSize, const void* srcVertices);
bool LockRange(unsigned count, void** pretVertices) const;
bool Lock(void** pretVertices) const;
bool Unlock() const;
bool LockDynamic(void** pretVertices);
virtual bool Lock(void** pretVertices);
bool Unlock();
void SetStream(int stride, int layer=0) const;
int GetVertexCount() const;
int GetVertexStride() const;
DWORD GetFlexibleVertexFormat() const;
inline LPDIRECT3DVERTEXBUFFER8 GetD3DVertexBuffer() const { return m_lpd3dVB; }
inline DWORD GetBufferSize() const { return m_dwBufferSize; }
bool IsEmpty() const;
protected:
void Initialize();
protected:
LPDIRECT3DVERTEXBUFFER8 m_lpd3dVB;
DWORD m_dwBufferSize;
DWORD m_dwFVF;
DWORD m_dwUsage;
D3DPOOL m_d3dPool;
int m_vtxCount;
DWORD m_dwLockFlag;
};
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "GrpVertexBuffer.h"
class CDynamicVertexBuffer : public CGraphicVertexBuffer
{
public:
CDynamicVertexBuffer();
virtual ~CDynamicVertexBuffer();
bool Create(int vtxCount, int fvf);
protected:
int m_vtxCount;
int m_fvf;
};
+208
View File
@@ -0,0 +1,208 @@
#pragma once
#include <imm.h>
#pragma comment(lib, "imm32.lib")
#include "Dimm.h"
class IIMEEventSink
{
public:
virtual bool OnWM_CHAR( WPARAM wParam, LPARAM lParam ) = 0;
virtual void OnUpdate() = 0;
virtual void OnChangeCodePage() = 0;
virtual void OnOpenCandidateList() = 0;
virtual void OnCloseCandidateList() = 0;
virtual void OnOpenReadingWnd() = 0;
virtual void OnCloseReadingWnd() = 0;
};
class CIME
{
public:
enum
{
IMEREADING_MAXLEN = 128,
IMESTR_MAXLEN = 1024,
IMECANDIDATE_MAXLEN = 32768,
MAX_CANDLIST = 10,
MAX_CANDIDATE_LENGTH = 256
};
public:
CIME();
virtual ~CIME();
bool Initialize(HWND hWnd);
void Uninitialize(void);
static void Clear();
void SetMax(int iMax);
void SetUserMax(int iMax);
void SetText(const char* c_szText, int len);
int GetText(std::string & rstrText, bool addCodePage=false);
const char* GetCodePageText();
int GetCodePage();
// Candidate List
int GetCandidateCount();
int GetCandidatePageCount();
int GetCandidate(DWORD index, std::string & rstrText);
int GetCandidateSelection();
// Reading Information
int GetReading(std::string & rstrText);
int GetReadingError();
void SetInputMode(DWORD dwMode);
DWORD GetInputMode();
bool IsIMEEnabled();
void EnableIME(bool bEnable=true);
void DisableIME();
void EnableCaptureInput();
void DisableCaptureInput();
bool IsCaptureEnabled();
void SetNumberMode();
void SetStringMode();
bool __IsWritable(wchar_t key);
void AddExceptKey(wchar_t key);
void ClearExceptKey();
void PasteTextFromClipBoard();
void EnablePaste(bool bFlag);
void PasteString(const char * str);
static void FinalizeString(bool bSend = false);
void UseDefaultIME();
static int GetCurPos();
static int GetCompLen();
static int GetULBegin();
static int GetULEnd();
static void CloseCandidateList();
static void CloseReadingInformation();
static void ChangeInputLanguage();
static void ChangeInputLanguageWorker();
LRESULT WMInputLanguage(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
LRESULT WMStartComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
LRESULT WMComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
LRESULT WMEndComposition(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
LRESULT WMNotify(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
LRESULT WMChar(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
protected:
void IncCurPos();
void DecCurPos();
void SetCurPos(int offset);
void DelCurPos();
protected:
static void CheckInputLocale();
static void CheckToggleState();
static void SetSupportLevel( DWORD dwImeLevel );
void InsertString(wchar_t* szString, int iSize);
void OnChar(wchar_t c);
UINT GetCodePageFromLang( LANGID langid );
void ResultProcess(HIMC hImc);
void CompositionProcessBuilding(HIMC hImc);
void CompositionProcess(HIMC hImc);
void AttributeProcess(HIMC hImc);
void CandidateProcess(HIMC hImc);
void ReadingProcess(HIMC hImc);
bool IsMax(const wchar_t* wInput, int len);
DWORD GetImeId(UINT uIndex = 0);
bool GetReadingWindowOrientation();
static void SetupImeApi();
static INPUTCONTEXT* (WINAPI * _ImmLockIMC)( HIMC );
static BOOL (WINAPI * _ImmUnlockIMC)( HIMC );
static LPVOID (WINAPI * _ImmLockIMCC)( HIMCC );
static BOOL (WINAPI * _ImmUnlockIMCC)( HIMCC );
static UINT (WINAPI * _GetReadingString)( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT );
static BOOL (WINAPI * _ShowReadingWindow)( HIMC, BOOL );
protected:
HIMC m_hOrgIMC;
int m_max;
int m_userMax;
BOOL m_bOnlyNumberMode;
std::vector<wchar_t> m_exceptKey;
bool m_bEnablePaste;
bool m_bUseDefaultIME;
public:
static bool ms_bInitialized;
static bool ms_bDisableIMECompletely;
static bool ms_bUILessMode;
static bool ms_bImeEnabled;
static bool ms_bCaptureInput;
static bool ms_bChineseIME;
static bool ms_bUseIMMCandidate;
static HWND ms_hWnd;
static HKL ms_hklCurrent;
static char ms_szKeyboardLayout[KL_NAMELENGTH+1];
static OSVERSIONINFOA ms_stOSVI;
static HINSTANCE ms_hImm32Dll;
static HINSTANCE ms_hCurrentImeDll;
static DWORD ms_dwImeState;
static DWORD ms_adwId[2];
// IME Level
static DWORD ms_dwIMELevel;
static DWORD ms_dwIMELevelSaved;
// Candidate List
static bool ms_bCandidateList;
static DWORD ms_dwCandidateCount;
static bool ms_bVerticalCandidate;
static int ms_iCandListIndexBase;
static WCHAR ms_wszCandidate[CIME::MAX_CANDLIST][MAX_CANDIDATE_LENGTH];
static DWORD ms_dwCandidateSelection;
static DWORD ms_dwCandidatePageSize;
// Reading Information
static bool ms_bReadingInformation;
static int ms_iReadingError;
static bool ms_bHorizontalReading;
static std::vector<wchar_t> ms_wstrReading;
// Indicator
static wchar_t* ms_wszCurrentIndicator;
static IIMEEventSink* ms_pEvent;
wchar_t m_wszComposition[IMESTR_MAXLEN];
static wchar_t m_wText[IMESTR_MAXLEN];
static int ms_compLen;
static int ms_curpos;
static int ms_lastpos;
static int ms_ulbegin;
static int ms_ulend;
static UINT ms_uOutputCodePage;
static UINT ms_uInputCodePage;
};
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
#endif
class CInputDevice
{
public:
CInputDevice();
virtual ~CInputDevice();
HRESULT CreateDevice(HWND hWnd);
protected:
static LPDIRECTINPUT8 ms_lpDI;
};
class CInputKeyboard : public CInputDevice
{
public:
CInputKeyboard();
virtual ~CInputKeyboard();
bool InitializeKeyboard(HWND hWnd);
void UpdateKeyboard();
void ResetKeyboard();
bool IsPressed(int iIndex);
void KeyDown(int iIndex);
void KeyUp(int iIndex);
protected:
virtual void OnKeyDown(int iIndex) = 0;
virtual void OnKeyUp(int iIndex) = 0;
protected:
static LPDIRECTINPUTDEVICE8 ms_lpKeyboard;
static bool ms_bPressedKey[256];
static char ms_diks[256];
};
+599
View File
@@ -0,0 +1,599 @@
///////////////////////////////////////////////////////////////////////
// CLensFlare Class
//
// (c) 2003 IDV, Inc.
//
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
//
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Interactive Data Visualization and may
// not be copied or disclosed except in accordance with the terms of
// that agreement.
//
// Copyright (c) 2001-2003 IDV, Inc.
// All Rights Reserved.
//
// IDV, Inc.
// 1233 Washington St. Suite 610
// Columbia, SC 29201
// Voice: (803) 799-1699
// Fax: (803) 931-0320
// Web: http://www.idvinc.com
//
///////////////////////////////////////////////////////////////////////
// Preprocessor
#include "StdAfx.h"
#include "LensFlare.h"
#include "Camera.h"
#include "StateManager.h"
#include "ResourceManager.h"
#include <math.h>
using namespace std;
///////////////////////////////////////////////////////////////////////
// Variables
static string g_strFiles[] =
{
"flare2.dds",
"flare1.dds",
"flare2.dds",
"flare1.dds",
"flare6.dds",
"flare4.dds",
"flare2.dds",
"flare3.dds",
""
};
static float g_fPosition[] =
{
-0.55f,
-0.5f,
-0.45f,
0.2f,
0.3f,
0.95f,
0.9f,
1.0f
};
static float g_fWidth[] =
{
20.0f,
32.0f,
20.0f,
32.0f,
100.0f,
32.0f,
20.0f,
250.0f
};
static float g_afColors[ ][4] =
{
{ 1.0f, 1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f, 1.0f },
{ 0.0f, 1.0f, 0.0f, 0.8f },
{ 0.3f, 0.5f, 1.0f, 0.9f },
{ 0.3f, 0.5f, 1.0f, 0.6f },
{ 1.0f, 0.6f, 0.9f, 0.4f },
{ 1.0f, 0.0f, 0.0f, 0.5f },
{ 1.0f, 0.6f, 0.3f, 0.4f }
};
///////////////////////////////////////////////////////////////////////
// CLensFlare::CLensFlare
CLensFlare::CLensFlare() :
m_fSunSize(0),
m_fBeforeBright(0.0f),
m_fAfterBright(0.0f),
m_bFlareVisible(false),
m_bDrawFlare(true),
m_bDrawBrightScreen(true),
m_bEnabled(true),
m_bShowMainFlare(true),
m_fMaxBrightness(1.0f)
{
m_pControlPixels = new float[c_nDepthTestDimension * c_nDepthTestDimension];
m_pTestPixels = new float[c_nDepthTestDimension * c_nDepthTestDimension];
m_afColor[0] = m_afColor[1] = m_afColor[2] = 1.0f;
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::~CLensFlare
CLensFlare::~CLensFlare()
{
delete[] m_pControlPixels;
delete[] m_pTestPixels;
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::Interpolate
float CLensFlare::Interpolate(float fStart, float fEnd, float fPercent)
{
return fStart + (fEnd - fStart) * fPercent;
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::DrawBeforeFlare
void CLensFlare::Compute(const D3DXVECTOR3 & c_rv3LightDirection)
{
float afSunPos[3];
D3DXVECTOR3 v3Target = CCameraManager::Instance().GetCurrentCamera()->GetTarget();
afSunPos[0] = v3Target.x - c_rv3LightDirection.x * 99999999.0f;
afSunPos[1] = v3Target.y - c_rv3LightDirection.y * 99999999.0f;
afSunPos[2] = v3Target.z - c_rv3LightDirection.z * 99999999.0f;
float fX, fY;
ProjectPosition(afSunPos[0], afSunPos[1], afSunPos[2], &fX, &fY);
// set flare location
SetFlareLocation(fX, fY);
// determine visibility
float fSunVectorMagnitude = sqrtf(afSunPos[0] * afSunPos[0] +
afSunPos[1] * afSunPos[1] +
afSunPos[2] * afSunPos[2]);
float afSunVector[3];
afSunVector[0] = -afSunPos[0] / fSunVectorMagnitude;
afSunVector[1] = -afSunPos[1] / fSunVectorMagnitude;
afSunVector[2] = -afSunPos[2] / fSunVectorMagnitude;
float afCameraDirection[3];
afCameraDirection[0] = ms_matView._13;
afCameraDirection[1] = ms_matView._23;
afCameraDirection[2] = ms_matView._33;
float fDotProduct =
(afSunVector[0] * afCameraDirection[0]) +
(afSunVector[1] * afCameraDirection[1]) +
(afSunVector[2] * afCameraDirection[2]);
if (acosf(fDotProduct) < 0.5f * D3DX_PI)
SetVisible(true);
else
SetVisible(false);
// set flare brightness
fX /= ms_Viewport.Width;
fY /= ms_Viewport.Height;
float fDistance = sqrtf(((0.5f - fX) * (0.5f - fX)) + ((0.5f - fY) * (0.5f - fY)));
float fBeforeBright = Interpolate(0.0f, c_fHalfMaxBright, 1.0f - (fDistance * c_fDistanceScale));
float fAfterBright = Interpolate(0.0f, 1.0f, 1.0f - (fDistance * c_fDistanceScale));
SetBrightnesses(fBeforeBright, fAfterBright);
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::DrawBeforeFlare
void CLensFlare::DrawBeforeFlare()
{
if (!m_bFlareVisible || !m_bEnabled || !m_bShowMainFlare)
return;
if (m_SunFlareImageInstance.IsEmpty())
return;
D3DXMATRIX matProj;
D3DXMatrixOrthoOffCenterRH(&matProj, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f);
STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProj);
STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity);
D3DXMATRIX matWorld;
D3DXMatrixTranslation(&matWorld, m_afFlarePos[0], m_afFlarePos[1], 0.0f);
STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld);
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); // glDisable(GL_DEPTH_TEST);
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // glDisable(GL_CULL_FACE);
STATEMANAGER.SaveRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); // glShadeModel(GL_FLAT);
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); // glDisable(GL_ALPHA_TEST);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // glEnable(GL_BLEND);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
/*
if (m_fBeforeBright != 0.0f && m_bDrawFlare && m_bDrawBrightScreen && false) // 왠 false?
{
glColor4f(1.0f, 1.0f, 1.0f, m_fBeforeBright);
glDisable(GL_TEXTURE_2D);
glBegin(GL_TRIANGLE_STRIP);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.0f, 1.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glEnd();
}
*/
float fAspectRatio = ms_Viewport.Width / float(ms_Viewport.Height);
float fHeight = m_fSunSize * fAspectRatio;
D3DXCOLOR color(1.0f, 1.0f, 1.0f, 1.0f);
SVertex vertices[4];
vertices[0].x = -m_fSunSize;
vertices[0].y = -fHeight;
vertices[0].z = 0.0f;
vertices[0].color = color;
vertices[0].u = 0.0f;
vertices[0].v = 0.0f;
vertices[1].x = -m_fSunSize;
vertices[1].y = fHeight;
vertices[1].z = 0.0f;
vertices[1].color = color;
vertices[1].u = 0.0f;
vertices[1].v = 1.0f;
vertices[2].x = m_fSunSize;
vertices[2].y = -fHeight;
vertices[2].z = 0.0f;
vertices[2].color = color;
vertices[2].u = 1.0f;
vertices[2].v = 0.0f;
vertices[3].x = m_fSunSize;
vertices[3].y = fHeight;
vertices[3].z = 0.0f;
vertices[3].color = color;
vertices[3].u = 1.0f;
vertices[3].v = 1.0f;
STATEMANAGER.SetTexture(0, m_SunFlareImageInstance.GetTexturePointer()->GetD3DTexture());
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(SVertex));
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); // glDisable(GL_DEPTH_TEST);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); // glDisable(GL_CULL_FACE);
STATEMANAGER.RestoreRenderState(D3DRS_SHADEMODE); // glShadeModel(GL_FLAT);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); // glDisable(GL_ALPHA_TEST);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); // glEnable(GL_BLEND);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
STATEMANAGER.RestoreTransform(D3DTS_VIEW);
STATEMANAGER.RestoreTransform(D3DTS_PROJECTION);
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::DrawAfterFlare
void CLensFlare::DrawAfterFlare()
{
if (m_bEnabled && m_fAfterBright != 0.0f && m_bDrawBrightScreen)
{
SetDiffuseColor(m_afColor[0], m_afColor[1], m_afColor[2], m_fAfterBright);
RenderBar2d(0.0f, 0.0f, 1024.0f, 1024.0f);
}
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::SetMainFlare
void CLensFlare::SetMainFlare(string strSunFile, float fSunSize)
{
if (m_bEnabled && m_bShowMainFlare)
{
m_fSunSize = fSunSize;
CResource * pResource = CResourceManager::Instance().GetResourcePointer(strSunFile.c_str());
if (!pResource->IsType(CGraphicImage::Type()))
assert(false);
m_SunFlareImageInstance.SetImagePointer(static_cast<CGraphicImage *> (pResource));
}
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::DrawFlare
void CLensFlare::DrawFlare()
{
if (m_bEnabled && m_bFlareVisible && m_bDrawFlare && m_fAfterBright != 0.0f)
{
//glPushAttrib(GL_ENABLE_BIT);
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE); // glDisable(GL_LIGHTING);
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE); // glDisable(GL_DEPTH_TEST);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // glDisable(GL_CULL_FACE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE); // glDisable(GL_ALPHA_TEST);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // glEnable(GL_BLEND);
D3DXMATRIX matProj;
D3DXMatrixOrthoOffCenterRH(&matProj, 0.0f, ms_Viewport.Width, ms_Viewport.Height, 0.0f, -1.0f, 1.0f);
STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProj);
STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity);
STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity);
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
//glDisable(GL_TEXTURE_2D);
DrawAfterFlare();
//glEnable(GL_TEXTURE_2D);
m_cFlare.Draw(m_fAfterBright,
ms_Viewport.Width,
ms_Viewport.Height,
static_cast<int>(m_afFlareWinPos[0]),
static_cast<int>(m_afFlareWinPos[1]));
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING); // glDisable(GL_LIGHTING);
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE); // glDisable(GL_DEPTH_TEST);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); // glDisable(GL_CULL_FACE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); // glEnable(GL_BLEND);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); // glDisable(GL_ALPHA_TEST);
STATEMANAGER.RestoreTransform(D3DTS_PROJECTION);
STATEMANAGER.RestoreTransform(D3DTS_VIEW);
//glDisable(GL_TEXTURE_2D);
//glPopAttrib();
}
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::CharacterizeFlare
void CLensFlare::CharacterizeFlare(bool bEnabled, bool bShowMainFlare, float fMaxBrightness, const D3DXCOLOR & c_rColor)
{
m_bEnabled = bEnabled;
m_bShowMainFlare = bShowMainFlare;
m_fMaxBrightness = fMaxBrightness;
m_afColor[0] = c_rColor.r;
m_afColor[1] = c_rColor.g;
m_afColor[2] = c_rColor.b;
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::Initialize
void CLensFlare::Initialize(std::string strPath)
{
if (m_bEnabled)
m_cFlare.Init(strPath);
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::SetFlareLocation
void CLensFlare::SetFlareLocation(double dX, double dY)
{
if (m_bEnabled)
{
m_afFlareWinPos[0] = float(dX);
m_afFlareWinPos[1] = float(dY);
m_afFlarePos[0] = float(dX) / ms_Viewport.Width;
m_afFlarePos[1] = float(dY) / ms_Viewport.Height;
}
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::SetBrightnesses
void CLensFlare::SetBrightnesses(float fBeforeBright, float fAfterBright)
{
if (m_bEnabled)
{
m_fBeforeBright = fBeforeBright;
m_fAfterBright = fAfterBright;
ClampBrightness();
}
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::ReadControlPixels
void CLensFlare::ReadControlPixels()
{
if (m_bEnabled)
ReadDepthPixels(m_pControlPixels);
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::AdjustBrightness
void CLensFlare::AdjustBrightness()
{
if (m_bEnabled)
{
ReadDepthPixels(m_pTestPixels);
int nDifferent = 0;
for (int i = 0; i < c_nDepthTestDimension * c_nDepthTestDimension; ++i)
if (m_pTestPixels[i] != m_pControlPixels[i])
++nDifferent;
float fAdjust = (static_cast<float>(nDifferent) / (c_nDepthTestDimension * c_nDepthTestDimension));
fAdjust = sqrtf(fAdjust) * 0.85f;
m_fAfterBright *= 1.0f - fAdjust;
}
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::ReadDepthPixels
void CLensFlare::ReadDepthPixels(float * /*pPixels*/)
{
/*
LPDIRECT3DSURFACE8 lpSurface;
if (FAILED(ms_lpd3dDevice->GetDepthStencilSurface(&lpSurface)))
assert(false);
D3DLOCKED_RECT rect;
lpSurface->LockRect(&rect, NULL, D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE);
lpSurface->UnlockRect();
*/
/*
glReadPixels(GLint(m_afFlareWinPos[0] - c_nDepthTestDimension / 2),
GLint(m_afFlareWinPos[1] - c_nDepthTestDimension / 2),
c_nDepthTestDimension, c_nDepthTestDimension,
GL_DEPTH_COMPONENT, GL_FLOAT, pPixels);
*/
}
///////////////////////////////////////////////////////////////////////
// CLensFlare::ClampBrightness
void CLensFlare::ClampBrightness()
{
// before
if (m_fBeforeBright < 0.0f)
m_fBeforeBright = 0.0f;
else if (m_fBeforeBright > 1.0f)
m_fBeforeBright = 1.0f;
m_fBeforeBright *= m_fMaxBrightness;
if (m_fAfterBright < 0.0f)
m_fAfterBright = 0.0f;
else if (m_fAfterBright > 1.0f)
m_fAfterBright = 1.0f;
m_fAfterBright *= m_fMaxBrightness;
}
///////////////////////////////////////////////////////////////////////
// CFlare implementation
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// CFlare::CFlare
CFlare::CFlare()
{
}
///////////////////////////////////////////////////////////////////////
// CFlare::~CFlare
CFlare::~CFlare()
{
}
///////////////////////////////////////////////////////////////////////
// CFlare::Init
void CFlare::Init(std::string strPath)
{
int i = 0;
while (g_strFiles[i] != "")
{
CResource * pResource = CResourceManager::Instance().GetResourcePointer((strPath + "/" + string(g_strFiles[i])).c_str());
if (!pResource->IsType(CGraphicImage::Type()))
assert(false);
SFlarePiece * pPiece = new SFlarePiece;
pPiece->m_imageInstance.SetImagePointer(static_cast<CGraphicImage *> (pResource));
pPiece->m_fPosition = g_fPosition[i];
pPiece->m_fWidth = g_fWidth[i];
pPiece->m_pColor = g_afColors[i];
m_vFlares.push_back(pPiece);
i++;
}
}
///////////////////////////////////////////////////////////////////////
// CFlare::Draw
void CFlare::Draw(float fBrightScale, int nWidth, int nHeight, int nX, int nY)
{
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
float fDX = float(nX) - float(nWidth) / 2.0f;
float fDY = float(nY) - float(nHeight) / 2.0f;
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
for (unsigned int i = 0; i < m_vFlares.size(); i++)
{
float fCenterX = float(nX) - (m_vFlares[i]->m_fPosition + 1.0f) * fDX;
float fCenterY = float(nY) - (m_vFlares[i]->m_fPosition + 1.0f) * fDY;
float fW = m_vFlares[i]->m_fWidth;
D3DXCOLOR d3dColor(m_vFlares[i]->m_pColor[0] * fBrightScale,
m_vFlares[i]->m_pColor[1] * fBrightScale,
m_vFlares[i]->m_pColor[2] * fBrightScale,
m_vFlares[i]->m_pColor[3] * fBrightScale);
STATEMANAGER.SetTexture(0, m_vFlares[i]->m_imageInstance.GetTexturePointer()->GetD3DTexture());
TVertex vertices[4];
vertices[0].u = 0.0f;
vertices[0].v = 0.0f;
vertices[0].x = fCenterX - fW;
vertices[0].y = fCenterY - fW;
vertices[0].z = 0.0f;
vertices[0].color = d3dColor;
vertices[1].u = 0.0f;
vertices[1].v = 1.0f;
vertices[1].x = fCenterX - fW;
vertices[1].y = fCenterY + fW;
vertices[1].z = 0.0f;
vertices[1].color = d3dColor;
vertices[2].u = 1.0f;
vertices[2].v = 0.0f;
vertices[2].x = fCenterX + fW;
vertices[2].y = fCenterY - fW;
vertices[2].z = 0.0f;
vertices[2].color = d3dColor;
vertices[3].u = 1.0f;
vertices[3].v = 1.0f;
vertices[3].x = fCenterX + fW;
vertices[3].y = fCenterY + fW;
vertices[3].z = 0.0f;
vertices[3].color = d3dColor;
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(TVertex));
}
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
}
+125
View File
@@ -0,0 +1,125 @@
///////////////////////////////////////////////////////////////////////
// CLensFlare Class
//
// (c) 2003 IDV, Inc.
//
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
//
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Interactive Data Visualization and may
// not be copied or disclosed except in accordance with the terms of
// that agreement.
//
// Copyright (c) 2001-2003 IDV, Inc.
// All Rights Reserved.
//
// IDV, Inc.
// 1233 Washington St. Suite 610
// Columbia, SC 29201
// Voice: (803) 799-1699
// Fax: (803) 931-0320
// Web: http://www.idvinc.com
//
///////////////////////////////////////////////////////////////////////
// Preprocessor
#pragma once
#include "GrpImageInstance.h"
#include "GrpScreen.h"
#include <float.h>
#include <string>
#include <vector>
///////////////////////////////////////////////////////////////////////
// Constants
const float c_fHalfMaxBright = 0.45f;
const float c_fDistanceScale = 1.0f;
const int c_nDepthTestDimension = 15;
///////////////////////////////////////////////////////////////////////
// CFlare
class CFlare
{
public:
void Draw(float fBrightScale, int nWidth, int nHeight, int nX, int nY);
void Init(std::string strPath);
CFlare();
virtual ~CFlare();
private:
struct SFlarePiece
{
SFlarePiece() :
m_fPosition(0.0f),
m_fWidth(0.0f),
m_pColor(NULL)
{
}
CGraphicImageInstance m_imageInstance;
float m_fPosition; // -1.0 = light location, 0.0 = center, 1.0 = far end of flare
float m_fWidth; // height = width
float * m_pColor;
};
std::vector<SFlarePiece *> m_vFlares;
};
///////////////////////////////////////////////////////////////////////
// CLensFlare
class CLensFlare : public CScreen
{
public:
CLensFlare();
virtual ~CLensFlare();
void Compute(const D3DXVECTOR3 & c_rv3LightDirection); // D3DTS_VIEW로 부터 카메라 방향을 얻어오므로, 카메라 설정 뒤에 해야 함.
void DrawBeforeFlare();
void DrawAfterFlare();
void DrawFlare();
void SetMainFlare(std::string strSunFile, float fSunSize);
void Initialize(std::string strPath);
void SetFlareLocation(double dX, double dY);
void SetVisible(bool bState) { m_bFlareVisible = bState; }
bool IsVisible() { return m_bFlareVisible; }
void SetBrightnesses(float fBeforeBright, float fAfterBright);
void ReadControlPixels();
void AdjustBrightness();
void CharacterizeFlare(bool bEnabled, bool bShowMainFlare, float fMaxBrightness, const D3DXCOLOR & c_rColor);
protected:
float Interpolate(float fStart, float fEnd, float fPercent);
private:
float m_afFlarePos[2], m_afFlareWinPos[2];
float m_fBeforeBright, m_fAfterBright;
bool m_bFlareVisible, m_bDrawFlare, m_bDrawBrightScreen;
float m_fSunSize;
CFlare m_cFlare;
float * m_pControlPixels;
float * m_pTestPixels;
bool m_bEnabled;
bool m_bShowMainFlare;
float m_fMaxBrightness;
float m_afColor[4];
CGraphicImageInstance m_SunFlareImageInstance;
void ReadDepthPixels(float * pPixels);
void ClampBrightness();
};
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "MSWindow.h"
class CMSApplication : public CMSWindow
{
public:
CMSApplication();
virtual ~CMSApplication();
void Initialize(HINSTANCE hInstance);
void MessageLoop();
bool IsMessage();
bool MessageProcess();
protected:
void ClearWindowClass();
LRESULT WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
};
+59
View File
@@ -0,0 +1,59 @@
#pragma once
#include "../EterBase/Stl.h"
class CMSWindow
{
public:
CMSWindow();
virtual ~CMSWindow();
void Destroy();
bool Create(const char* c_szName, int brush=BLACK_BRUSH, DWORD cs=0, DWORD ws=WS_OVERLAPPEDWINDOW, HICON hIcon=NULL, int iCursorResource=32512);
void Show();
void Hide();
void SetVisibleMode(bool isVisible);
void SetPosition(int x, int y);
void SetCenterPosition();
void SetText(const char* c_szText);
void AdjustSize(int width, int height);
void SetSize(int width, int height);
bool IsVisible();
bool IsActive();
void GetMousePosition(POINT* ppt);
void GetClientRect(RECT* prc);
void GetWindowRect(RECT* prc);
int GetScreenWidth();
int GetScreenHeight();
HWND GetWindowHandle();
HINSTANCE GetInstance();
virtual LRESULT WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
virtual void OnSize(WPARAM wParam, LPARAM lParam);
protected:
const char* RegisterWindowClass(DWORD style, int brush, WNDPROC pfnWndProc, HICON hIcon=NULL, int iCursorResource=32512);
protected:
typedef std::set<char*, stl_sz_less> TWindowClassSet;
protected:
HWND m_hWnd;
RECT m_rect;
bool m_isActive;
bool m_isVisible;
protected:
static TWindowClassSet ms_stWCSet;
static HINSTANCE ms_hInstance;
};
+18
View File
@@ -0,0 +1,18 @@
#ifndef __INC_ETERLIB_MUTEX_H__
#define __INC_ETERLIB_MUTEX_H__
class Mutex
{
public:
Mutex();
~Mutex();
void Lock();
void Unlock();
bool Trylock();
private:
CRITICAL_SECTION lock;
};
#endif
+107
View File
@@ -0,0 +1,107 @@
#include "StdAfx.h"
#include "NetAddress.h"
#ifndef VC_EXTRALEAN
bool CNetworkAddress::GetHostName(char* szName, int size)
{
if (gethostname(szName, size)==SOCKET_ERROR)
return false;
return true;
}
CNetworkAddress::CNetworkAddress()
{
Clear();
}
CNetworkAddress::~CNetworkAddress()
{
}
CNetworkAddress::operator const SOCKADDR_IN&() const
{
return m_sockAddrIn;
}
void CNetworkAddress::Clear()
{
memset(&m_sockAddrIn, 0, sizeof(m_sockAddrIn));
m_sockAddrIn.sin_family=AF_INET;
}
bool CNetworkAddress::IsIP(const char* c_szAddr)
{
if (c_szAddr[0]<'0' || c_szAddr[0]>'9')
return false;
return true;
}
bool CNetworkAddress::Set(const char* c_szAddr, int port)
{
if (IsIP(c_szAddr))
{
SetIP(c_szAddr);
}
else
{
if (!SetDNS(c_szAddr))
return false;
}
SetPort(port);
return true;
}
void CNetworkAddress::SetLocalIP()
{
SetIP(INADDR_ANY);
}
void CNetworkAddress::SetIP(DWORD ip)
{
m_sockAddrIn.sin_addr.s_addr=htonl(ip);
}
void CNetworkAddress::SetIP(const char* c_szIP)
{
m_sockAddrIn.sin_addr.s_addr=inet_addr(c_szIP);
}
bool CNetworkAddress::SetDNS(const char* c_szDNS)
{
HOSTENT* pHostent=gethostbyname(c_szDNS);
if (!pHostent) return false;
memcpy(&m_sockAddrIn.sin_addr, pHostent->h_addr, sizeof(m_sockAddrIn.sin_addr));
return true;
}
void CNetworkAddress::SetPort(int port)
{
m_sockAddrIn.sin_port = htons(port);
}
int CNetworkAddress::GetSize()
{
return sizeof(m_sockAddrIn);
}
DWORD CNetworkAddress::GetIP()
{
return ntohl(m_sockAddrIn.sin_addr.s_addr);
}
void CNetworkAddress::GetIP(char* szIP, int len)
{
BYTE IPs[4];
*((DWORD*)IPs)=m_sockAddrIn.sin_addr.s_addr;
_snprintf(szIP, len, "%d.%d.%d.%d", IPs[0], IPs[1], IPs[2], IPs[3]);
}
int CNetworkAddress::GetPort()
{
return ntohs(m_sockAddrIn.sin_port);
}
#endif
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#ifndef VC_EXTRALEAN
class CNetworkAddress
{
public:
static bool GetHostName(char* szName, int size);
public:
CNetworkAddress();
~CNetworkAddress();
void Clear();
bool Set(const char* c_szAddr, int port);
void SetLocalIP();
void SetIP(DWORD ip);
void SetIP(const char* c_szIP);
bool SetDNS(const char* c_szDNS);
void SetPort(int port);
int GetPort();
int GetSize();
void GetIP(char* szIP, int len);
DWORD GetIP();
operator const SOCKADDR_IN&() const;
private:
bool IsIP(const char* c_szAddr);
private:
SOCKADDR_IN m_sockAddrIn;
};
#endif
+99
View File
@@ -0,0 +1,99 @@
#include "StdAfx.h"
#include "NetDatagram.h"
CNetworkDatagram::CNetworkDatagram()
{
__Initialize();
}
CNetworkDatagram::~CNetworkDatagram()
{
Destroy();
}
void CNetworkDatagram::Destroy()
{
if (INVALID_SOCKET==m_sock)
return;
closesocket(m_sock);
__Initialize();
}
bool CNetworkDatagram::Create(UINT uPort)
{
assert(INVALID_SOCKET==m_sock);
m_sock = socket(AF_INET, SOCK_DGRAM, 0);
DWORD arg = 1;
ioctlsocket(m_sock, FIONBIO, &arg); // Non-blocking mode
SOCKADDR_IN sockAddrIn;
memset(&sockAddrIn, 0, sizeof(SOCKADDR_IN));
sockAddrIn.sin_family = AF_INET;
sockAddrIn.sin_addr.s_addr = INADDR_ANY;
sockAddrIn.sin_port = htons(uPort);
if (SOCKET_ERROR == bind(m_sock, (PSOCKADDR)&sockAddrIn, sizeof(SOCKADDR_IN)))
{
return false;
}
return true;
}
#pragma warning(push)
#pragma warning(disable:4127)
void CNetworkDatagram::Update()
{
if (m_sock == INVALID_SOCKET)
return;
FD_ZERO(&m_fdsRecv);
FD_ZERO(&m_fdsSend);
FD_SET(m_sock, &m_fdsRecv);
FD_SET(m_sock, &m_fdsSend);
TIMEVAL delay;
delay.tv_sec = 0;
delay.tv_usec = 0;
if (select(0, &m_fdsRecv, &m_fdsSend, NULL, &delay) == SOCKET_ERROR)
return;
}
#pragma warning(pop)
bool CNetworkDatagram::CanRecv()
{
if (FD_ISSET(m_sock, &m_fdsRecv))
return true;
return false;
}
int CNetworkDatagram::PeekRecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn)
{
int nSockAddrInLen=sizeof(SOCKADDR_IN);
return recvfrom(m_sock, (char*)pvBuf, uBufLen, MSG_PEEK, (PSOCKADDR)pkSockAddrIn, &nSockAddrInLen);
}
int CNetworkDatagram::RecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn)
{
int nSockAddrInLen=sizeof(SOCKADDR_IN);
return recvfrom(m_sock, (char*)pvBuf, uBufLen, 0, (PSOCKADDR)pkSockAddrIn, &nSockAddrInLen);
}
int CNetworkDatagram::SendTo(UINT uBufLen, const void* c_pvBuf, const SOCKADDR_IN& c_rkSockAddrIn)
{
return sendto(m_sock, (const char *)c_pvBuf, uBufLen, 0, (PSOCKADDR)&c_rkSockAddrIn, sizeof(SOCKADDR_IN));
}
void CNetworkDatagram::__Initialize()
{
m_sock=INVALID_SOCKET;
}
+28
View File
@@ -0,0 +1,28 @@
#pragma once
class CNetworkDatagram
{
public:
CNetworkDatagram();
virtual ~CNetworkDatagram();
void Destroy();
bool Create(UINT uPort);
void Update();
bool CanRecv();
int PeekRecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn);
int RecvFrom(UINT uBufLen, void* pvBuf, SOCKADDR_IN* pkSockAddrIn);
int SendTo(UINT uBufLen, const void* c_pvBuf, const SOCKADDR_IN& c_rkSockAddrIn);
private:
void __Initialize();
private:
SOCKET m_sock;
fd_set m_fdsRecv;
fd_set m_fdsSend;
};
+105
View File
@@ -0,0 +1,105 @@
#include "StdAfx.h"
#include "NetDatagramReceiver.h"
BOOL CNetDatagramReceiver::Process()
{
m_recvBufCurrentPos = 0;
m_recvBufCurrentSize = 0;
int irecvAddrLength = sizeof(SOCKADDR_IN);
m_recvBufCurrentSize = recvfrom(m_Socket, (char *)m_recvBuf, m_recvBufSize, 0, (PSOCKADDR)&m_SockAddr, &irecvAddrLength);
if (m_recvBufCurrentSize <= 0)
{
return FALSE;
}
return TRUE;
}
BOOL CNetDatagramReceiver::Recv(void * pBuffer, int iSize)
{
if (!Peek(pBuffer, iSize))
return FALSE;
m_recvBufCurrentPos += iSize;
return TRUE;
}
BOOL CNetDatagramReceiver::Peek(void * pBuffer, int iSize)
{
if (m_recvBufCurrentSize < m_recvBufCurrentPos+iSize)
return FALSE;
memcpy(pBuffer, m_recvBuf + m_recvBufCurrentPos, iSize);
return TRUE;
}
BOOL CNetDatagramReceiver::isBind()
{
return m_isBind;
}
BOOL CNetDatagramReceiver::Bind(DWORD /*dwAddress*/, WORD wPortIndex)
{
m_Socket = socket(AF_INET, SOCK_DGRAM, 0);
DWORD arg = 1;
ioctlsocket(m_Socket, FIONBIO, &arg); // Non-blocking mode
memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));
m_SockAddr.sin_family = AF_INET;
// m_SockAddr.sin_addr.s_addr = dwAddress;
m_SockAddr.sin_addr.s_addr = INADDR_ANY;
m_SockAddr.sin_port = htons(wPortIndex);
if (bind(m_Socket, (PSOCKADDR)&m_SockAddr, sizeof(SOCKADDR_IN)) < 0)
{
Tracef("Failed binding socket\n");
return FALSE;
}
m_isBind = TRUE;
return TRUE;
}
void CNetDatagramReceiver::SetRecvBufferSize(int recvBufSize)
{
if (m_recvBuf)
{
if (m_recvBufSize>recvBufSize)
return;
delete [] m_recvBuf;
}
m_recvBufSize=recvBufSize;
m_recvBuf=new char[m_recvBufSize];
}
void CNetDatagramReceiver::Clear()
{
m_isBind = FALSE;
m_dwPortIndex = 1000;
m_Socket = 0;
memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));
m_recvBufCurrentPos = 0;
m_recvBufCurrentSize = 0;
}
CNetDatagramReceiver::CNetDatagramReceiver()
{
m_recvBuf = NULL;
m_recvBufSize = 0;
Clear();
}
CNetDatagramReceiver::~CNetDatagramReceiver()
{
if (m_recvBuf)
delete [] m_recvBuf;
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#ifndef VC_EXTRALEAN
class CNetDatagramReceiver
{
public:
CNetDatagramReceiver();
virtual ~CNetDatagramReceiver();
void Clear();
BOOL Bind(DWORD dwAddress, WORD wPortIndex);
BOOL isBind();
BOOL Process();
BOOL Recv(void * pBuffer, int iSize);
BOOL Peek(void * pBuffer, int iSize);
void SetRecvBufferSize(int recvBufSize);
protected:
BOOL m_isBind;
DWORD m_dwPortIndex;
SOCKET m_Socket;
SOCKADDR_IN m_SockAddr;
int m_recvBufCurrentPos;
int m_recvBufCurrentSize;
char* m_recvBuf;
int m_recvBufSize;
};
#endif
+58
View File
@@ -0,0 +1,58 @@
#include "StdAfx.h"
#include "NetDatagramSender.h"
BOOL CNetDatagramSender::SetSocket(const char * c_szIP, WORD wPortIndex)
{
return SetSocket(inet_addr(c_szIP), wPortIndex);
}
BOOL CNetDatagramSender::SetSocket(DWORD dwAddress, WORD wPortIndex)
{
m_isSocket = TRUE;
m_dwAddress = dwAddress;
m_wPortIndex = wPortIndex;
m_Socket = socket(AF_INET, SOCK_DGRAM, 0);
memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));
m_SockAddr.sin_family = AF_INET;
m_SockAddr.sin_addr.s_addr = dwAddress;
m_SockAddr.sin_port = htons(wPortIndex);
return TRUE;
}
BOOL CNetDatagramSender::Send(const void * pBuffer, int iSize)
{
assert(isSocket());
int iSendingLength = sendto(m_Socket, (const char *)pBuffer, iSize, 0, (PSOCKADDR)&m_SockAddr, sizeof(SOCKADDR_IN));
if (iSendingLength < 0)
{
Tracef("Failed sending packet\n");
return FALSE;
}
return TRUE;
}
BOOL CNetDatagramSender::isSocket()
{
return m_isSocket;
}
CNetDatagramSender::CNetDatagramSender()
{
m_isSocket = FALSE;
m_dwAddress = 0;
m_wPortIndex = 1000;
m_Socket = 0;
memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));
}
CNetDatagramSender::~CNetDatagramSender()
{
}
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#ifndef VC_EXTRALEAN
class CNetDatagramSender
{
public:
CNetDatagramSender();
virtual ~CNetDatagramSender();
BOOL isSocket();
BOOL SetSocket(const char * c_szIP, WORD wPortIndex);
BOOL SetSocket(DWORD dwAddress, WORD wPortIndex);
BOOL Send(const void * pBuffer, int iSize);
protected:
BOOL m_isSocket;
WORD m_dwAddress;
WORD m_wPortIndex;
SOCKET m_Socket;
SOCKADDR_IN m_SockAddr;
};
#endif
+41
View File
@@ -0,0 +1,41 @@
#include "StdAfx.h"
#include "NetDevice.h"
CNetworkDevice::CNetworkDevice()
{
Initialize();
}
CNetworkDevice::~CNetworkDevice()
{
Destroy();
}
void CNetworkDevice::Initialize()
{
m_isWSA=false;
}
void CNetworkDevice::Destroy()
{
if (m_isWSA)
{
WSACleanup();
m_isWSA=false;
}
}
bool CNetworkDevice::Create()
{
Destroy();
Initialize();
WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData)!=0)
return false;
m_isWSA=true;
return true;
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
class CNetworkDevice
{
public:
CNetworkDevice();
virtual ~CNetworkDevice();
void Destroy();
bool Create();
protected:
void Initialize();
protected:
bool m_isWSA;
};
+26
View File
@@ -0,0 +1,26 @@
#include "StdAfx.h"
#include "NetPacketHeaderMap.h"
void CNetworkPacketHeaderMap::Set(int header, TPacketType rPacketType)
{
m_headerMap[header] = rPacketType;
}
bool CNetworkPacketHeaderMap::Get(int header, TPacketType * pPacketType)
{
std::map<int, TPacketType>::iterator f=m_headerMap.find(header);
if (m_headerMap.end()==f)
return false;
*pPacketType = f->second;
return true;
}
CNetworkPacketHeaderMap::CNetworkPacketHeaderMap()
{
}
CNetworkPacketHeaderMap::~CNetworkPacketHeaderMap()
{
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <map>
class CNetworkPacketHeaderMap
{
public:
typedef struct SPacketType
{
SPacketType(int iSize = 0, bool bFlag = false)
{
iPacketSize = iSize;
isDynamicSizePacket = bFlag;
}
int iPacketSize;
bool isDynamicSizePacket;
} TPacketType;
public:
CNetworkPacketHeaderMap();
virtual ~CNetworkPacketHeaderMap();
void Set(int header, TPacketType rPacketType);
bool Get(int header, TPacketType * pPacketType);
protected:
std::map<int, TPacketType> m_headerMap;
};
File diff suppressed because it is too large Load Diff
+113
View File
@@ -0,0 +1,113 @@
#pragma once
#ifdef _IMPROVED_PACKET_ENCRYPTION_
#include "../EterBase/cipher.h"
#endif
#include "../EterBase/tea.h"
#include "NetAddress.h"
class CNetworkStream
{
public:
CNetworkStream();
virtual ~CNetworkStream();
void SetRecvBufferSize(int recvBufSize);
void SetSendBufferSize(int sendBufSize);
#ifndef _IMPROVED_PACKET_ENCRYPTION_
void SetSecurityMode(bool isSecurityMode, const char* c_szTeaKey);
void SetSecurityMode(bool isSecurityMode, const char* c_szTeaEncryptKey, const char* c_szTeaDecryptKey);
#endif
bool IsSecurityMode();
int GetRecvBufferSize();
void Clear();
void ClearRecvBuffer();
void Process();
bool Connect(const CNetworkAddress& c_rkNetAddr, int limitSec = 3);
bool Connect(const char* c_szAddr, int port, int limitSec = 3);
bool Connect(DWORD dwAddr, int port, int limitSec = 3);
void Disconnect();
bool Peek(int len);
bool Peek(int len, char* pDestBuf);
bool Recv(int len);
bool Recv(int len, char* pDestBuf);
bool Send(int len, const char* pSrcBuf);
bool Peek(int len, void* pDestBuf);
bool Recv(int len, void* pDestBuf);
bool Send(int len, const void* pSrcBuf);
bool SendFlush(int len, const void* pSrcBuf);
bool IsOnline();
void SetPacketSequenceMode(bool isOn);
bool SendSequence();
protected:
virtual void OnConnectSuccess();
virtual void OnConnectFailure();
virtual void OnRemoteDisconnect();
virtual void OnDisconnect();
virtual bool OnProcess();
bool __SendInternalBuffer();
bool __RecvInternalBuffer();
void __PopSendBuffer();
int __GetSendBufferSize();
#ifdef _IMPROVED_PACKET_ENCRYPTION_
size_t Prepare(void* buffer, size_t* length);
bool Activate(size_t agreed_length, const void* buffer, size_t length);
void ActivateCipher();
#endif
private:
time_t m_connectLimitTime;
char* m_recvTEABuf;
int m_recvTEABufInputPos;
int m_recvTEABufSize;
char* m_recvBuf;
int m_recvBufSize;
int m_recvBufInputPos;
int m_recvBufOutputPos;
char* m_sendBuf;
int m_sendBufSize;
int m_sendBufInputPos;
int m_sendBufOutputPos;
char* m_sendTEABuf;
int m_sendTEABufSize;
int m_sendTEABufInputPos;
bool m_isOnline;
#ifdef _IMPROVED_PACKET_ENCRYPTION_
Cipher m_cipher;
#else
// Obsolete encryption stuff here
bool m_isSecurityMode;
char m_szEncryptKey[TEA_KEY_LENGTH]; // Client 에서 보낼 패킷을 Encrypt 할때 사용하는 Key
char m_szDecryptKey[TEA_KEY_LENGTH]; // Server 에서 전송된 패킷을 Decrypt 할때 사용하는 Key
#endif
SOCKET m_sock;
CNetworkAddress m_addr;
// Sequence
DWORD m_iSequence;
bool m_bUseSequence;
std::vector<BYTE> m_kVec_bSequenceTable;
};
+58
View File
@@ -0,0 +1,58 @@
#include "StdAfx.h"
#include "PathStack.h"
CPathStack::CPathStack()
{
SetBase();
}
CPathStack::~CPathStack()
{
MoveBase();
}
void CPathStack::GetCurrentPathName(std::string* pstCurPathName)
{
assert(pstCurPathName!=NULL);
char szPathName[MAX_PATH+1];
_getcwd(szPathName, MAX_PATH);
*pstCurPathName = szPathName;
}
void CPathStack::Push()
{
char szPathName[MAX_PATH+1];
_getcwd(szPathName, MAX_PATH);
m_stPathNameDeque.push_front(szPathName);
}
bool CPathStack::Pop()
{
if (m_stPathNameDeque.empty())
{
assert(!"CPathStack::Pop Empty Stack");
return false;
}
_chdir(m_stPathNameDeque.front().c_str());
m_stPathNameDeque.pop_front();
return true;
}
void CPathStack::MoveBase()
{
_chdir(m_stBasePathName.c_str());
}
void CPathStack::SetBase()
{
GetCurrentPathName(&m_stBasePathName);
}
void CPathStack::Move(const char* c_szPathName)
{
_chdir(c_szPathName);
}
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include <deque>
#include <string>
class CPathStack
{
public:
CPathStack();
virtual ~CPathStack();
void SetBase();
void MoveBase();
void Push();
bool Pop();
void Move(const char* c_szPathName);
void GetCurrentPathName(std::string* pstCurPathName);
protected:
std::string m_stBasePathName;
std::deque<std::string> m_stPathNameDeque;
};
+685
View File
@@ -0,0 +1,685 @@
#pragma once
#include "../EterBase/Debug.h"
#include <algorithm> // PORT: std::find below; MSVC's headers pulled it in transitively
//#define DYNAMIC_POOL_STRICT
template<typename T>
class CDynamicPool
{
public:
CDynamicPool()
{
//Tracen(typeid(T).name());
m_uInitCapacity=0;
m_uUsedCapacity=0;
}
virtual ~CDynamicPool()
{
assert(m_kVct_pkData.empty());
//#ifdef _DEBUG
// char szText[256];
// sprintf(szText, "--------------------------------------------------------------------- %s Pool Capacity %d\n", typeid(T).name(), m_uUsedCapacity);
// OutputDebugString(szText);
// printf(szText);
//#endif
}
void SetName(const char* c_szName)
{
}
void Clear()
{
Destroy();
}
void Destroy()
{
/*
#ifdef _DEBUG
if (!m_kVct_pkData.empty())
{
char szText[256];
sprintf(szText, "--------------------------------------------------------------------- %s Pool Destroy\n", typeid(T).name());
OutputDebugString(szText);
printf(szText);
}
#endif
*/
for (auto v : m_kVct_pkData)
Delete(v);
m_kVct_pkData.clear();
m_kVct_pkFree.clear();
}
void Create(UINT uCapacity)
{
m_uInitCapacity=uCapacity;
m_kVct_pkData.reserve(uCapacity);
m_kVct_pkFree.reserve(uCapacity);
}
T* Alloc()
{
if (m_kVct_pkFree.empty())
{
T* pkNewData=new T;
m_kVct_pkData.push_back(pkNewData);
++m_uUsedCapacity;
return pkNewData;
}
T* pkFreeData=m_kVct_pkFree.back();
m_kVct_pkFree.pop_back();
return pkFreeData;
}
void Free(T* pkData)
{
#ifdef DYNAMIC_POOL_STRICT
assert(__IsValidData(pkData));
assert(!__IsFreeData(pkData));
#endif
m_kVct_pkFree.push_back(pkData);
}
void FreeAll()
{
m_kVct_pkFree=m_kVct_pkData;
}
DWORD GetCapacity()
{
return m_kVct_pkData.size();
}
protected:
bool __IsValidData(T* pkData)
{
if (m_kVct_pkData.end()==std::find(m_kVct_pkData.begin(), m_kVct_pkData.end(), pkData))
return false;
return true;
}
bool __IsFreeData(T* pkData)
{
if (m_kVct_pkFree.end()==std::find(m_kVct_pkFree.begin(), m_kVct_pkFree.end(), pkData))
return false;
return true;
}
static void Delete(T* pkData)
{
delete pkData;
}
protected:
std::vector<T*> m_kVct_pkData;
std::vector<T*> m_kVct_pkFree;
UINT m_uInitCapacity;
UINT m_uUsedCapacity;
};
template<typename T>
class CDynamicPoolEx
{
public:
CDynamicPoolEx()
{
m_uInitCapacity=0;
m_uUsedCapacity=0;
}
virtual ~CDynamicPoolEx()
{
assert(m_kVct_pkFree.size()==m_kVct_pkData.size());
Destroy();
#ifdef _DEBUG
char szText[256];
sprintf(szText, "--------------------------------------------------------------------- %s Pool Capacity %d\n", typeid(T).name(), m_uUsedCapacity);
OutputDebugString(szText);
printf(szText);
#endif
}
void Clear()
{
Destroy();
}
void Destroy()
{
#ifdef _DEBUG
if (!m_kVct_pkData.empty())
{
char szText[256];
sprintf(szText, "--------------------------------------------------------------------- %s Pool Destroy\n", typeid(T).name());
OutputDebugString(szText);
printf(szText);
}
#endif
for (auto v : m_kVct_pkData)
Delete(v);
m_kVct_pkData.clear();
m_kVct_pkFree.clear();
}
void Create(UINT uCapacity)
{
m_uInitCapacity=uCapacity;
m_kVct_pkData.reserve(uCapacity);
m_kVct_pkFree.reserve(uCapacity);
}
T* Alloc()
{
if (m_kVct_pkFree.empty())
{
T* pkNewData=New();
m_kVct_pkData.push_back(pkNewData);
++m_uUsedCapacity;
return pkNewData;
}
T* pkFreeData=m_kVct_pkFree.back();
m_kVct_pkFree.pop_back();
return pkFreeData;
}
void Free(T* pkData)
{
#ifdef DYNAMIC_POOL_STRICT
assert(__IsValidData(pkData));
assert(!__IsFreeData(pkData));
#endif
m_kVct_pkFree.push_back(pkData);
}
void FreeAll()
{
m_kVct_pkFree=m_kVct_pkData;
}
DWORD GetCapacity()
{
return m_kVct_pkData.size();
}
protected:
bool __IsValidData(T* pkData)
{
if (m_kVct_pkData.end()==std::find(m_kVct_pkData.begin(), m_kVct_pkData.end(), pkData))
return false;
return true;
}
bool __IsFreeData(T* pkData)
{
if (m_kVct_pkFree.end()==std::find(m_kVct_pkFree.begin(), m_kVct_pkFree.end(), pkData))
return false;
return true;
}
static T* New()
{
return (T*)::operator new(sizeof(T));
}
static void Delete(T* pkData)
{
::operator delete(pkData);
}
protected:
std::vector<T*> m_kVct_pkData;
std::vector<T*> m_kVct_pkFree;
UINT m_uInitCapacity;
UINT m_uUsedCapacity;
};
template <class T>
class CPooledObject
{
public:
CPooledObject()
{
}
virtual ~CPooledObject()
{
}
void * operator new(size_t /*mem_size*/) // PORT: was unsigned int (size_t on ILP32 Win32)
{
return ms_kPool.Alloc();
}
void operator delete(void* pT)
{
ms_kPool.Free((T*)pT);
}
static void DestroySystem()
{
ms_kPool.Destroy();
}
static void DeleteAll()
{
ms_kPool.FreeAll();
}
protected:
static CDynamicPoolEx<T> ms_kPool;
};
template <class T> CDynamicPoolEx<T> CPooledObject<T>::ms_kPool;
/*
template <class T>
class CDynamicSizePool
{
#define GETPREVP(p) *(T**)((char*)p+sizeof(T))
#define GETNEXTP(p) *(T**)((char*)p+sizeof(T)+sizeof(T*))
public:
CDynamicSizePool()
{
Initialize();
}
virtual ~CDynamicSizePool()
{
Clear();
}
void Initialize()
{
m_nodes = NULL;
m_nodeCount = 0;
m_pFreeList = NULL;
m_pUsedList = NULL;
}
void SetName(const char* c_szName)
{
m_stName = c_szName;
}
T* Alloc()
{
void* pnewNode;
if (m_pFreeList)
{
pnewNode = m_pFreeList;
m_pFreeList = GETNEXTP(m_pFreeList);
}
else
{
pnewNode = AllocNode();
}
if (!pnewNode)
return NULL;
if (!m_pUsedList)
{
m_pUsedList = pnewNode;
GETPREVP(m_pUsedList) = NULL;
GETNEXTP(m_pUsedList) = NULL;
}
else
{
GETPREVP(m_pUsedList) = (T*) pnewNode;
GETNEXTP(pnewNode) = (T*) m_pUsedList;
GETPREVP(pnewNode) = NULL;
m_pUsedList = pnewNode;
}
//Tracef("%s Pool Alloc %p\n", m_stName.c_str(), pnewNode);
return (T*) pnewNode;
}
void Free(T * pdata)
{
void* pfreeNode = (void*) pdata;
if (pfreeNode == m_pUsedList)
{
if (NULL != (m_pUsedList = GETNEXTP(m_pUsedList)))
GETPREVP(m_pUsedList) = NULL;
}
else
{
if (GETNEXTP(pfreeNode))
GETPREVP(GETNEXTP(pfreeNode)) = GETPREVP(pfreeNode);
if (GETPREVP(pfreeNode))
GETNEXTP(GETPREVP(pfreeNode)) = GETNEXTP(pfreeNode);
}
GETPREVP(pfreeNode) = NULL;
GETNEXTP(pfreeNode) = (T*)m_pFreeList;
m_pFreeList = pfreeNode;
//Tracef("%s Pool Free\n", m_stName.c_str());
}
void FreeAll()
{
void * pcurNode;
void * pnextNode;
pcurNode = m_pUsedList;
while (pcurNode)
{
pnextNode = GETNEXTP(pcurNode);
Free(pcurNode);
pcurNode = pnextNode;
}
}
void Clear()
{
void* pcurNode;
void* pnextNode;
int count = 0;
pcurNode = m_pFreeList;
while (pcurNode)
{
pnextNode = GETNEXTP(pcurNode);
((T*)pcurNode)->~T();
::operator delete(pcurNode);
pcurNode = pnextNode;
++count;
}
m_pFreeList = NULL;
pcurNode = m_pUsedList;
while (pcurNode)
{
pnextNode = GETNEXTP(pcurNode);
((T*)pcurNode)->~T();
::operator delete(pcurNode);
pcurNode = pnextNode;
++count;
}
m_pUsedList = NULL;
//Tracef("%s Pool Clear %d\n", m_stName.c_str(), count);
}
protected:
void* AllocNode()
{
return ::operator new(sizeof(T)+sizeof(T*)*2);
}
protected:
void * m_nodes;
void * m_pFreeList;
void * m_pUsedList;
int m_nodeCount;
std::string m_stName;
#undef GETNEXTP
#undef GETPREVP
};
template <class T>
class CPooledObject
{
public:
CPooledObject()
{
}
virtual ~CPooledObject()
{
}
void * operator new(unsigned int mem_size)
{
return ms_DynamicSizePool.Alloc();
}
void operator delete(void* pT)
{
ms_DynamicSizePool.Free((T*)pT);
}
static void SetPoolName(const char* szPoolName)
{
ms_DynamicSizePool.SetName(szPoolName);
}
static void ClearPool()
{
ms_DynamicSizePool.Clear();
}
static void FreePool()
{
ms_DynamicSizePool.FreeAll();
}
protected:
static CDynamicSizePool<T> ms_DynamicSizePool;
};
template <class T> CDynamicSizePool<T> CPooledObject<T>::ms_DynamicSizePool;
*/
/*
template<typename T>
class CPoolNode : public T
{
public:
CPoolNode()
{
m_pNext = NULL;
m_pPrev = NULL;
}
virtual ~CPoolNode()
{
}
public:
CPoolNode<T> * m_pNext;
CPoolNode<T> * m_pPrev;
};
template<typename T>
class CDynamicPool
{
public:
typedef CPoolNode<T> TNode;
public:
CDynamicPool()
{
Initialize();
}
virtual ~CDynamicPool()
{
assert(m_pFreeList==NULL && "CDynamicPool::~CDynamicPool() - NOT Clear");
assert(m_pUsedList==NULL && "CDynamicPool::~CDynamicPool() - NOT Clear");
Clear();
}
void Initialize()
{
m_nodes = NULL;
m_nodeCount = 0;
m_pFreeList = NULL;
m_pUsedList = NULL;
}
void SetName(const char* c_szName)
{
m_stName = c_szName;
}
DWORD GetCapacity()
{
return m_nodeCount;
}
T* Alloc()
{
TNode* pnewNode;
if (m_pFreeList)
{
pnewNode = m_pFreeList;
m_pFreeList = m_pFreeList->m_pNext;
}
else
{
pnewNode = AllocNode();
}
if (!pnewNode)
return NULL;
if (!m_pUsedList)
{
m_pUsedList = pnewNode;
m_pUsedList->m_pPrev = m_pUsedList->m_pNext = NULL;
}
else
{
m_pUsedList->m_pPrev = pnewNode;
pnewNode->m_pNext = m_pUsedList;
pnewNode->m_pPrev = NULL;
m_pUsedList = pnewNode;
}
//Tracef("%s Pool Alloc %p\n", m_stName.c_str(), pnewNode);
return (T*) pnewNode;
}
bool IsUsedData(T* pdata)
{
TNode* pchkNode=(TNode*)pdata;
TNode* pcurNode = m_pUsedList;
while (pcurNode)
{
if (pcurNode==pdata)
return true;
pcurNode = pcurNode->m_pNext;
}
return false;
}
bool IsFreeData(T* pdata)
{
TNode* pchkNode=(TNode*)pdata;
TNode* pcurNode = m_pFreeList;
while (pcurNode)
{
if (pcurNode==pdata)
return true;
pcurNode = pcurNode->m_pNext;
}
return false;
}
void Free(T * pdata)
{
assert(IsUsedData(pdata));
assert(!IsFreeData(pdata));
TNode* pfreeNode = (TNode*) pdata;
if (pfreeNode == m_pUsedList)
{
m_pUsedList = m_pUsedList->m_pNext;
if (NULL != m_pUsedList)
m_pUsedList->m_pPrev = NULL;
}
else
{
if (pfreeNode->m_pNext)
pfreeNode->m_pNext->m_pPrev = pfreeNode->m_pPrev;
if (pfreeNode->m_pPrev)
pfreeNode->m_pPrev->m_pNext = pfreeNode->m_pNext;
}
pfreeNode->m_pPrev = NULL;
pfreeNode->m_pNext = m_pFreeList;
m_pFreeList = pfreeNode;
//Tracef("%s Pool Free\n", m_stName.c_str());
}
void FreeAll()
{
TNode * pcurNode;
TNode * pnextNode;
pcurNode = m_pUsedList;
while (pcurNode)
{
pnextNode = pcurNode->m_pNext;
Free(pcurNode);
pcurNode = pnextNode;
}
assert(NULL==m_pUsedList);
}
void Clear()
{
TNode* pcurNode;
TNode* pnextNode;
DWORD count = 0;
pcurNode = m_pFreeList;
while (pcurNode)
{
pnextNode = pcurNode->m_pNext;
delete pcurNode;
pcurNode = pnextNode;
++count;
}
m_pFreeList = NULL;
pcurNode = m_pUsedList;
while (pcurNode)
{
pnextNode = pcurNode->m_pNext;
delete pcurNode;
pcurNode = pnextNode;
++count;
}
m_pUsedList = NULL;
assert(count==m_nodeCount && "CDynamicPool::Clear()");
m_nodeCount=0;
}
protected:
TNode* AllocNode()
{
++m_nodeCount;
return new TNode;
}
protected:
TNode * m_nodes;
TNode * m_pFreeList;
TNode * m_pUsedList;
DWORD m_nodeCount;
std::string m_stName;
};
*/
+264
View File
@@ -0,0 +1,264 @@
#pragma once
#include "../EterBase/Timer.h"
#include "../EterBase/Debug.h"
/*
class CProfiler : public CSingleton<CProfiler>
{
public:
enum
{
STACK_DATA_MAX_NUM = 64,
};
public:
typedef struct SProfileStackData
{
int iCallStep;
long iStartTime;
long iEndTime;
std::string strName;
} TProfileStackData;
typedef struct SProfileAccumulationData
{
int iStartTime;
int iCallingCount;
int iCollapsedTime;
std::string strName;
} TProfileAccumulationData;
typedef std::map<std::string, CGraphicTextInstance*> TGraphicTextInstanceMap;
typedef std::map<std::string, TProfileAccumulationData> TProfileAccumulationDataMap;
public:
CProfiler()
{
Clear();
m_ProfileAccumulationDataMap.clear();
}
virtual ~CProfiler()
{
}
void Clear()
{
m_ProfileStackDataCount = 0;
m_iCallStep = 0;
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.begin();
for (; itor != m_ProfileAccumulationDataMap.end(); ++itor)
{
TProfileAccumulationData & rData = itor->second;
rData.iCallingCount = 0;
rData.iCollapsedTime = 0;
}
}
void Push(const char * c_szName)
{
assert(m_ProfileStackDataCount < STACK_DATA_MAX_NUM);
TProfileStackData & rProfileStackData = m_ProfileStackDatas[m_ProfileStackDataCount++];
rProfileStackData.iCallStep = m_iCallStep;
rProfileStackData.iStartTime = ELTimer_GetMSec();
rProfileStackData.strName = c_szName;
++m_iCallStep;
TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(c_szName);
if (m_GraphicTextInstanceMap.end() == itor)
{
CGraphicTextInstance * pGraphicTextInstance = CGraphicTextInstance::New();
CResource * pResource = CResourceManager::Instance().GetResourcePointer("굴림체.fnt");
pGraphicTextInstance->Clear();
pGraphicTextInstance->SetTextPointer(static_cast<CGraphicText*>(pResource));
m_GraphicTextInstanceMap.insert(TGraphicTextInstanceMap::value_type(c_szName, pGraphicTextInstance));
}
}
void Pop(const char * c_szName)
{
TProfileStackData * pProfileStackData;
if (!GetProfileStackDataPointer(c_szName, &pProfileStackData))
{
assert(!"The name doesn't exist");
return;
}
pProfileStackData->iEndTime = ELTimer_GetMSec();
--m_iCallStep;
}
void PushAccumulation(const char * c_szName)
{
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName);
if (itor == m_ProfileAccumulationDataMap.end())
{
TProfileAccumulationData ProfileAccumulationData;
ProfileAccumulationData.iCollapsedTime = 0;
ProfileAccumulationData.iCallingCount = 0;
ProfileAccumulationData.strName = c_szName;
m_ProfileAccumulationDataMap.insert(TProfileAccumulationDataMap::value_type(c_szName, ProfileAccumulationData));
itor = m_ProfileAccumulationDataMap.find(c_szName);
/////
CGraphicTextInstance * pGraphicTextInstance = m_GraphicTextInstancePool.Alloc();
CResource * pResource = CResourceManager::Instance().GetResourcePointer("굴림체.fnt");
pGraphicTextInstance->Clear();
pGraphicTextInstance->SetTextPointer(static_cast<CGraphicText*>(pResource));
m_GraphicTextInstanceMap.insert(TGraphicTextInstanceMap::value_type(c_szName, pGraphicTextInstance));
}
TProfileAccumulationData & rData = itor->second;
rData.iStartTime = ELTimer_GetMSec();
}
void PopAccumulation(const char * c_szName)
{
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName);
if (itor == m_ProfileAccumulationDataMap.end())
return;
TProfileAccumulationData & rData = itor->second;
rData.iCollapsedTime += ELTimer_GetMSec() - rData.iStartTime;
++rData.iCallingCount;
}
void ProfileByConsole()
{
for (int i = 0; i < m_ProfileStackDataCount; ++i)
{
TProfileStackData & rProfileStackData = m_ProfileStackDatas[i];
// for (int i = 0; i < rProfileStackData.iCallStep; ++i)
// Tracef("\t");
Tracef("%-10s: %2d\t", rProfileStackData.strName.c_str(), rProfileStackData.iEndTime - rProfileStackData.iStartTime);
}
Tracef("\n");
}
void ProfileOneStackDataByConsole(const char * c_szName)
{
TProfileStackData * pProfileStackData;
if (!GetProfileStackDataPointer(c_szName, &pProfileStackData))
{
return;
}
Tracef("%-10s: %3d\n", pProfileStackData->strName.c_str(), pProfileStackData->iEndTime - pProfileStackData->iStartTime);
}
void ProfileOneAccumulationDataByConsole(const char * c_szName)
{
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.find(c_szName);
if (itor == m_ProfileAccumulationDataMap.end())
return;
TProfileAccumulationData & rData = itor->second;
Tracef("%-10s : [CollapsedTime : %3d] / [CallingCount : %3d]\n", rData.strName.c_str(),
rData.iCollapsedTime,
rData.iCallingCount);
}
void ProfileByScreen()
{
float fxPosition = 0;
float fyPosition = 10;
char szText[128];
for (int i = 0; i < m_ProfileStackDataCount; ++i)
{
TProfileStackData & rProfileStackData = m_ProfileStackDatas[i];
TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(rProfileStackData.strName);
if (m_GraphicTextInstanceMap.end() != itor)
{
CGraphicTextInstance * pGraphicTextInstance = itor->second;
fxPosition = 10 + (float) rProfileStackData.iCallStep * 10 * 4;
sprintf(szText, "%-10s : %3d", rProfileStackData.strName.c_str(), rProfileStackData.iEndTime - rProfileStackData.iStartTime);
pGraphicTextInstance->SetColor(0.7f, 0.7f, 0.7f);
pGraphicTextInstance->SetValue(szText, strlen(szText));
pGraphicTextInstance->SetPosition(fxPosition, fyPosition);
pGraphicTextInstance->Update();
pGraphicTextInstance->Render();
fyPosition += 17;
}
}
fxPosition = 10;
fyPosition += 10;
TProfileAccumulationDataMap::iterator itor = m_ProfileAccumulationDataMap.begin();
for (; itor != m_ProfileAccumulationDataMap.end(); ++itor)
{
TProfileAccumulationData & rData = itor->second;
TGraphicTextInstanceMap::iterator itor = m_GraphicTextInstanceMap.find(rData.strName);
if (m_GraphicTextInstanceMap.end() != itor)
{
CGraphicTextInstance * pGraphicTextInstance = itor->second;
sprintf(szText, "%-10s : [CollapsedTime : %3d] / [CallingCount : %3d]", rData.strName.c_str(),
rData.iCollapsedTime,
rData.iCallingCount);
pGraphicTextInstance->SetColor(0.7f, 0.7f, 0.7f);
pGraphicTextInstance->SetValue(szText, strlen(szText));
pGraphicTextInstance->SetPosition(fxPosition, fyPosition);
pGraphicTextInstance->Update();
pGraphicTextInstance->Render();
fyPosition += 17;
}
}
}
protected:
bool GetProfileStackDataPointer(const char * c_szName, TProfileStackData ** ppProfileStackData)
{
for (int i = 0; i < m_ProfileStackDataCount; ++i)
{
if (0 == m_ProfileStackDatas[i].strName.compare(c_szName))
{
*ppProfileStackData = &m_ProfileStackDatas[i];
return true;
}
}
return false;
}
protected:
// Profile Stack Data
int m_ProfileStackDataCount;
TProfileStackData m_ProfileStackDatas[STACK_DATA_MAX_NUM];
// Profile Increase Data
TProfileAccumulationDataMap m_ProfileAccumulationDataMap;
int m_iCallStep;
TGraphicTextInstanceMap m_GraphicTextInstanceMap;
};
*/
+65
View File
@@ -0,0 +1,65 @@
#pragma once
#include <d3dx8.h>
class CRay
{
public:
CRay(const D3DXVECTOR3 & v3Start, const D3DXVECTOR3 & v3Dir, float fRayRange) : m_v3Start(v3Start), m_v3Direction(v3Dir)
{
assert(fRayRange >= 0);
m_fRayRange = fRayRange;
D3DXVec3Normalize(&m_v3Direction, &m_v3Direction);
m_v3End = m_v3Start + fRayRange * m_v3Direction;
}
CRay()
{
}
void SetStartPoint(const D3DXVECTOR3 & v3Start)
{
m_v3Start = v3Start;
}
void SetDirection(const D3DXVECTOR3 & v3Dir, float fRayRange)
{
assert(fRayRange >= 0);
m_v3Direction = v3Dir;
D3DXVec3Normalize(&m_v3Direction, &m_v3Direction);
m_fRayRange = fRayRange;
m_v3End = m_v3Start + m_fRayRange * m_v3Direction;
}
void GetStartPoint(D3DXVECTOR3 * pv3Start) const
{
*pv3Start = m_v3Start;
}
void GetDirection(D3DXVECTOR3 * pv3Dir, float * pfRayRange) const
{
*pv3Dir = m_v3Direction;
*pfRayRange = m_fRayRange;
}
void GetEndPoint(D3DXVECTOR3 * pv3End) const
{
*pv3End = m_v3End;
}
const CRay & operator = (const CRay & rhs)
{
assert(rhs.m_fRayRange >= 0);
m_v3Start = rhs.m_v3Start;
m_v3Direction = rhs.m_v3Direction;
m_fRayRange = rhs.m_fRayRange;
D3DXVec3Normalize(&m_v3Direction, &m_v3Direction);
m_v3End = m_v3Start + m_fRayRange * m_v3Direction;
}
private:
D3DXVECTOR3 m_v3Start;
D3DXVECTOR3 m_v3End;
D3DXVECTOR3 m_v3Direction;
float m_fRayRange;
};
+104
View File
@@ -0,0 +1,104 @@
#ifndef __INC_REF_H__
#define __INC_REF_H__
#include "ReferenceObject.h"
#include <assert.h>
template<typename T> class CRef
{
public:
struct FClear
{
void operator() (CRef<T>& rRef)
{
rRef.Clear();
}
};
public:
CRef() : m_pObject(NULL)
{
}
CRef(CReferenceObject* pObject)
{
m_pObject = NULL;
Initialize(pObject);
}
CRef(const CRef& c_rRef)
{
m_pObject = NULL;
Initialize(c_rRef.m_pObject);
}
~CRef()
{
Clear();
}
void operator = (CReferenceObject* pObject)
{
SetPointer(pObject);
}
void operator = (const CRef& c_rRef)
{
SetPointer(c_rRef.m_pObject);
}
void Clear()
{
if (m_pObject)
{
m_pObject->Release();
m_pObject = NULL;
}
}
bool IsNull() const
{
return m_pObject == NULL ? true : false;
}
void SetPointer(CReferenceObject* pObject)
{
CReferenceObject* pOldObject = m_pObject;
m_pObject = pObject;
if (m_pObject)
m_pObject->AddReference();
if (pOldObject)
pOldObject->Release();
}
T* GetPointer() const
{
return static_cast<T*>(m_pObject);
}
T* operator->() const
{
assert(m_pObject != NULL);
return static_cast<T*>(m_pObject);
}
private:
void Initialize(CReferenceObject* pObject)
{
assert(m_pObject == NULL);
m_pObject = pObject;
if (m_pObject)
m_pObject->AddReference();
}
private:
CReferenceObject* m_pObject;
};
#endif
+61
View File
@@ -0,0 +1,61 @@
#include "StdAfx.h"
#include "ReferenceObject.h"
CReferenceObject::CReferenceObject() : m_refCount(0), m_destructed(false)
{
}
CReferenceObject::~CReferenceObject()
{
}
void CReferenceObject::AddReference()
{
if (m_refCount == 0)
OnConstruct();
++m_refCount;
}
int CReferenceObject::GetReferenceCount()
{
return m_refCount;
}
void CReferenceObject::AddReferenceOnly()
{
++m_refCount;
}
void CReferenceObject::Release()
{
if (m_refCount > 1)
{
--m_refCount;
return;
}
assert(m_destructed == false);
assert(m_refCount >= 0);
m_refCount = 0;
OnSelfDestruct();
}
void CReferenceObject::OnConstruct()
{
m_destructed = false;
}
void CReferenceObject::OnSelfDestruct()
{
m_destructed = true;
delete this;
}
bool CReferenceObject::canDestroy()
{
if (m_refCount > 0)
return false;
return true;
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
class CReferenceObject
{
public:
CReferenceObject();
virtual ~CReferenceObject();
void AddReference();
void AddReferenceOnly();
void Release();
int GetReferenceCount();
bool canDestroy();
protected:
virtual void OnConstruct();
virtual void OnSelfDestruct();
private:
int m_refCount;
bool m_destructed;
};
+181
View File
@@ -0,0 +1,181 @@
#include "StdAfx.h"
#include "../EterPack/EterPackManager.h"
#include "../EterBase/CRC32.h"
#include "../EterBase/Timer.h"
#include "Resource.h"
#include "ResourceManager.h"
bool CResource::ms_bDeleteImmediately = false;
CResource::CResource(const char* c_szFileName) : me_state(STATE_EMPTY)
{
SetFileName(c_szFileName);
}
CResource::~CResource()
{
}
void CResource::SetDeleteImmediately(bool isSet)
{
ms_bDeleteImmediately = isSet;
}
void CResource::OnConstruct()
{
Load();
}
void CResource::OnSelfDestruct()
{
if (ms_bDeleteImmediately)
Clear();
else
CResourceManager::Instance().ReserveDeletingResource(this);
}
void CResource::Load()
{
if (me_state != STATE_EMPTY)
return;
const char * c_szFileName = GetFileName();
DWORD dwStart = ELTimer_GetMSec();
CMappedFile file;
LPCVOID fileData;
//Tracenf("Load %s", c_szFileName);
if (CEterPackManager::Instance().Get(file, c_szFileName, &fileData))
{
m_dwLoadCostMiliiSecond = ELTimer_GetMSec() - dwStart;
//Tracef("CResource::Load %s (%d bytes) in %d ms\n", c_szFileName, file.Size(), m_dwLoadCostMiliiSecond);
if (OnLoad(file.Size(), fileData))
{
me_state = STATE_EXIST;
}
else
{
Tracef("CResource::Load Error %s\n", c_szFileName);
me_state = STATE_ERROR;
return;
}
}
else
{
if (OnLoad(0, NULL))
me_state = STATE_EXIST;
else
{
Tracef("CResource::Load file not exist %s\n", c_szFileName);
me_state = STATE_ERROR;
}
}
}
void CResource::Reload()
{
Clear();
Tracef("CResource::Reload %s\n", GetFileName());
CMappedFile file;
LPCVOID fileData;
if (CEterPackManager::Instance().Get(file, GetFileName(), &fileData))
{
if (OnLoad(file.Size(), fileData))
{
me_state = STATE_EXIST;
}
else
{
me_state = STATE_ERROR;
return;
}
}
else
{
if (OnLoad(0, NULL))
me_state = STATE_EXIST;
else
{
me_state = STATE_ERROR;
}
}
}
CResource::TType CResource::StringToType(const char* c_szType)
{
return GetCRC32(c_szType, strlen(c_szType));
}
int CResource::ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen)
{
const char * pc;
int len = 0;
for (pc = c_szPathName; *pc && len < retLen; ++pc, ++len)
{
if (*pc == '/')
*(pszRetPathName++) = '\\';
else
*(pszRetPathName++) = (char) korean_tolower(*pc);
}
*pszRetPathName = '\0';
return len;
}
void CResource::SetFileName(const char* c_szFileName)
{
// 2004. 2. 1. myevan. 쓰레드가 사용되는 상황에서 static 변수는 사용하지 않는것이 좋다.
// 2004. 2. 1. myevan. 파일 이름 처리를 std::string 사용
m_stFileName=c_szFileName;
}
void CResource::Clear()
{
OnClear();
me_state = STATE_EMPTY;
}
bool CResource::IsType(TType type)
{
return OnIsType(type);
}
CResource::TType CResource::Type()
{
static TType s_type = StringToType("CResource");
return s_type;
}
bool CResource::OnIsType(TType type)
{
if (CResource::Type() == type)
return true;
return false;
}
bool CResource::IsData() const
{
return me_state != STATE_EMPTY;
}
bool CResource::IsEmpty() const
{
return OnIsEmpty();
}
bool CResource::CreateDeviceObjects()
{
return true;
}
void CResource::DestroyDeviceObjects()
{
}
+69
View File
@@ -0,0 +1,69 @@
#pragma once
#include "ReferenceObject.h"
#include <string>
class CResource : public CReferenceObject
{
public:
typedef DWORD TType;
enum EState
{
STATE_EMPTY,
STATE_ERROR,
STATE_EXIST,
STATE_LOAD,
STATE_FREE
};
public:
void Clear();
static TType StringToType(const char* c_szType);
static TType Type();
void Load();
void Reload();
int ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen);
virtual bool CreateDeviceObjects();
virtual void DestroyDeviceObjects();
public:
CResource(const char* c_szFileName);
virtual ~CResource();
static void SetDeleteImmediately(bool isSet = false);
// is loaded?
bool IsData() const;
bool IsEmpty() const;
bool IsType(TType type);
DWORD GetLoadCostMilliSecond() { return m_dwLoadCostMiliiSecond; }
//const char * GetFileName() const { return m_pszFileName; }
const char * GetFileName() const { return m_stFileName.c_str(); }
const std::string& GetFileNameString() const { return m_stFileName; }
virtual bool OnLoad(int iSize, const void * c_pvBuf) = 0;
protected:
void SetFileName(const char* c_szFileName);
virtual void OnClear() = 0;
virtual bool OnIsEmpty() const = 0;
virtual bool OnIsType(TType type) = 0;
virtual void OnConstruct();
virtual void OnSelfDestruct();
protected:
std::string m_stFileName;
//char * m_pszFileName;
DWORD m_dwLoadCostMiliiSecond;
EState me_state;
protected:
static bool ms_bDeleteImmediately;
};
+525
View File
@@ -0,0 +1,525 @@
#include "StdAfx.h"
#include <io.h>
#include "../EterBase/CRC32.h"
#include "../EterBase/Timer.h"
#include "../EterBase/Stl.h"
#include "../EterPack/EterPackManager.h"
#include "ResourceManager.h"
#include "GrpImage.h"
int g_iLoadingDelayTime = 20;
const long c_Deleting_Wait_Time = 30000; // 삭제 대기 시간 (30초)
const long c_DeletingCountPerFrame = 30; // 프레임당 체크 리소스 갯수
const long c_Reference_Decrease_Wait_Time = 30000; // 선로딩 리소스의 해제 대기 시간 (30초)
CFileLoaderThread CResourceManager::ms_loadingThread;
void CResourceManager::LoadStaticCache(const char* c_szFileName)
{
CResource* pkRes=GetResourcePointer(c_szFileName);
if (!pkRes)
{
Lognf(1, "CResourceManager::LoadStaticCache %s - FAILED", c_szFileName);
return;
}
DWORD dwCacheKey=GetCRC32(c_szFileName, strlen(c_szFileName));
TResourcePointerMap::iterator f=m_pCacheMap.find(dwCacheKey);
if (m_pCacheMap.end()!=f)
return;
pkRes->AddReference();
m_pCacheMap.insert(TResourcePointerMap::value_type(dwCacheKey, pkRes));
}
void CResourceManager::ProcessBackgroundLoading()
{
TResourceRequestMap::iterator itor = m_RequestMap.begin();
while (itor != m_RequestMap.end())
{
DWORD dwFileCRC = itor->first;
std::string & stFileName = itor->second;
if (isResourcePointerData(dwFileCRC) ||
(m_WaitingMap.end() != m_WaitingMap.find(dwFileCRC)))
{
//printf("SKP %s\n", stFileName.c_str());
itor = m_RequestMap.erase(itor);
continue;
}
//printf("REQ %s\n", stFileName.c_str());
ms_loadingThread.Request(stFileName);
m_WaitingMap.insert(TResourceRequestMap::value_type(dwFileCRC, stFileName));
itor = m_RequestMap.erase(itor);
//break; // NOTE: 여기서 break 하면 천천히 로딩 된다.
}
DWORD dwCurrentTime = ELTimer_GetMSec();
CFileLoaderThread::TData * pData;
while (ms_loadingThread.Fetch(&pData))
{
//printf("LOD %s\n", pData->stFileName.c_str());
CResource * pResource = GetResourcePointer(pData->stFileName.c_str());
if (pResource)
{
if (pResource->IsEmpty())
{
pResource->OnLoad(pData->dwSize, pData->pvBuf);
pResource->AddReferenceOnly();
// 여기서 올라간 레퍼런스 카운트를 일정 시간이 지난 뒤에 풀어주기 위하여
m_pResRefDecreaseWaitingMap.insert(TResourceRefDecreaseWaitingMap::value_type(dwCurrentTime, pResource));
}
}
m_WaitingMap.erase(GetCRC32(pData->stFileName.c_str(), pData->stFileName.size()));
delete [] ((char *) pData->pvBuf);
delete pData;
}
// DO : 일정 시간이 지나고 난뒤 미리 로딩해 두었던 리소스의 레퍼런스 카운트를 감소 시킨다 - [levites]
long lCurrentTime = ELTimer_GetMSec();
TResourceRefDecreaseWaitingMap::iterator itorRef = m_pResRefDecreaseWaitingMap.begin();
while (itorRef != m_pResRefDecreaseWaitingMap.end())
{
const long & rCreatingTime = itorRef->first;
if (lCurrentTime - rCreatingTime > c_Reference_Decrease_Wait_Time)
{
CResource * pResource = itorRef->second;
// Decrease Reference Count
pResource->Release();
itorRef = m_pResRefDecreaseWaitingMap.erase(itorRef);
//Tracef("Decrease Pre Loading Resource\n", rCreatingTime);
}
else
++itorRef;
}
}
void CResourceManager::PushBackgroundLoadingSet(std::set<std::string> & LoadingSet)
{
std::set<std::string>::iterator itor = LoadingSet.begin();
while (itor != LoadingSet.end())
{
DWORD dwFileCRC = __GetFileCRC(itor->c_str());
if (NULL != isResourcePointerData(dwFileCRC))
{
++itor;
continue;
}
m_RequestMap.insert(TResourceRequestMap::value_type(dwFileCRC, itor->c_str()));
++itor;
}
}
void CResourceManager::__DestroyCacheMap()
{
TResourcePointerMap::iterator i;
for (i = m_pCacheMap.begin(); i != m_pCacheMap.end(); ++i)
{
CResource* pResource = i->second;
pResource->Release();
}
m_pCacheMap.clear();
}
void CResourceManager::__DestroyDeletingResourceMap()
{
Tracenf("CResourceManager::__DestroyDeletingResourceMap %d", m_ResourceDeletingMap.size());
for (TResourceDeletingMap::iterator i = m_ResourceDeletingMap.begin(); i != m_ResourceDeletingMap.end(); ++i)
(i->first)->Clear();
m_ResourceDeletingMap.clear();
}
void CResourceManager::__DestroyResourceMap()
{
Tracenf("CResourceManager::__DestroyResourceMap %d", m_pResMap.size());
TResourcePointerMap::iterator i;
for (i = m_pResMap.begin(); i != m_pResMap.end(); ++i)
{
CResource* pResource = i->second;
pResource->Clear();
}
stl_wipe_second(m_pResMap);
}
void CResourceManager::DestroyDeletingList()
{
CResource::SetDeleteImmediately(true);
__DestroyCacheMap();
__DestroyDeletingResourceMap();
}
void CResourceManager::Destroy()
{
assert(m_ResourceDeletingMap.empty() && "CResourceManager::Destroy - YOU MUST CALL DestroyDeletingList");
__DestroyResourceMap();
}
void CResourceManager::RegisterResourceNewFunctionPointer(const char* c_szFileExt, CResource* (*pNewFunc)(const char* c_szFileName))
{
m_pResNewFuncMap[c_szFileExt] = pNewFunc;
}
void CResourceManager::RegisterResourceNewFunctionByTypePointer(int iType, CResource* (*pNewFunc) (const char* c_szFileName))
{
assert(iType >= 0);
m_pResNewFuncByTypeMap[iType] = pNewFunc;
}
CResource * CResourceManager::InsertResourcePointer(DWORD dwFileCRC, CResource* pResource)
{
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
if (m_pResMap.end() != itor)
{
TraceError("CResource::InsertResourcePointer: %s is already registered\n", pResource->GetFileName());
assert(!"CResource::InsertResourcePointer: Resource already resistered");
delete pResource;
return itor->second;
}
m_pResMap.insert(TResourcePointerMap::value_type(dwFileCRC, pResource));
return pResource;
}
int __ConvertPathName(const char * c_szPathName, char * pszRetPathName, int retLen)
{
const char * pc;
int len = 0;
for (pc = c_szPathName; *pc && len < retLen; ++pc, ++len)
{
if (*pc == '/')
*(pszRetPathName++) = '\\';
else
*(pszRetPathName++) = (char) korean_tolower(*pc);
}
*pszRetPathName = '\0';
return len;
}
CResource * CResourceManager::GetTypeResourcePointer(const char * c_szFileName, int iType)
{
if (!c_szFileName || !*c_szFileName)
{
assert(c_szFileName != NULL && *c_szFileName != '\0');
return NULL;
}
const char * c_pszFile;
DWORD dwFileCRC = __GetFileCRC(c_szFileName, &c_pszFile);
CResource * pResource = FindResourcePointer(dwFileCRC);
if (pResource) // 이미 리소스가 있으면 리턴 한다.
return pResource;
CResource * (*newFunc) (const char *) = NULL;
if (iType != -1)
{
TResourceNewFunctionByTypePointerMap::iterator f = m_pResNewFuncByTypeMap.find(iType);
if (m_pResNewFuncByTypeMap.end() != f)
newFunc = f->second;
}
else
{
const char * pcFileExt = strrchr(c_pszFile, '.');
if (pcFileExt)
{
static char s_szFileExt[8 + 1];
strncpy(s_szFileExt, pcFileExt + 1, 8);
TResourceNewFunctionPointerMap::iterator f = m_pResNewFuncMap.find(s_szFileExt);
if (m_pResNewFuncMap.end() != f)
newFunc = f->second;
}
}
if (!newFunc)
{
TraceError("ResourceManager::GetResourcePointer: NOT SUPPORT FILE %s", c_pszFile);
return NULL;
}
pResource = InsertResourcePointer(dwFileCRC, newFunc(c_pszFile));
return pResource;
}
CResource * CResourceManager::GetResourcePointer(const char * c_szFileName)
{
if (!c_szFileName || !*c_szFileName)
{
TraceError("CResourceManager::GetResourcePointer: filename error!");
return NULL;
}
const char * c_pszFile;
DWORD dwFileCRC = __GetFileCRC(c_szFileName, &c_pszFile);
CResource * pResource = FindResourcePointer(dwFileCRC);
if (pResource) // 이미 리소스가 있으면 리턴 한다.
return pResource;
const char * pcFileExt = strrchr(c_pszFile, '.');
#ifdef _DEBUG
if (!IsFileExist(c_szFileName) )
{
if( pcFileExt == NULL || (stricmp( pcFileExt, ".fnt" ) != 0) ) {
TraceError("CResourceManager::GetResourcePointer: File not exist %s", c_szFileName);
}
}
#endif
CResource * (*newFunc) (const char *) = NULL;
if (pcFileExt)
{
static char s_szFileExt[8 + 1];
strncpy(s_szFileExt, pcFileExt + 1, 8);
TResourceNewFunctionPointerMap::iterator f = m_pResNewFuncMap.find(s_szFileExt);
if (m_pResNewFuncMap.end() != f)
newFunc = f->second;
}
if (!newFunc)
{
TraceError("ResourceManager::GetResourcePointer: NOT SUPPORT FILE %s", c_pszFile);
return NULL;
}
pResource = InsertResourcePointer(dwFileCRC, newFunc(c_pszFile));
return pResource;
}
CResource * CResourceManager::FindResourcePointer(DWORD dwFileCRC)
{
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
if (m_pResMap.end() == itor)
return NULL;
return itor->second;
}
bool CResourceManager::isResourcePointerData(DWORD dwFileCRC)
{
TResourcePointerMap::iterator itor = m_pResMap.find(dwFileCRC);
if (m_pResMap.end() == itor)
return NULL;
return (itor->second)->IsData();
}
DWORD CResourceManager::__GetFileCRC(const char * c_szFileName, const char ** c_ppszLowerFileName)
{
static char s_szFullPathFileName[MAX_PATH];
const char * src = c_szFileName;
char * dst = s_szFullPathFileName;
int len = 0;
while (src[len])
{
if (src[len]=='/')
dst[len] = '\\';
else
dst[len] = (char) korean_tolower(src[len]);
++len;
}
dst[len] = '\0';
if (c_ppszLowerFileName)
*c_ppszLowerFileName = &s_szFullPathFileName[0];
return (GetCRC32(s_szFullPathFileName, len));
}
typedef struct SDumpData
{
const char * filename;
float KB;
DWORD cost;
} TDumpData;
bool DumpKBCompare(const TDumpData& lhs, const TDumpData& rhs)
{
return (lhs.KB > rhs.KB) ? true : false;
}
bool DumpCostCompare(const TDumpData& lhs, const TDumpData& rhs)
{
return (lhs.cost > rhs.cost) ? true : false;
}
struct FDumpPrint
{
FILE * m_fp;
static float m_totalKB;
void operator () (TDumpData & data)
{
m_totalKB += data.KB;
fprintf(m_fp, "%6.1f %s\n", data.KB, data.filename);
}
};
float FDumpPrint::m_totalKB;
struct FDumpCostPrint
{
FILE * m_fp;
void operator() (TDumpData & data)
{
fprintf(m_fp, "%-4d %s\n", data.cost, data.filename);
}
};
void CResourceManager::DumpFileListToTextFile(const char* c_szFileName)
{
std::vector<TDumpData> dumpVector;
for (TResourcePointerMap::iterator i = m_pResMap.begin(); i != m_pResMap.end(); ++i)
{
CResource* pResource = i->second;
TDumpData data;
if (pResource->IsEmpty())
continue;
data.filename = pResource->GetFileName();
int filesize;
const char * ext = strrchr(data.filename, '.');
if (pResource->IsType(CGraphicImage::Type()) && strnicmp(ext, ".sub", 4))
filesize = ((CGraphicImage*) pResource)->GetWidth() * ((CGraphicImage*) pResource)->GetHeight() * 4;
else
{
FILE * fp2 = fopen(data.filename, "rb");
if (fp2)
{
fseek(fp2, 0L, SEEK_END);
filesize = ftell(fp2);
fclose(fp2);
}
else
filesize = 0;
}
data.KB = (float) filesize / (float) 1024;
data.cost = pResource->GetLoadCostMilliSecond();
dumpVector.push_back(data);
}
FILE * fp = fopen(c_szFileName, "w");
if (fp)
{
std::sort(dumpVector.begin(), dumpVector.end(), DumpKBCompare);
FDumpPrint DumpPrint;
DumpPrint.m_fp = fp;
DumpPrint.m_totalKB = 0;
std::for_each(dumpVector.begin(), dumpVector.end(), DumpPrint);
fprintf(fp, "total: %.2fmb", DumpPrint.m_totalKB / 1024.0f);
FDumpCostPrint DumpCostPrint;
DumpCostPrint.m_fp = fp;
std::sort(dumpVector.begin(), dumpVector.end(), DumpCostCompare);
std::for_each(dumpVector.begin(), dumpVector.end(), DumpCostPrint);
fprintf(fp, "total: %.2fmb", DumpPrint.m_totalKB / 1024.0f);
fclose(fp);
}
}
bool CResourceManager::IsFileExist(const char * c_szFileName)
{
return CEterPackManager::Instance().isExist(c_szFileName);
}
void CResourceManager::Update()
{
DWORD CurrentTime = ELTimer_GetMSec();
CResource * pResource;
int Count = 0;
TResourceDeletingMap::iterator itor = m_ResourceDeletingMap.begin();
while (itor != m_ResourceDeletingMap.end())
{
pResource = itor->first;
if (CurrentTime >= itor->second)
{
if (pResource->canDestroy())
{
//Tracef("Resource Clear %s\n", pResource->GetFileName());
pResource->Clear();
}
itor = m_ResourceDeletingMap.erase(itor);
if (++Count >= c_DeletingCountPerFrame)
break;
}
else
++itor;
}
ProcessBackgroundLoading();
}
void CResourceManager::ReserveDeletingResource(CResource * pResource)
{
DWORD dwCurrentTime = ELTimer_GetMSec();
m_ResourceDeletingMap.insert(TResourceDeletingMap::value_type(pResource, dwCurrentTime + c_Deleting_Wait_Time));
}
CResourceManager::CResourceManager()
{
//ms_loadingThread.Create(0);
}
CResourceManager::~CResourceManager()
{
Destroy();
//ms_loadingThread.Shutdown();
}
+73
View File
@@ -0,0 +1,73 @@
#pragma once
#include "Resource.h"
#include "FileLoaderThread.h"
#include <set>
#include <map>
#include <string>
class CResourceManager : public CSingleton<CResourceManager>
{
public:
CResourceManager();
virtual ~CResourceManager();
void LoadStaticCache(const char* c_szFileName);
void DestroyDeletingList();
void Destroy();
void BeginThreadLoading();
void EndThreadLoading();
CResource * InsertResourcePointer(DWORD dwFileCRC, CResource* pResource);
CResource * FindResourcePointer(DWORD dwFileCRC);
CResource * GetResourcePointer(const char * c_szFileName);
CResource * GetTypeResourcePointer(const char * c_szFileName, int iType=-1);
// 추가
bool isResourcePointerData(DWORD dwFileCRC);
void RegisterResourceNewFunctionPointer(const char* c_szFileExt, CResource* (*pResNewFunc)(const char* c_szFileName));
void RegisterResourceNewFunctionByTypePointer(int iType, CResource* (*pNewFunc) (const char* c_szFileName));
void DumpFileListToTextFile(const char* c_szFileName);
bool IsFileExist(const char * c_szFileName);
void Update();
void ReserveDeletingResource(CResource * pResource);
public:
void ProcessBackgroundLoading();
void PushBackgroundLoadingSet(std::set<std::string> & LoadingSet);
protected:
void __DestroyDeletingResourceMap();
void __DestroyResourceMap();
void __DestroyCacheMap();
DWORD __GetFileCRC(const char * c_szFileName, const char ** c_pszLowerFile = NULL);
protected:
typedef std::map<DWORD, CResource *> TResourcePointerMap;
typedef std::map<std::string, CResource* (*)(const char*)> TResourceNewFunctionPointerMap;
typedef std::map<int, CResource* (*)(const char*)> TResourceNewFunctionByTypePointerMap;
typedef std::map<CResource *, DWORD> TResourceDeletingMap;
typedef std::map<DWORD, std::string> TResourceRequestMap;
typedef std::map<long, CResource*> TResourceRefDecreaseWaitingMap;
protected:
TResourcePointerMap m_pCacheMap;
TResourcePointerMap m_pResMap;
TResourceNewFunctionPointerMap m_pResNewFuncMap;
TResourceNewFunctionByTypePointerMap m_pResNewFuncByTypeMap;
TResourceDeletingMap m_ResourceDeletingMap;
TResourceRequestMap m_RequestMap; // 쓰레드로 로딩 요청한 리스트
TResourceRequestMap m_WaitingMap;
TResourceRefDecreaseWaitingMap m_pResRefDecreaseWaitingMap;
static CFileLoaderThread ms_loadingThread;
};
extern int g_iLoadingDelayTime;
+52
View File
@@ -0,0 +1,52 @@
#include "StdAfx.h"
#include "ScreenFilter.h"
#include "StateManager.h"
void CScreenFilter::Render()
{
if (!m_bEnable)
return;
STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &ms_matIdentity);
STATEMANAGER.SaveTransform(D3DTS_VIEW, &ms_matIdentity);
STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, m_bySrcType);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, m_byDestType);
SetOrtho2D(CScreen::ms_iWidth, CScreen::ms_iHeight, 400.0f);
SetDiffuseColor(m_Color.r, m_Color.g, m_Color.b, m_Color.a);
RenderBar2d(0, 0, CScreen::ms_iWidth, CScreen::ms_iHeight);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
STATEMANAGER.RestoreTransform(D3DTS_VIEW);
STATEMANAGER.RestoreTransform(D3DTS_PROJECTION);
}
void CScreenFilter::SetEnable(BOOL /*bFlag*/)
{
m_bEnable = FALSE;
}
void CScreenFilter::SetBlendType(BYTE bySrcType, BYTE byDestType)
{
m_bySrcType = bySrcType;
m_byDestType = byDestType;
}
void CScreenFilter::SetColor(const D3DXCOLOR & c_rColor)
{
m_Color = c_rColor;
}
CScreenFilter::CScreenFilter()
{
m_bEnable = FALSE;
m_bySrcType = D3DBLEND_SRCALPHA;
m_byDestType = D3DBLEND_INVSRCALPHA;
m_Color = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f);
}
CScreenFilter::~CScreenFilter()
{
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "GrpScreen.h"
class CScreenFilter : public CScreen
{
public:
CScreenFilter();
virtual ~CScreenFilter();
void SetEnable(BOOL bFlag);
void SetBlendType(BYTE bySrcType, BYTE byDestType);
void SetColor(const D3DXCOLOR & c_rColor);
void Render();
protected:
BOOL m_bEnable;
BYTE m_bySrcType;
BYTE m_byDestType;
D3DXCOLOR m_Color;
};
+188
View File
@@ -0,0 +1,188 @@
// SkyBox.h: interface for the CSkyBox class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_)
#define AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "GrpBase.h"
#include "GrpScreen.h"
#include "GrpImageInstance.h"
#include "ColorTransitionHelper.h"
#include <map>
#include <string>
typedef struct SColor
{
SColor(float _r = 0.0f, float _g = 0.0f, float _b = 0.0f, float _a = 0.0f) : r(_r), g(_g), b(_b), a(_a){}
float r, g, b, a;
} TColor;
typedef struct
{
TColor m_FirstColor;
TColor m_SecondColor;
}TGradientColor;
typedef std::vector<TGradientColor> TVectorGradientColor;
typedef TVectorGradientColor::iterator TVectorGradientIterator;
class CSkyObjectQuad
{
public:
CSkyObjectQuad();
virtual ~CSkyObjectQuad();
void Clear(const unsigned char & c_rucNumVertex,
const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha);
void SetSrcColor(const unsigned char & c_rucNumVertex,
const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha);
void SetTransition(const unsigned char & c_rucNumVertex,
const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha,
DWORD dwDuration);
void SetVertex(const unsigned char & c_rucNumVertex, const TPDTVertex & c_rPDTVertex);
void StartTransition();
bool Update();
void Render();
private:
TPDTVertex m_Vertex[4];
TIndex m_Indices[4]; // 인덱스 버퍼...
CColorTransitionHelper m_Helper[4];
};
class CSkyObject : public CScreen
{
public:
enum
{
SKY_RENDER_MODE_DEFAULT, // = SKY_RENDER_MODE_TEXTURE
SKY_RENDER_MODE_DIFFUSE,
SKY_RENDER_MODE_TEXTURE,
SKY_RENDER_MODE_MODULATE,
SKY_RENDER_MODE_MODULATE2X,
SKY_RENDER_MODE_MODULATE4X,
};
CSkyObject();
virtual ~CSkyObject();
virtual void Destroy() = 0;
virtual void Render() = 0;
virtual void Update() = 0;
virtual void StartTransition();
void SetRenderMode(unsigned char ucRenderMode) { m_ucRenderMode = ucRenderMode; }
const bool & isTransitionStarted() { return m_bTransitionStarted; }
protected:
CGraphicImageInstance * GenerateTexture(const char * szfilename);
void DeleteTexture(CGraphicImageInstance * pGraphicImageInstance);
protected:
//////////////////////////////////////////////////////////////////////////
// 타입 정의
typedef std::vector<CSkyObjectQuad> TSkyObjectQuadVector;
typedef TSkyObjectQuadVector::iterator TSkyObjectQuadIterator;
typedef struct CSkyBox
{
void StartTransition();
bool Update();
void Render();
std::string m_strfacename;
std::string m_strFaceTextureFileName;
TSkyObjectQuadVector m_SkyObjectQuadVector;
}TSkyObjectFace;
typedef std::map <std::string, CGraphicImageInstance*> TGraphicImageInstanceMap;
//////////////////////////////////////////////////////////////////////////
// 구름...
TSkyObjectFace m_FaceCloud; // 구름 일단 한장...
D3DXMATRIX m_matWorldCloud, m_matTranslationCloud, m_matTextureCloud;
D3DXVECTOR3 m_v3PositionCloud;
float m_fCloudScaleX, m_fCloudScaleY, m_fCloudHeight;
float m_fCloudTextureScaleX, m_fCloudTextureScaleY;
float m_fCloudScrollSpeedU, m_fCloudScrollSpeedV;
float m_fCloudPositionU, m_fCloudPositionV;
DWORD m_dwlastTime;
// 스카이 박스 이미지...
TGraphicImageInstanceMap m_GraphicImageInstanceMap;
// Transform...
D3DXMATRIX m_matWorld, m_matTranslation;
D3DXVECTOR3 m_v3Position;
float m_fScaleX, m_fScaleY, m_fScaleZ;
// 랜더링 관련... 임시 변수..
unsigned char m_ucRenderMode;
std::string m_strCurTime;
bool m_bTransitionStarted;
bool m_bSkyMatrixUpdated;
CGraphicImageInstance m_CloudAlphaImageInstance;
};
class CSkyBox : public CSkyObject
{
public:
CSkyBox();
virtual ~CSkyBox();
void Update();
void Render();
void RenderCloud();
void Destroy();
void Unload();
void SetSkyBoxScale(const D3DXVECTOR3 & c_rv3Scale);
void SetGradientLevel(BYTE byUpper, BYTE byLower);
void SetFaceTexture( const char* c_szFileName, int iFaceIndex );
void SetCloudTexture(const char * c_szFileName);
void SetCloudScale(const D3DXVECTOR2 & c_rv2CloudScale);
void SetCloudHeight(float fHeight);
void SetCloudTextureScale(const D3DXVECTOR2 & c_rv2CloudTextureScale);
void SetCloudScrollSpeed(const D3DXVECTOR2 & c_rv2CloudScrollSpeed);
void SetCloudColor(const TGradientColor & c_rColor, const TGradientColor & c_rNextColor, const DWORD & dwTransitionTime);
void Refresh();
void SetSkyColor(const TVectorGradientColor & c_rColorVector, const TVectorGradientColor & c_rNextColorVector, long lTransitionTime);
void StartTransition();
protected:
void SetSkyObjectQuadVertical(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR2 * c_pv2QuadPoints);
void SetSkyObjectQuadHorizon(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR3 * c_pv3QuadPoints);
//void UpdateSkyFaceQuadTransform(D3DXVECTOR3 * c_pv3QuadPoints);
protected:
unsigned char m_ucVirticalGradientLevelUpper;
unsigned char m_ucVirticalGradientLevelLower;
TSkyObjectFace m_Faces[6];
};
#endif // !defined(AFX_SKYBOX_H__AB5049E1_8F1C_4C35_9406_45EC7EF4AD1B__INCLUDED_)
+769
View File
@@ -0,0 +1,769 @@
#include "StdAfx.h"
#include "StateManager.h"
//#define StateManager_Assert(a) if (!(a)) puts("assert"#a)
#define StateManager_Assert(a) assert(a)
struct SLightData
{
enum
{
LIGHT_NUM = 8,
};
D3DLIGHT8 m_akD3DLight[LIGHT_NUM];
} m_kLightData;
void CStateManager::SetLight(DWORD index, CONST D3DLIGHT8* pLight)
{
assert(index<SLightData::LIGHT_NUM);
m_kLightData.m_akD3DLight[index]=*pLight;
m_lpD3DDev->SetLight(index, pLight);
}
void CStateManager::GetLight(DWORD index, D3DLIGHT8* pLight)
{
assert(index<8);
*pLight=m_kLightData.m_akD3DLight[index];
}
bool CStateManager::BeginScene()
{
m_bScene=true;
D3DXMATRIX m4Proj;
D3DXMATRIX m4View;
D3DXMATRIX m4World;
GetTransform(D3DTS_WORLD, &m4World);
GetTransform(D3DTS_PROJECTION, &m4Proj);
GetTransform(D3DTS_VIEW, &m4View);
SetTransform(D3DTS_WORLD, &m4World);
SetTransform(D3DTS_PROJECTION, &m4Proj);
SetTransform(D3DTS_VIEW, &m4View);
if (FAILED(m_lpD3DDev->BeginScene()))
return false;
return true;
}
void CStateManager::EndScene()
{
m_lpD3DDev->EndScene();
m_bScene=false;
}
CStateManager::CStateManager(LPDIRECT3DDEVICE8 lpDevice) : m_lpD3DDev(NULL)
{
m_bScene = false;
m_dwBestMinFilter = D3DTEXF_LINEAR;
m_dwBestMagFilter = D3DTEXF_LINEAR;
SetDevice(lpDevice);
}
CStateManager::~CStateManager()
{
if (m_lpD3DDev)
{
m_lpD3DDev->Release();
m_lpD3DDev = NULL;
}
}
void CStateManager::SetDevice(LPDIRECT3DDEVICE8 lpDevice)
{
StateManager_Assert(lpDevice);
lpDevice->AddRef();
if (m_lpD3DDev)
{
m_lpD3DDev->Release();
m_lpD3DDev = NULL;
}
m_lpD3DDev = lpDevice;
D3DCAPS8 d3dCaps;
m_lpD3DDev->GetDeviceCaps(&d3dCaps);
if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC)
m_dwBestMagFilter = D3DTEXF_ANISOTROPIC;
else
m_dwBestMagFilter = D3DTEXF_LINEAR;
if (d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC)
m_dwBestMinFilter = D3DTEXF_ANISOTROPIC;
else
m_dwBestMinFilter = D3DTEXF_LINEAR;
DWORD dwMax = d3dCaps.MaxAnisotropy;
dwMax = dwMax < 4 ? dwMax : 4;
for (int i = 0; i < 8; ++i)
m_lpD3DDev->SetTextureStageState(i, D3DTSS_MAXANISOTROPY, dwMax);
SetDefaultState();
}
void CStateManager::SetBestFiltering(DWORD dwStage)
{
SetTextureStageState(dwStage, D3DTSS_MINFILTER, m_dwBestMinFilter);
SetTextureStageState(dwStage, D3DTSS_MAGFILTER, m_dwBestMagFilter);
SetTextureStageState(dwStage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
}
void CStateManager::Restore()
{
int i, j;
m_bForce = true;
for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; ++i)
SetRenderState(D3DRENDERSTATETYPE(i), m_CurrentState.m_RenderStates[i]);
for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i)
for (j = 0; j < STATEMANAGER_MAX_TEXTURESTATES; ++j)
SetTextureStageState(i, D3DTEXTURESTAGESTATETYPE(j), m_CurrentState.m_TextureStates[i][j]);
for (i = 0; i < STATEMANAGER_MAX_STAGES; ++i)
SetTexture(i, m_CurrentState.m_Textures[i]);
m_bForce = false;
}
void CStateManager::SetDefaultState()
{
m_CurrentState.ResetState();
m_CopyState.ResetState();
m_ChipState.ResetState();
m_bScene = false;
m_bForce = true;
D3DXMATRIX Identity;
D3DXMatrixIdentity(&Identity);
SetTransform(D3DTS_WORLD, &Identity);
SetTransform(D3DTS_VIEW, &Identity);
SetTransform(D3DTS_PROJECTION, &Identity);
D3DMATERIAL8 DefaultMat;
ZeroMemory(&DefaultMat, sizeof(D3DMATERIAL8));
DefaultMat.Diffuse.r = 1.0f;
DefaultMat.Diffuse.g = 1.0f;
DefaultMat.Diffuse.b = 1.0f;
DefaultMat.Diffuse.a = 1.0f;
DefaultMat.Ambient.r = 1.0f;
DefaultMat.Ambient.g = 1.0f;
DefaultMat.Ambient.b = 1.0f;
DefaultMat.Ambient.a = 1.0f;
DefaultMat.Emissive.r = 0.0f;
DefaultMat.Emissive.g = 0.0f;
DefaultMat.Emissive.b = 0.0f;
DefaultMat.Emissive.a = 0.0f;
DefaultMat.Specular.r = 0.0f;
DefaultMat.Specular.g = 0.0f;
DefaultMat.Specular.b = 0.0f;
DefaultMat.Specular.a = 0.0f;
DefaultMat.Power = 0.0f;
SetMaterial(&DefaultMat);
SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_LINEPATTERN, 0xFFFFFFFF);
SetRenderState(D3DRS_LASTPIXEL, FALSE);
SetRenderState(D3DRS_ALPHAREF, 1);
SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
SetRenderState(D3DRS_ZVISIBLE, FALSE);
SetRenderState(D3DRS_FOGSTART, 0);
SetRenderState(D3DRS_FOGEND, 0);
SetRenderState(D3DRS_FOGDENSITY, 0);
SetRenderState(D3DRS_EDGEANTIALIAS, FALSE);
SetRenderState(D3DRS_ZBIAS, 0);
SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
SetRenderState(D3DRS_AMBIENT, 0x00000000);
SetRenderState(D3DRS_LOCALVIEWER, FALSE);
SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
SetRenderState(D3DRS_COLORWRITEENABLE, 0xFFFFFFFF);
SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
SetRenderState(D3DRS_FOGENABLE, FALSE);
SetRenderState(D3DRS_FOGCOLOR, 0xFF000000);
SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
SetRenderState(D3DRS_ZENABLE, TRUE);
SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
SetRenderState(D3DRS_DITHERENABLE, TRUE);
SetRenderState(D3DRS_STENCILENABLE, FALSE);
SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
SetRenderState(D3DRS_CLIPPING, TRUE);
SetRenderState(D3DRS_LIGHTING, FALSE);
SetRenderState(D3DRS_SPECULARENABLE, FALSE);
SetRenderState(D3DRS_COLORVERTEX, FALSE);
SetRenderState(D3DRS_WRAP0, 0);
SetRenderState(D3DRS_WRAP1, 0);
SetRenderState(D3DRS_WRAP2, 0);
SetRenderState(D3DRS_WRAP3, 0);
SetRenderState(D3DRS_WRAP4, 0);
SetRenderState(D3DRS_WRAP5, 0);
SetRenderState(D3DRS_WRAP6, 0);
SetRenderState(D3DRS_WRAP7, 0);
SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(2, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(3, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(3, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(3, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(4, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(4, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(4, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(4, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(4, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(4, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(5, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(5, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(5, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(5, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(5, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(5, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(6, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(6, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(6, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(6, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(6, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(6, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(7, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(7, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(7, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(7, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(7, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(7, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 2);
SetTextureStageState(3, D3DTSS_TEXCOORDINDEX, 3);
SetTextureStageState(4, D3DTSS_TEXCOORDINDEX, 4);
SetTextureStageState(5, D3DTSS_TEXCOORDINDEX, 5);
SetTextureStageState(6, D3DTSS_TEXCOORDINDEX, 6);
SetTextureStageState(7, D3DTSS_TEXCOORDINDEX, 7);
SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
SetTextureStageState(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
SetTextureStageState(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
SetTextureStageState(2, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
SetTextureStageState(3, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
SetTextureStageState(3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
SetTextureStageState(3, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
SetTextureStageState(4, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
SetTextureStageState(4, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
SetTextureStageState(4, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
SetTextureStageState(5, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
SetTextureStageState(5, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
SetTextureStageState(5, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
SetTextureStageState(6, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
SetTextureStageState(6, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
SetTextureStageState(6, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
SetTextureStageState(7, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
SetTextureStageState(7, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
SetTextureStageState(7, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
SetTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
SetTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
SetTextureStageState(4, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
SetTextureStageState(4, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
SetTextureStageState(5, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
SetTextureStageState(5, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
SetTextureStageState(6, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
SetTextureStageState(6, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
SetTextureStageState(7, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
SetTextureStageState(7, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
SetTextureStageState(2, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
SetTextureStageState(3, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
SetTextureStageState(4, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
SetTextureStageState(5, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
SetTextureStageState(6, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
SetTextureStageState(7, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
SetTexture(0, NULL);
SetTexture(1, NULL);
SetTexture(2, NULL);
SetTexture(3, NULL);
SetTexture(4, NULL);
SetTexture(5, NULL);
SetTexture(6, NULL);
SetTexture(7, NULL);
SetPixelShader(0);
SetVertexShader(D3DFVF_XYZ);
D3DXVECTOR4 av4Null[STATEMANAGER_MAX_VCONSTANTS];
memset(av4Null, 0, sizeof(av4Null));
SetVertexShaderConstant(0, av4Null, STATEMANAGER_MAX_VCONSTANTS);
SetPixelShaderConstant(0, av4Null, STATEMANAGER_MAX_PCONSTANTS);
m_bForce = false;
#ifdef _DEBUG
int i, j;
for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; i++)
m_bRenderStateSavingFlag[i] = FALSE;
for (j = 0; j < STATEMANAGER_MAX_TRANSFORMSTATES; j++)
m_bTransformSavingFlag[j] = FALSE;
for (j = 0; j < STATEMANAGER_MAX_STAGES; ++j)
for (i = 0; i < STATEMANAGER_MAX_TEXTURESTATES; ++i)
m_bTextureStageStateSavingFlag[j][i] = FALSE;
#endif _DEBUG
}
// Material
void CStateManager::SaveMaterial()
{
m_CopyState.m_D3DMaterial = m_CurrentState.m_D3DMaterial;
}
void CStateManager::SaveMaterial(const D3DMATERIAL8 * pMaterial)
{
// Check that we have set this up before, if not, the default is this.
m_CopyState.m_D3DMaterial = m_CurrentState.m_D3DMaterial;
SetMaterial(pMaterial);
}
void CStateManager::RestoreMaterial()
{
SetMaterial(&m_CopyState.m_D3DMaterial);
}
void CStateManager::SetMaterial(const D3DMATERIAL8 * pMaterial)
{
m_lpD3DDev->SetMaterial(pMaterial);
m_CurrentState.m_D3DMaterial = *pMaterial;
}
void CStateManager::GetMaterial(D3DMATERIAL8 * pMaterial)
{
// Set the renderstate and remember it.
*pMaterial = m_CurrentState.m_D3DMaterial;
}
// Renderstates
DWORD CStateManager::GetRenderState(D3DRENDERSTATETYPE Type)
{
return m_CurrentState.m_RenderStates[Type];
}
void CStateManager::SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue)
{
#ifdef _DEBUG
if (m_bRenderStateSavingFlag[Type])
{
Tracef(" CStateManager::SaveRenderState - This render state is already saved [%d, %d]\n", Type, dwValue);
StateManager_Assert(!" This render state is already saved!");
}
m_bRenderStateSavingFlag[Type] = TRUE;
#endif _DEBUG
// Check that we have set this up before, if not, the default is this.
m_CopyState.m_RenderStates[Type] = m_CurrentState.m_RenderStates[Type];
SetRenderState(Type, dwValue);
}
void CStateManager::RestoreRenderState(D3DRENDERSTATETYPE Type)
{
#ifdef _DEBUG
if (!m_bRenderStateSavingFlag[Type])
{
Tracef(" CStateManager::SaveRenderState - This render state was not saved [%d, %d]\n", Type);
StateManager_Assert(!" This render state was not saved!");
}
m_bRenderStateSavingFlag[Type] = FALSE;
#endif _DEBUG
SetRenderState(Type, m_CopyState.m_RenderStates[Type]);
}
void CStateManager::SetRenderState(D3DRENDERSTATETYPE Type, DWORD Value)
{
if (m_CurrentState.m_RenderStates[Type] == Value)
return;
m_lpD3DDev->SetRenderState(Type, Value);
m_CurrentState.m_RenderStates[Type] = Value;
}
void CStateManager::GetRenderState(D3DRENDERSTATETYPE Type, DWORD * pdwValue)
{
*pdwValue = m_CurrentState.m_RenderStates[Type];
}
// Textures
void CStateManager::SaveTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture)
{
// Check that we have set this up before, if not, the default is this.
m_CopyState.m_Textures[dwStage] = m_CurrentState.m_Textures[dwStage];
SetTexture(dwStage, pTexture);
}
void CStateManager::RestoreTexture(DWORD dwStage)
{
SetTexture(dwStage, m_CopyState.m_Textures[dwStage]);
}
void CStateManager::SetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture)
{
if (pTexture == m_CurrentState.m_Textures[dwStage])
return;
m_lpD3DDev->SetTexture(dwStage, pTexture);
m_CurrentState.m_Textures[dwStage] = pTexture;
}
void CStateManager::GetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 * ppTexture)
{
*ppTexture = m_CurrentState.m_Textures[dwStage];
}
// Texture stage states
void CStateManager::SaveTextureStageState(DWORD dwStage,D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue)
{
// Check that we have set this up before, if not, the default is this.
#ifdef _DEBUG
if (m_bTextureStageStateSavingFlag[dwStage][Type])
{
Tracef(" CStateManager::SaveTextureStageState - This texture stage state is already saved [%d, %d]\n", dwStage, Type);
StateManager_Assert(!" This texture stage state is already saved!");
}
m_bTextureStageStateSavingFlag[dwStage][Type] = TRUE;
#endif _DEBUG
m_CopyState.m_TextureStates[dwStage][Type] = m_CurrentState.m_TextureStates[dwStage][Type];
SetTextureStageState(dwStage, Type, dwValue);
}
void CStateManager::RestoreTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type)
{
#ifdef _DEBUG
if (!m_bTextureStageStateSavingFlag[dwStage][Type])
{
Tracef(" CStateManager::RestoreTextureStageState - This texture stage state was not saved [%d, %d]\n", dwStage, Type);
StateManager_Assert(!" This texture stage state was not saved!");
}
m_bTextureStageStateSavingFlag[dwStage][Type] = FALSE;
#endif _DEBUG
SetTextureStageState(dwStage, Type, m_CopyState.m_TextureStates[dwStage][Type]);
}
void CStateManager::SetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue)
{
if (m_CurrentState.m_TextureStates[dwStage][Type] == dwValue)
return;
m_lpD3DDev->SetTextureStageState(dwStage, Type, dwValue);
m_CurrentState.m_TextureStates[dwStage][Type] = dwValue;
}
void CStateManager::GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD * pdwValue)
{
*pdwValue = m_CurrentState.m_TextureStates[dwStage][Type];
}
// Vertex Shader
void CStateManager::SaveVertexShader(DWORD dwShader)
{
m_CopyState.m_dwVertexShader = m_CurrentState.m_dwVertexShader;
SetVertexShader(dwShader);
}
void CStateManager::RestoreVertexShader()
{
SetVertexShader(m_CopyState.m_dwVertexShader);
}
void CStateManager::SetVertexShader(DWORD dwShader)
{
if (m_CurrentState.m_dwVertexShader == dwShader)
return;
m_lpD3DDev->SetVertexShader(dwShader);
m_CurrentState.m_dwVertexShader = dwShader;
}
void CStateManager::GetVertexShader(DWORD * pdwShader)
{
*pdwShader = m_CurrentState.m_dwVertexShader;
}
// Pixel Shader
void CStateManager::SavePixelShader(DWORD dwShader)
{
m_CopyState.m_dwPixelShader = m_CurrentState.m_dwPixelShader;
SetPixelShader(dwShader);
}
void CStateManager::RestorePixelShader()
{
SetPixelShader(m_CopyState.m_dwPixelShader);
}
void CStateManager::SetPixelShader(DWORD dwShader)
{
if (m_CurrentState.m_dwPixelShader == dwShader)
return;
m_lpD3DDev->SetPixelShader(dwShader);
m_CurrentState.m_dwPixelShader = dwShader;
}
void CStateManager::GetPixelShader(DWORD * pdwShader)
{
*pdwShader = m_CurrentState.m_dwPixelShader;
}
// *** These states are cached, but not protected from multiple sends of the same value.
// Transform
void CStateManager::SaveTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix)
{
#ifdef _DEBUG
if (m_bTransformSavingFlag[Type])
{
Tracef(" CStateManager::SaveTransform - This transform is already saved [%d]\n", Type);
StateManager_Assert(!" This trasform is already saved!");
}
m_bTransformSavingFlag[Type] = TRUE;
#endif _DEBUG
m_CopyState.m_Matrices[Type] = m_CurrentState.m_Matrices[Type];
SetTransform(Type, (D3DXMATRIX *)pMatrix);
}
void CStateManager::RestoreTransform(D3DTRANSFORMSTATETYPE Type)
{
#ifdef _DEBUG
if (!m_bTransformSavingFlag[Type])
{
Tracef(" CStateManager::RestoreTransform - This transform was not saved [%d]\n", Type);
StateManager_Assert(!" This render state was not saved!");
}
m_bTransformSavingFlag[Type] = FALSE;
#endif _DEBUG
SetTransform(Type, &m_CopyState.m_Matrices[Type]);
}
// Don't cache-check the transform. To much to do
void CStateManager::SetTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix)
{
if (m_bScene)
{
m_lpD3DDev->SetTransform(Type, pMatrix);
}
else
{
assert(D3DTS_VIEW==Type || D3DTS_PROJECTION==Type || D3DTS_WORLD==Type);
}
m_CurrentState.m_Matrices[Type] = *pMatrix;
}
void CStateManager::GetTransform(D3DTRANSFORMSTATETYPE Type, D3DMATRIX * pMatrix)
{
*pMatrix = m_CurrentState.m_Matrices[Type];
}
// SetVertexShaderConstant
void CStateManager::SaveVertexShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
{
DWORD i;
for (i = 0; i < dwConstantCount; i++)
{
StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
m_CopyState.m_VertexShaderConstants[dwRegister + i] = m_CurrentState.m_VertexShaderConstants[dwRegister + i];
}
SetVertexShaderConstant(dwRegister, pConstantData, dwConstantCount);
}
void CStateManager::RestoreVertexShaderConstant(DWORD dwRegister, DWORD dwConstantCount)
{
SetVertexShaderConstant(dwRegister, &m_CopyState.m_VertexShaderConstants[dwRegister], dwConstantCount);
}
void CStateManager::SetVertexShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
{
m_lpD3DDev->SetVertexShaderConstant(dwRegister, pConstantData, dwConstantCount);
// Set the renderstate and remember it.
for (DWORD i = 0; i < dwConstantCount; i++)
{
StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
m_CurrentState.m_VertexShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
}
}
// SetPixelShaderConstant
void CStateManager::SavePixelShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
{
DWORD i;
for (i = 0; i < dwConstantCount; i++)
{
StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
m_CopyState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
}
SetPixelShaderConstant(dwRegister, pConstantData, dwConstantCount);
}
void CStateManager::RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount)
{
SetPixelShaderConstant(dwRegister, &m_CopyState.m_PixelShaderConstants[dwRegister], dwConstantCount);
}
void CStateManager::SetPixelShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
{
m_lpD3DDev->SetPixelShaderConstant(dwRegister, pConstantData, dwConstantCount);
// Set the renderstate and remember it.
for (DWORD i = 0; i < dwConstantCount; i++)
{
StateManager_Assert((dwRegister + i) < STATEMANAGER_MAX_VCONSTANTS);
m_CurrentState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
}
}
void CStateManager::SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData,UINT Stride)
{
// Check that we have set this up before, if not, the default is this.
m_CopyState.m_StreamData[StreamNumber] = m_CurrentState.m_StreamData[StreamNumber];
SetStreamSource(StreamNumber, pStreamData, Stride);
}
void CStateManager::RestoreStreamSource(UINT StreamNumber)
{
SetStreamSource(StreamNumber,
m_CopyState.m_StreamData[StreamNumber].m_lpStreamData,
m_CopyState.m_StreamData[StreamNumber].m_Stride);
}
void CStateManager::SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride)
{
CStreamData kStreamData(pStreamData, Stride);
if (m_CurrentState.m_StreamData[StreamNumber] == kStreamData)
return;
m_lpD3DDev->SetStreamSource(StreamNumber, pStreamData, Stride);
m_CurrentState.m_StreamData[StreamNumber] = kStreamData;
}
void CStateManager::SaveIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex)
{
m_CopyState.m_IndexData = m_CurrentState.m_IndexData;
SetIndices(pIndexData, BaseVertexIndex);
}
void CStateManager::RestoreIndices()
{
SetIndices(m_CopyState.m_IndexData.m_lpIndexData, m_CopyState.m_IndexData.m_BaseVertexIndex);
}
void CStateManager::SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex)
{
CIndexData kIndexData(pIndexData, BaseVertexIndex);
if (m_CurrentState.m_IndexData == kIndexData)
return;
m_lpD3DDev->SetIndices(pIndexData, BaseVertexIndex);
m_CurrentState.m_IndexData = kIndexData;
}
HRESULT CStateManager::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
{
return (m_lpD3DDev->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount));
}
HRESULT CStateManager::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride)
{
m_CurrentState.m_StreamData[0] = NULL;
return (m_lpD3DDev->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride));
}
HRESULT CStateManager::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount)
{
return (m_lpD3DDev->DrawIndexedPrimitive(PrimitiveType, minIndex, NumVertices, startIndex, primCount));
}
HRESULT CStateManager::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void * pIndexData, D3DFORMAT IndexDataFormat, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride)
{
m_CurrentState.m_IndexData = NULL;
m_CurrentState.m_StreamData[0] = NULL;
return (m_lpD3DDev->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride));
}
+341
View File
@@ -0,0 +1,341 @@
/******************************************************************************
Copyright (C) 1999, 2000 NVIDIA Corporation
This file is provided without support, instruction, or implied warranty of any
kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is
not liable under any circumstances for any damages or loss whatsoever arising
from the use or inability to use this file or items derived from it.
Comments:
A simple class to manage rendering state. Created as a singleton.
Create it as a static global, or with new. It doesn't matter as long as it is created
before you use the CStateManager::GetSingleton() API to get a reference to it.
Call it with STATEMANAGER.SetRenderState(...)
Call it with STATEMANAGER.SetTextureStageState(...), etc.
Call the 'Save' versions of the function if you want to deviate from the current state.
Call the 'Restore' version to retrieve the last Save.
There are two levels of caching:
- All Sets/Saves/Restores are tracked for redundancy. This reduces the size of the batch to
be flushed
- The flush function is called before rendering, and only copies state that is
different from the current chip state.
If you get an assert it is probably because an API call failed.
See NVLink for a good example of how this class is used.
Don't be afraid of the vector being used to track the flush batch. It will grow as big as
it needs to be and then stop, so it shouldn't be reallocated.
The state manager holds a reference to the d3d device.
- cmaughan@nvidia.com
******************************************************************************/
#ifndef __CSTATEMANAGER_H
#define __CSTATEMANAGER_H
#include <d3d8.h>
#include <d3dx8.h>
#include <vector>
#include "../EterBase/Singleton.h"
#define CHECK_D3DAPI(a) \
{ \
HRESULT hr = (a); \
\
if (hr != S_OK) \
assert(!#a); \
}
static const DWORD STATEMANAGER_MAX_RENDERSTATES = 256;
static const DWORD STATEMANAGER_MAX_TEXTURESTATES = 128;
static const DWORD STATEMANAGER_MAX_STAGES = 8;
static const DWORD STATEMANAGER_MAX_VCONSTANTS = 96;
static const DWORD STATEMANAGER_MAX_PCONSTANTS = 8;
static const DWORD STATEMANAGER_MAX_TRANSFORMSTATES = 300; // World1 lives way up there...
static const DWORD STATEMANAGER_MAX_STREAMS = 16;
class CStreamData
{
public:
CStreamData(LPDIRECT3DVERTEXBUFFER8 pStreamData = NULL, UINT Stride = 0) : m_lpStreamData(pStreamData), m_Stride(Stride)
{
}
bool operator == (const CStreamData& rhs) const
{
return ((m_lpStreamData == rhs.m_lpStreamData) && (m_Stride == rhs.m_Stride));
}
LPDIRECT3DVERTEXBUFFER8 m_lpStreamData;
UINT m_Stride;
};
class CIndexData
{
public:
CIndexData(LPDIRECT3DINDEXBUFFER8 pIndexData = NULL, UINT BaseVertexIndex = 0)
: m_lpIndexData(pIndexData),
m_BaseVertexIndex(BaseVertexIndex)
{
}
bool operator == (const CIndexData& rhs) const
{
return ((m_lpIndexData == rhs.m_lpIndexData) && (m_BaseVertexIndex == rhs.m_BaseVertexIndex));
}
LPDIRECT3DINDEXBUFFER8 m_lpIndexData;
UINT m_BaseVertexIndex;
};
// State types managed by the class
typedef enum eStateType
{
STATE_MATERIAL = 0,
STATE_RENDER,
STATE_TEXTURE,
STATE_TEXTURESTAGE,
STATE_VSHADER,
STATE_PSHADER,
STATE_TRANSFORM,
STATE_VCONSTANT,
STATE_PCONSTANT,
STATE_STREAM,
STATE_INDEX
} eStateType;
class CStateID
{
public:
CStateID(eStateType Type, DWORD dwValue0 = 0, DWORD dwValue1 = 0)
: m_Type(Type),
m_dwValue0(dwValue0),
m_dwValue1(dwValue1)
{
}
CStateID(eStateType Type, DWORD dwStage, D3DTEXTURESTAGESTATETYPE StageType)
: m_Type(Type),
m_dwStage(dwStage),
m_TextureStageStateType(StageType)
{
}
CStateID(eStateType Type, D3DRENDERSTATETYPE RenderType)
: m_Type(Type),
m_RenderStateType(RenderType)
{
}
eStateType m_Type;
union
{
DWORD m_dwValue0;
DWORD m_dwStage;
D3DRENDERSTATETYPE m_RenderStateType;
D3DTRANSFORMSTATETYPE m_TransformStateType;
};
union
{
DWORD m_dwValue1;
D3DTEXTURESTAGESTATETYPE m_TextureStageStateType;
};
};
typedef std::vector<CStateID> TStateID;
class CStateManagerState
{
public:
CStateManagerState()
{
}
void ResetState()
{
DWORD i, y;
for (i = 0; i < STATEMANAGER_MAX_RENDERSTATES; i++)
m_RenderStates[i] = 0x7FFFFFFF;
for (i = 0; i < STATEMANAGER_MAX_STAGES; i++)
for (y = 0; y < STATEMANAGER_MAX_TEXTURESTATES; y++)
m_TextureStates[i][y] = 0x7FFFFFFF;
for (i = 0; i < STATEMANAGER_MAX_STREAMS; i++)
m_StreamData[i] = CStreamData();
m_IndexData = CIndexData();
for (i = 0; i < STATEMANAGER_MAX_STAGES; i++)
m_Textures[i] = NULL;
// Matrices and constants are not cached, just restored. It's silly to check all the
// data elements (by which time the driver could have been sent them).
for (i = 0; i < STATEMANAGER_MAX_TRANSFORMSTATES; i++)
D3DXMatrixIdentity(&m_Matrices[i]);
for (i = 0; i < STATEMANAGER_MAX_VCONSTANTS; i++)
m_VertexShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
for (i = 0; i < STATEMANAGER_MAX_PCONSTANTS; i++)
m_PixelShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
m_dwPixelShader = 0;
m_dwVertexShader = D3DFVF_XYZ;
ZeroMemory(&m_Matrices, sizeof(D3DXMATRIX) * STATEMANAGER_MAX_TRANSFORMSTATES);
}
// Renderstates
DWORD m_RenderStates[STATEMANAGER_MAX_RENDERSTATES];
// Texture stage states
DWORD m_TextureStates[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES];
// Vertex shader constants
D3DXVECTOR4 m_VertexShaderConstants[STATEMANAGER_MAX_VCONSTANTS];
// Pixel shader constants
D3DXVECTOR4 m_PixelShaderConstants[STATEMANAGER_MAX_PCONSTANTS];
// Textures
LPDIRECT3DBASETEXTURE8 m_Textures[STATEMANAGER_MAX_STAGES];
// Shaders
DWORD m_dwPixelShader;
DWORD m_dwVertexShader;
D3DXMATRIX m_Matrices[STATEMANAGER_MAX_TRANSFORMSTATES];
D3DMATERIAL8 m_D3DMaterial;
CStreamData m_StreamData[STATEMANAGER_MAX_STREAMS];
CIndexData m_IndexData;
};
class CStateManager : public CSingleton<CStateManager>
{
public:
CStateManager(LPDIRECT3DDEVICE8 lpDevice);
virtual ~CStateManager();
void SetDefaultState();
void Restore();
bool BeginScene();
void EndScene();
// Material
void SaveMaterial();
void SaveMaterial(const D3DMATERIAL8 * pMaterial);
void RestoreMaterial();
void SetMaterial(const D3DMATERIAL8 * pMaterial);
void GetMaterial(D3DMATERIAL8 * pMaterial);
void SetLight(DWORD index, CONST D3DLIGHT8* pLight);
void GetLight(DWORD index, D3DLIGHT8* pLight);
// Renderstates
void SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue);
void RestoreRenderState(D3DRENDERSTATETYPE Type);
void SetRenderState(D3DRENDERSTATETYPE Type, DWORD Value);
void GetRenderState(D3DRENDERSTATETYPE Type, DWORD * pdwValue);
// Textures
void SaveTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture);
void RestoreTexture(DWORD dwStage);
void SetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 pTexture);
void GetTexture(DWORD dwStage, LPDIRECT3DBASETEXTURE8 * ppTexture);
// Texture stage states
void SaveTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue);
void RestoreTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type);
void SetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD dwValue);
void GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE Type, DWORD * pdwValue);
void SetBestFiltering(DWORD dwStage); // if possible set anisotropy filtering, or use trilinear
// Vertex Shader
void SaveVertexShader(DWORD dwShader);
void RestoreVertexShader();
void SetVertexShader(DWORD dwShader);
void GetVertexShader(DWORD * pdwShader);
// Pixel Shader
void SavePixelShader(DWORD dwShader);
void RestorePixelShader();
void SetPixelShader(DWORD dwShader);
void GetPixelShader(DWORD * pdwShader);
// *** These states are cached, but not protected from multiple sends of the same value.
// Transform
void SaveTransform(D3DTRANSFORMSTATETYPE Transform, const D3DMATRIX* pMatrix);
void RestoreTransform(D3DTRANSFORMSTATETYPE Transform);
// Don't cache-check the transform. To much to do
void SetTransform(D3DTRANSFORMSTATETYPE Type, const D3DMATRIX* pMatrix);
void GetTransform(D3DTRANSFORMSTATETYPE Type, D3DMATRIX * pMatrix);
// SetVertexShaderConstant
void SaveVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
void RestoreVertexShaderConstant(DWORD dwRegister, DWORD dwConstantCount);
void SetVertexShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
// SetPixelShaderConstant
void SavePixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
void RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount);
void SetPixelShaderConstant(DWORD dwRegister, CONST void* pConstantData, DWORD dwConstantCount);
void SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride);
void RestoreStreamSource(UINT StreamNumber);
void SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData, UINT Stride);
void SaveIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex);
void RestoreIndices();
void SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexData,UINT BaseVertexIndex);
HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);
HRESULT DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride);
HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount);
HRESULT DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void * pIndexData, D3DFORMAT IndexDataFormat, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride);
// Codes For Debug
DWORD GetRenderState(D3DRENDERSTATETYPE Type);
private:
void SetDevice(LPDIRECT3DDEVICE8 lpDevice);
private:
CStateManagerState m_ChipState;
CStateManagerState m_CurrentState;
CStateManagerState m_CopyState;
TStateID m_DirtyStates;
bool m_bForce;
bool m_bScene;
DWORD m_dwBestMinFilter;
DWORD m_dwBestMagFilter;
LPDIRECT3DDEVICE8 m_lpD3DDev;
#ifdef _DEBUG
// Saving Flag
BOOL m_bRenderStateSavingFlag[STATEMANAGER_MAX_RENDERSTATES];
BOOL m_bTextureStageStateSavingFlag[STATEMANAGER_MAX_STAGES][STATEMANAGER_MAX_TEXTURESTATES];
BOOL m_bTransformSavingFlag[STATEMANAGER_MAX_TRANSFORMSTATES];
#endif _DEBUG
};
#define STATEMANAGER (CStateManager::Instance())
#endif __CSTATEMANAGER_H
+142
View File
@@ -0,0 +1,142 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#define _WIN32_DCOM
#pragma warning(disable:4710) // not inlined
#pragma warning(disable:4786) // character 255 넘어가는거 끄기
#pragma warning(disable:4244) // type conversion possible lose of data
#pragma warning(disable:4018)
#pragma warning(disable:4245)
#pragma warning(disable:4512)
#pragma warning(disable:4201)
#if _MSC_VER >= 1400
#pragma warning(disable:4201 4512 4238 4239)
#endif
#include <d3d8.h>
#include <d3dx8.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma warning ( disable : 4201 )
#include <mmsystem.h>
#pragma warning ( default : 4201 )
#include <process.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <direct.h>
#include <malloc.h>
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "d3d8.lib")
#pragma comment(lib, "d3dx8.lib")
#include "../EterBase/StdAfx.h"
#include "../EterBase/Debug.h"
#include "../EterLocale/CodePageId.h"
#ifndef VC_EXTRALEAN
#include <winsock.h>
#endif
/*
#include "Pool.h"
#include "Dynamic.h"
#include "Event.h"
#include "FuncObject.h"
#include "ReferenceObject.h"
#include "Ref.h"
#include "Util.h"
#include "TextFileLoader.h"
#include "parser.h"
#include "Resource.h"
#include "ResourceManager.h"
#include "MSWindow.h"
#include "MSApplication.h"
#include "Mutex.h"
#include "Thread.h"
#include "GrpBase.h"
#include "GrpDIB.h"
#include "GrpMath.h"
#include "GrpDevice.h"
#include "CollisionData.h"
#include "GrpCollisionObject.h"
#include "GrpScreen.h"
#include "CullingManager.h"
// Attribute
#include "AttributeData.h"
#include "AttributeInstance.h"
#include "GrpObjectInstance.h"
#include "GrpRatioInstance.h"
#include "GrpD3DXBuffer.h"
#include "GrpTexture.h"
#include "GrpImageTexture.h"
#include "GrpFontTexture.h"
#include "GrpText.h"
#include "GrpImage.h"
#include "GrpSubImage.h"
#include "GrpIndexBuffer.h"
#include "GrpVertexBuffer.h"
#include "GrpVertexBufferStatic.h"
#include "GrpVertexBufferDynamic.h"
#include "GrpVertexShader.h"
#include "GrpPixelShader.h"
#include "GrpShadowTexture.h"
#include "GrpImageInstance.h"
#include "GrpExpandedImageInstance.h"
#include "GrpTextInstance.h"
#include "GrpLightManager.h"
#include "TargaResource.h"
#include "NetDevice.h"
#include "NetAddress.h"
// #include "NetStream.h"
#include "NetPacketHeaderMap.h"
#include "NetDatagramSender.h"
#include "NetDatagramReceiver.h"
#include "Input.h"
#include "IME.h"
#include "PathStack.h"
//#include "Property.h"
#include "Profiler.h"
#include "StateManager.h"
#include "ColorTransitionHelper.h"
#include "LensFlare.h"
#include "ScreenFilter.h"
#include "EnvironmentMap.h"
#include "lineintersect_utils.h"
#include "Decal.h"
*/
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include "DibBar.h"
class CTextBar : public CDibBar
{
public:
CTextBar(int fontSize, bool isBold);
virtual ~CTextBar();
void TextOut(int ix, int iy, const char * c_szText);
void SetTextColor(int r, int g, int b);
void GetTextExtent(const char * c_szText, SIZE* p_size);
protected:
void __SetFont(int fontSize, bool isBold);
void OnCreate();
protected:
HFONT m_hFont;
HFONT m_hOldFont;
int m_fontSize;
bool m_isBold;
};
+696
View File
@@ -0,0 +1,696 @@
#include "StdAfx.h"
#include "../EterBase/CRC32.h"
#include <string>
#include "../EterPack/EterPackManager.h"
#include "Pool.h"
#include "TextFileLoader.h"
std::map<DWORD, CTextFileLoader*> CTextFileLoader::ms_kMap_dwNameKey_pkTextFileLoader;
bool CTextFileLoader::ms_isCacheMode=false;
CDynamicPool<CTextFileLoader::SGroupNode> CTextFileLoader::SGroupNode::ms_kPool;
CTokenVector* CTextFileLoader::SGroupNode::GetTokenVector(const std::string& c_rstGroupName)
{
DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length());
std::map<DWORD, CTokenVector>::iterator f=m_kMap_dwKey_kVct_stToken.find(dwGroupNameKey);
if (m_kMap_dwKey_kVct_stToken.end()==f)
return NULL;
return &f->second;
}
bool CTextFileLoader::SGroupNode::IsExistTokenVector(const std::string& c_rstGroupName)
{
DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length());
if (m_kMap_dwKey_kVct_stToken.end()==m_kMap_dwKey_kVct_stToken.find(dwGroupNameKey))
return false;
return true;
}
void CTextFileLoader::SGroupNode::InsertTokenVector(const std::string& c_rstGroupName, const CTokenVector& c_rkVct_stToken)
{
DWORD dwGroupNameKey=GenNameKey(c_rstGroupName.c_str(), c_rstGroupName.length());
m_kMap_dwKey_kVct_stToken.insert(std::map<DWORD, CTokenVector>::value_type(dwGroupNameKey, c_rkVct_stToken));
}
DWORD CTextFileLoader::SGroupNode::GenNameKey(const char* c_szGroupName, UINT uGroupNameLen)
{
return GetCRC32(c_szGroupName, uGroupNameLen);
}
const std::string& CTextFileLoader::SGroupNode::GetGroupName()
{
return m_strGroupName;
}
bool CTextFileLoader::SGroupNode::IsGroupNameKey(DWORD dwGroupNameKey)
{
if (dwGroupNameKey==m_dwGroupNameKey)
return true;
return false;
}
void CTextFileLoader::SGroupNode::SetGroupName(const std::string& c_rstGroupName)
{
m_strGroupName=c_rstGroupName;
stl_lowers(m_strGroupName);
m_dwGroupNameKey=GenNameKey(m_strGroupName.c_str(), m_strGroupName.length());
}
CTextFileLoader::SGroupNode* CTextFileLoader::SGroupNode::New()
{
return ms_kPool.Alloc();
}
void CTextFileLoader::SGroupNode::Delete(SGroupNode* pkNode)
{
pkNode->m_kMap_dwKey_kVct_stToken.clear();
pkNode->ChildNodeVector.clear();
pkNode->m_strGroupName="";
pkNode->m_dwGroupNameKey=0;
ms_kPool.Free(pkNode);
}
void CTextFileLoader::SGroupNode::DestroySystem()
{
ms_kPool.Destroy();
}
CTextFileLoader* CTextFileLoader::Cache(const char* c_szFileName)
{
DWORD dwNameKey=GetCRC32(c_szFileName, strlen(c_szFileName));
std::map<DWORD, CTextFileLoader*>::iterator f=ms_kMap_dwNameKey_pkTextFileLoader.find(dwNameKey);
if (ms_kMap_dwNameKey_pkTextFileLoader.end()!=f)
{
if (!ms_isCacheMode)
{
delete f->second;
CTextFileLoader* pkNewTextFileLoader=new CTextFileLoader;
pkNewTextFileLoader->Load(c_szFileName);
f->second=pkNewTextFileLoader;
}
f->second->SetTop();
return f->second;
}
CTextFileLoader* pkNewTextFileLoader=new CTextFileLoader;
pkNewTextFileLoader->Load(c_szFileName);
ms_kMap_dwNameKey_pkTextFileLoader.insert(std::map<DWORD, CTextFileLoader*>::value_type(dwNameKey, pkNewTextFileLoader));
return pkNewTextFileLoader;
}
void CTextFileLoader::SetCacheMode()
{
ms_isCacheMode=true;
}
void CTextFileLoader::DestroySystem()
{
{
std::map<DWORD, CTextFileLoader*>::iterator i;
for (i=ms_kMap_dwNameKey_pkTextFileLoader.begin(); i!=ms_kMap_dwNameKey_pkTextFileLoader.end(); ++i)
delete i->second;
ms_kMap_dwNameKey_pkTextFileLoader.clear();
}
SGroupNode::DestroySystem();
}
void CTextFileLoader::Destroy()
{
__DestroyGroupNodeVector();
}
CTextFileLoader::CTextFileLoader()
{
SetTop();
m_acBufData=NULL;
m_dwBufSize=0;
m_dwBufCapacity=0;
m_GlobalNode.m_strGroupName = "global";
m_GlobalNode.pParentNode = NULL;
m_kVct_pkNode.reserve(128);
}
CTextFileLoader::~CTextFileLoader()
{
Destroy();
if (m_acBufData)
delete [] m_acBufData;
}
void CTextFileLoader::__DestroyGroupNodeVector()
{
std::vector<SGroupNode*>::iterator i;
for (i=m_kVct_pkNode.begin(); i!=m_kVct_pkNode.end(); ++i)
SGroupNode::Delete(*i);
m_kVct_pkNode.clear();
}
const char * CTextFileLoader::GetFileName()
{
return m_strFileName.c_str();
}
bool CTextFileLoader::IsEmpty()
{
return m_strFileName.empty();
}
bool CTextFileLoader::Load(const char * c_szFileName)
{
m_strFileName = "";
const VOID* pvData;
CMappedFile kFile;
if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
return false;
if (m_dwBufCapacity<kFile.Size())
{
m_dwBufCapacity=kFile.Size();
if (m_acBufData)
delete [] m_acBufData;
m_acBufData=new char[m_dwBufCapacity];
}
m_dwBufSize=kFile.Size();
memcpy(m_acBufData, pvData, m_dwBufSize);
m_strFileName = c_szFileName;
m_dwcurLineIndex = 0;
m_textFileLoader.Bind(m_dwBufSize, m_acBufData);
return LoadGroup(&m_GlobalNode);
}
bool CTextFileLoader::LoadGroup(TGroupNode * pGroupNode)
{
CTokenVector stTokenVector;
int nLocalGroupDepth = 0;
for (; m_dwcurLineIndex < m_textFileLoader.GetLineCount(); ++m_dwcurLineIndex)
{
int iRet;
if ((iRet = m_textFileLoader.SplitLine2(m_dwcurLineIndex, &stTokenVector)) != 0)
{
if (iRet == -2)
TraceError("cannot find \" in %s:%lu", m_strFileName.c_str(), m_dwcurLineIndex);
continue;
}
stl_lowers(stTokenVector[0]);
if ('{' == stTokenVector[0][0])
{
nLocalGroupDepth++;
continue;
}
if ('}' == stTokenVector[0][0]) {
nLocalGroupDepth--;
break;
}
// Group
if (0 == stTokenVector[0].compare("group"))
{
if (2 != stTokenVector.size())
{
assert(!"There is no group name!");
continue;
}
TGroupNode * pNewNode = TGroupNode::New();
m_kVct_pkNode.push_back(pNewNode);
pNewNode->pParentNode = pGroupNode;
pNewNode->SetGroupName(stTokenVector[1]);
pGroupNode->ChildNodeVector.push_back(pNewNode);
++m_dwcurLineIndex;
if( false == LoadGroup(pNewNode) )
return false;
}
// List
else if (0 == stTokenVector[0].compare("list"))
{
if (2 != stTokenVector.size())
{
assert(!"There is no list name!");
continue;
}
CTokenVector stSubTokenVector;
stl_lowers(stTokenVector[1]);
std::string key = stTokenVector[1];
stTokenVector.clear();
++m_dwcurLineIndex;
for (; m_dwcurLineIndex < m_textFileLoader.GetLineCount(); ++m_dwcurLineIndex)
{
if (!m_textFileLoader.SplitLine(m_dwcurLineIndex, &stSubTokenVector))
continue;
if ('{' == stSubTokenVector[0][0])
continue;
if ('}' == stSubTokenVector[0][0])
break;
for (DWORD j = 0; j < stSubTokenVector.size(); ++j)
{
stTokenVector.push_back(stSubTokenVector[j]);
}
}
pGroupNode->InsertTokenVector(key, stTokenVector);
//pGroupNode->LocalTokenVectorMap.insert(std::make_pair(key, stTokenVector));
}
else
{
std::string key = stTokenVector[0];
if (1 == stTokenVector.size())
{
TraceError("CTextFileLoader::LoadGroup : must have a value (filename: %s line: %d key: %s)",
m_strFileName.c_str(),
m_dwcurLineIndex,
key.c_str());
break;
}
stTokenVector.erase(stTokenVector.begin());
pGroupNode->InsertTokenVector(key, stTokenVector);
//pGroupNode->LocalTokenVectorMap.insert(std::make_pair(key, stTokenVector));
}
}
return (nLocalGroupDepth == 0);
}
void CTextFileLoader::SetTop()
{
m_pcurNode = &m_GlobalNode;
}
DWORD CTextFileLoader::GetChildNodeCount()
{
if (!m_pcurNode)
{
assert(!"Node to access has not set!");
return 0;
}
return m_pcurNode->ChildNodeVector.size();
}
BOOL CTextFileLoader::SetChildNode(const char * c_szKey)
{
if (!m_pcurNode)
{
assert(!"Node to access has not set!");
return FALSE;
}
DWORD dwKey=SGroupNode::GenNameKey(c_szKey, strlen(c_szKey));
for (DWORD i = 0; i < m_pcurNode->ChildNodeVector.size(); ++i)
{
TGroupNode * pGroupNode = m_pcurNode->ChildNodeVector[i];
if (pGroupNode->IsGroupNameKey(dwKey))
{
m_pcurNode = pGroupNode;
return TRUE;
}
}
return FALSE;
}
BOOL CTextFileLoader::SetChildNode(const std::string & c_rstrKeyHead, DWORD dwIndex)
{
char szKey[32+1];
_snprintf(szKey, sizeof(szKey), "%s%02u", c_rstrKeyHead.c_str(), dwIndex);
return SetChildNode(szKey);
}
BOOL CTextFileLoader::SetChildNode(DWORD dwIndex)
{
if (!m_pcurNode)
{
assert(!"Node to access has not set!");
return FALSE;
}
if (dwIndex >= m_pcurNode->ChildNodeVector.size())
{
assert(!"Node index to set is too large to access!");
return FALSE;
}
m_pcurNode = m_pcurNode->ChildNodeVector[dwIndex];
return TRUE;
}
BOOL CTextFileLoader::SetParentNode()
{
if (!m_pcurNode)
{
assert(!"Node to access has not set!");
return FALSE;
}
if (NULL == m_pcurNode->pParentNode)
{
assert(!"Current group node is already top!");
return FALSE;
}
m_pcurNode = m_pcurNode->pParentNode;
return TRUE;
}
BOOL CTextFileLoader::GetCurrentNodeName(std::string * pstrName)
{
if (!m_pcurNode)
return FALSE;
if (NULL == m_pcurNode->pParentNode)
return FALSE;
*pstrName = m_pcurNode->GetGroupName();
return TRUE;
}
BOOL CTextFileLoader::IsToken(const std::string & c_rstrKey)
{
if (!m_pcurNode)
{
assert(!"Node to access has not set!");
return FALSE;
}
return m_pcurNode->IsExistTokenVector(c_rstrKey);
//return m_pcurNode->LocalTokenVectorMap.end() != m_pcurNode->LocalTokenVectorMap.find(c_rstrKey);
}
BOOL CTextFileLoader::GetTokenVector(const std::string & c_rstrKey, CTokenVector ** ppTokenVector)
{
if (!m_pcurNode)
{
assert(!"Node to access has not set!");
return FALSE;
}
CTokenVector* pkRetTokenVector=m_pcurNode->GetTokenVector(c_rstrKey);
if (!pkRetTokenVector)
return FALSE;
*ppTokenVector = pkRetTokenVector;
//CTokenVectorMap::iterator itor = m_pcurNode->LocalTokenVectorMap.find(c_rstrKey);
//if (m_pcurNode->LocalTokenVectorMap.end() == itor)
//{
//Tracef(" CTextFileLoader::GetTokenVector - Failed to find the key %s [%s :: %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
// return FALSE;
//}
//*ppTokenVector = &itor->second;
return TRUE;
}
BOOL CTextFileLoader::GetTokenBoolean(const std::string & c_rstrKey, BOOL * pData)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->empty())
{
//Tracef(" CTextFileLoader::GetTokenBoolean - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
*pData = BOOL(atoi(pTokenVector->at(0).c_str()));
return TRUE;
}
BOOL CTextFileLoader::GetTokenByte(const std::string & c_rstrKey, BYTE * pData)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->empty())
{
//Tracef(" CTextFileLoader::GetTokenByte - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
*pData = BYTE(atoi(pTokenVector->at(0).c_str()));
return TRUE;
}
BOOL CTextFileLoader::GetTokenWord(const std::string & c_rstrKey, WORD * pData)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->empty())
{
//Tracef(" CTextFileLoader::GetTokenWord - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
*pData = WORD(atoi(pTokenVector->at(0).c_str()));
return TRUE;
}
BOOL CTextFileLoader::GetTokenInteger(const std::string & c_rstrKey, int * pData)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->empty())
{
//Tracef(" CTextFileLoader::GetTokenInteger - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
*pData = atoi(pTokenVector->at(0).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenDoubleWord(const std::string & c_rstrKey, DWORD * pData)
{
return GetTokenInteger(c_rstrKey, *(int **)(&pData));
}
BOOL CTextFileLoader::GetTokenFloat(const std::string & c_rstrKey, float * pData)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->empty())
{
//Tracef(" CTextFileLoader::GetTokenFloat - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
*pData = atof(pTokenVector->at(0).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenVector2(const std::string & c_rstrKey, D3DXVECTOR2 * pVector2)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->size() != 2)
{
//Tracef(" CTextFileLoader::GetTokenVector2 - This key should have 2 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
pVector2->x = atof(pTokenVector->at(0).c_str());
pVector2->y = atof(pTokenVector->at(1).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenVector3(const std::string & c_rstrKey, D3DXVECTOR3 * pVector3)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->size() != 3)
{
//Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
pVector3->x = atof(pTokenVector->at(0).c_str());
pVector3->y = atof(pTokenVector->at(1).c_str());
pVector3->z = atof(pTokenVector->at(2).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenVector4(const std::string & c_rstrKey, D3DXVECTOR4 * pVector4)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->size() != 4)
{
//Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
pVector4->x = atof(pTokenVector->at(0).c_str());
pVector4->y = atof(pTokenVector->at(1).c_str());
pVector4->z = atof(pTokenVector->at(2).c_str());
pVector4->w = atof(pTokenVector->at(3).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenPosition(const std::string & c_rstrKey, D3DXVECTOR3 * pVector)
{
return GetTokenVector3(c_rstrKey, pVector);
}
BOOL CTextFileLoader::GetTokenQuaternion(const std::string & c_rstrKey, D3DXQUATERNION * pQ)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->size() != 4)
{
//Tracef(" CTextFileLoader::GetTokenVector3 - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
pQ->x = atof(pTokenVector->at(0).c_str());
pQ->y = atof(pTokenVector->at(1).c_str());
pQ->z = atof(pTokenVector->at(2).c_str());
pQ->w = atof(pTokenVector->at(3).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenDirection(const std::string & c_rstrKey, D3DVECTOR * pVector)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->size() != 3)
{
//Tracef(" CTextFileLoader::GetTokenDirection - This key should have 3 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
pVector->x = atof(pTokenVector->at(0).c_str());
pVector->y = atof(pTokenVector->at(1).c_str());
pVector->z = atof(pTokenVector->at(2).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenColor(const std::string & c_rstrKey, D3DXCOLOR * pColor)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->size() != 4)
{
//Tracef(" CTextFileLoader::GetTokenColor - This key should have 4 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
pColor->r = atof(pTokenVector->at(0).c_str());
pColor->g = atof(pTokenVector->at(1).c_str());
pColor->b = atof(pTokenVector->at(2).c_str());
pColor->a = atof(pTokenVector->at(3).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenColor(const std::string & c_rstrKey, D3DCOLORVALUE * pColor)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->size() != 4)
{
//Tracef(" CTextFileLoader::GetTokenColor - This key should have 4 values %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
pColor->r = atof(pTokenVector->at(0).c_str());
pColor->g = atof(pTokenVector->at(1).c_str());
pColor->b = atof(pTokenVector->at(2).c_str());
pColor->a = atof(pTokenVector->at(3).c_str());
return TRUE;
}
BOOL CTextFileLoader::GetTokenString(const std::string & c_rstrKey, std::string * pString)
{
CTokenVector * pTokenVector;
if (!GetTokenVector(c_rstrKey, &pTokenVector))
return FALSE;
if (pTokenVector->empty())
{
//Tracef(" CTextFileLoader::GetTokenString - Failed to find the value %s [%s : %s]\n", m_File.GetFileName(), m_pcurNode->strGroupName.c_str(), c_rstrKey.c_str());
return FALSE;
}
*pString = pTokenVector->at(0);
return TRUE;
}
+132
View File
@@ -0,0 +1,132 @@
#ifndef __INC_METIN_II_TEXTFILELOADER_H__
#define __INC_METIN_II_TEXTFILELOADER_H__
#include "../EterBase/FileLoader.h"
#include "../EterBase/MappedFile.h"
#include "../EterLib/Util.h"
#include "../EterLib/Pool.h"
class CTextFileLoader
{
public:
typedef struct SGroupNode
{
static DWORD GenNameKey(const char* c_szGroupName, UINT uGroupNameLen);
void SetGroupName(const std::string& c_rstGroupName);
bool IsGroupNameKey(DWORD dwGroupNameKey);
const std::string& GetGroupName();
CTokenVector* GetTokenVector(const std::string& c_rstGroupName);
bool IsExistTokenVector(const std::string& c_rstGroupName);
void InsertTokenVector(const std::string& c_rstGroupName, const CTokenVector& c_rkVct_stToken);
DWORD m_dwGroupNameKey;
std::string m_strGroupName;
std::map<DWORD, CTokenVector> m_kMap_dwKey_kVct_stToken;
SGroupNode * pParentNode;
std::vector<SGroupNode*> ChildNodeVector;
static SGroupNode* New();
static void Delete(SGroupNode* pkNode);
static void DestroySystem();
static CDynamicPool<SGroupNode> ms_kPool;
} TGroupNode;
typedef std::vector<TGroupNode*> TGroupNodeVector;
class CGotoChild
{
public:
CGotoChild(CTextFileLoader * pOwner, const char * c_szKey) : m_pOwner(pOwner)
{
m_pOwner->SetChildNode(c_szKey);
}
CGotoChild(CTextFileLoader * pOwner, DWORD dwIndex) : m_pOwner(pOwner)
{
m_pOwner->SetChildNode(dwIndex);
}
~CGotoChild()
{
m_pOwner->SetParentNode();
}
CTextFileLoader * m_pOwner;
};
public:
static void DestroySystem();
static void SetCacheMode();
static CTextFileLoader* Cache(const char* c_szFileName);
public:
CTextFileLoader();
virtual ~CTextFileLoader();
void Destroy();
bool Load(const char * c_szFileName);
const char * GetFileName();
bool IsEmpty();
void SetTop();
DWORD GetChildNodeCount();
BOOL SetChildNode(const char * c_szKey);
BOOL SetChildNode(const std::string & c_rstrKeyHead, DWORD dwIndex);
BOOL SetChildNode(DWORD dwIndex);
BOOL SetParentNode();
BOOL GetCurrentNodeName(std::string * pstrName);
BOOL IsToken(const std::string & c_rstrKey);
BOOL GetTokenVector(const std::string & c_rstrKey, CTokenVector ** ppTokenVector);
BOOL GetTokenBoolean(const std::string & c_rstrKey, BOOL * pData);
BOOL GetTokenByte(const std::string & c_rstrKey, BYTE * pData);
BOOL GetTokenWord(const std::string & c_rstrKey, WORD * pData);
BOOL GetTokenInteger(const std::string & c_rstrKey, int * pData);
BOOL GetTokenDoubleWord(const std::string & c_rstrKey, DWORD * pData);
BOOL GetTokenFloat(const std::string & c_rstrKey, float * pData);
BOOL GetTokenVector2(const std::string & c_rstrKey, D3DXVECTOR2 * pVector2);
BOOL GetTokenVector3(const std::string & c_rstrKey, D3DXVECTOR3 * pVector3);
BOOL GetTokenVector4(const std::string & c_rstrKey, D3DXVECTOR4 * pVector4);
BOOL GetTokenPosition(const std::string & c_rstrKey, D3DXVECTOR3 * pVector);
BOOL GetTokenQuaternion(const std::string & c_rstrKey, D3DXQUATERNION * pQ);
BOOL GetTokenDirection(const std::string & c_rstrKey, D3DVECTOR * pVector);
BOOL GetTokenColor(const std::string & c_rstrKey, D3DXCOLOR * pColor);
BOOL GetTokenColor(const std::string & c_rstrKey, D3DCOLORVALUE * pColor);
BOOL GetTokenString(const std::string & c_rstrKey, std::string * pString);
protected:
void __DestroyGroupNodeVector();
bool LoadGroup(TGroupNode * pGroupNode);
protected:
std::string m_strFileName;
char* m_acBufData;
DWORD m_dwBufSize;
DWORD m_dwBufCapacity;
DWORD m_dwcurLineIndex;
CMemoryTextFileLoader m_textFileLoader;
TGroupNode m_GlobalNode;
TGroupNode * m_pcurNode;
std::vector<SGroupNode*> m_kVct_pkNode;
protected:
static std::map<DWORD, CTextFileLoader*> ms_kMap_dwNameKey_pkTextFileLoader;
static bool ms_isCacheMode;
};
#endif
+209
View File
@@ -0,0 +1,209 @@
#include "StdAfx.h"
#include "TextTag.h"
int GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo)
{
tagLen = 1;
if (maxLen < 2 || *src != L'|')
return TEXT_TAG_PLAIN;
const wchar_t * cur = ++src;
if (*cur == L'c') // color
{
if (maxLen < 10)
return TEXT_TAG_PLAIN;
tagLen = 10;
extraInfo.assign(++cur, 8);
return TEXT_TAG_COLOR;
}
else if (*cur == L'|') // ||는 |로 표시한다.
{
tagLen = 2;
return TEXT_TAG_TAG;
}
else if (*cur == L'r') // restore color
{
tagLen = 2;
return TEXT_TAG_RESTORE_COLOR;
}
else if (*cur == L'H') // hyperlink |Hitem:10000:0:0:0:0|h[이름]|h
{
tagLen = 2;
return TEXT_TAG_HYPERLINK_START;
}
else if (*cur == L'h') // end of hyperlink
{
tagLen = 2;
return TEXT_TAG_HYPERLINK_END;
}
return TEXT_TAG_PLAIN;
}
std::wstring GetTextTagOutputString(const wchar_t * src, int src_len)
{
int len;
std::wstring dst;
std::wstring extraInfo;
int output_len = 0;
int hyperlinkStep = 0;
for (int i = 0; i < src_len; )
{
int tag = GetTextTag(&src[i], src_len - i, len, extraInfo);
if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG)
{
if (hyperlinkStep == 0)
{
++output_len;
dst += src[i];
}
}
else if (tag == TEXT_TAG_HYPERLINK_START)
hyperlinkStep = 1;
else if (tag == TEXT_TAG_HYPERLINK_END)
hyperlinkStep = 0;
i += len;
}
return dst;
}
int GetTextTagInternalPosFromRenderPos(const wchar_t * src, int src_len, int offset)
{
int len;
std::wstring dst;
std::wstring extraInfo;
int output_len = 0;
int hyperlinkStep = 0;
bool color_tag = false;
int internal_offset = 0;
for (int i = 0; i < src_len; )
{
int tag = GetTextTag(&src[i], src_len - i, len, extraInfo);
if (tag == TEXT_TAG_COLOR)
{
color_tag = true;
internal_offset = i;
}
else if (tag == TEXT_TAG_RESTORE_COLOR)
{
color_tag = false;
}
else if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG)
{
if (hyperlinkStep == 0)
{
if (!color_tag)
internal_offset = i;
if (offset <= output_len)
return internal_offset;
++output_len;
dst += src[i];
}
}
else if (tag == TEXT_TAG_HYPERLINK_START)
hyperlinkStep = 1;
else if (tag == TEXT_TAG_HYPERLINK_END)
hyperlinkStep = 0;
i += len;
}
return internal_offset;
}
int GetTextTagOutputLen(const wchar_t * src, int src_len)
{
int len;
std::wstring extraInfo;
int output_len = 0;
int hyperlinkStep = 0;
for (int i = 0; i < src_len; )
{
int tag = GetTextTag(&src[i], src_len - i, len, extraInfo);
if (tag == TEXT_TAG_PLAIN || tag == TEXT_TAG_TAG)
{
if (hyperlinkStep == 0)
++output_len;
}
else if (tag == TEXT_TAG_HYPERLINK_START)
hyperlinkStep = 1;
else if (tag == TEXT_TAG_HYPERLINK_END)
hyperlinkStep = 0;
i += len;
}
return output_len;
}
int FindColorTagStartPosition(const wchar_t * src, int src_len)
{
if (src_len < 2)
return 0;
const wchar_t * cur = src;
// |r의 경우
if (*cur == L'r' && *(cur - 1) == L'|')
{
int len = src_len;
// ||r은 무시
if (len >= 2 && *(cur - 2) == L'|')
return 1;
cur -= 2;
len -= 2;
// |c까지 찾아서 |위치까지 리턴한다.
while (len > 1) // 최소 2자를 검사해야 된다.
{
if (*cur == L'c' && *(cur - 1) == L'|')
return (src - cur) + 1;
--cur;
--len;
}
return (src_len); // 못찾으면 전부;;
}
// ||의 경우
else if (*cur == L'|' && *(cur - 1) == L'|')
return 1;
return 0;
}
int FindColorTagEndPosition(const wchar_t * src, int src_len)
{
const wchar_t * cur = src;
if (src_len >= 4 && *cur == L'|' && *(cur + 1) == L'c')
{
int left = src_len - 2;
cur += 2;
while (left > 1)
{
if (*cur == L'|' && *(cur + 1) == L'r')
return (cur - src) + 1;
--left;
++cur;
}
}
else if (src_len >= 2 && *cur == L'|' && *(cur + 1) == L'|')
return 1;
return 0;
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once // PORT: 40250 TextTag.h has no include guard; the header gate includes every header twice.
enum
{
TEXT_TAG_PLAIN,
TEXT_TAG_TAG, // ||
TEXT_TAG_COLOR, // |cffffffff
TEXT_TAG_HYPERLINK_START, // |H
TEXT_TAG_HYPERLINK_END, // |h ex) |Hitem:1234:1:1:1|h
TEXT_TAG_RESTORE_COLOR,
};
extern int GetTextTag(const wchar_t * src, int maxLen, int & tagLen, std::wstring & extraInfo);
extern std::wstring GetTextTagOutputString(const wchar_t * src, int src_len);
extern int GetTextTagOutputLen(const wchar_t * src, int len);
extern int FindColorTagEndPosition(const wchar_t * src, int src_len);
extern int FindColorTagStartPosition(const wchar_t * src, int src_len);
extern int GetTextTagInternalPosFromRenderPos(const wchar_t * src, int src_len, int offset);
+28
View File
@@ -0,0 +1,28 @@
#ifndef __INC_ETERLIB_THREAD_H__
#define __INC_ETERLIB_THREAD_H__
class CThread
{
public:
CThread();
int Create(void * arg);
protected:
static UINT CALLBACK EntryPoint(void * pThis);
virtual UINT Setup() = 0; // Execute이 불려지기 전에 불려진다.
virtual UINT Execute(void * arg) = 0; // 실제 쓰레드가 하는 일이 들어가는 곳
UINT Run(void * arg);
void * Arg() const { return m_pArg; }
void Arg(void * arg) { m_pArg = arg; }
HANDLE m_hThread;
private:
void * m_pArg;
unsigned m_uThreadID;
};
#endif
+237
View File
@@ -0,0 +1,237 @@
#include "StdAfx.h"
#include "../EterPack/EterPackManager.h"
#include "TextFileLoader.h"
void PrintfTabs(FILE * File, int iTabCount, const char * c_szString, ...)
{
va_list args;
va_start(args, c_szString);
static char szBuf[1024];
_vsnprintf(szBuf, sizeof(szBuf), c_szString, args);
va_end(args);
for (int i = 0; i < iTabCount; ++i)
fprintf(File, " ");
fprintf(File, szBuf);
}
bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap)
{
LPCVOID pMotionData;
CMappedFile File;
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pMotionData))
return false;
CMemoryTextFileLoader textFileLoader;
CTokenVector stTokenVector;
textFileLoader.Bind(File.Size(), pMotionData);
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLine(i, &stTokenVector))
continue;
if (2 != stTokenVector.size())
return false;
stl_lowers(stTokenVector[0]);
stl_lowers(stTokenVector[1]);
rstTokenMap[stTokenVector[0]] = stTokenVector[1];
}
return true;
}
bool LoadMultipleTextData(const char * c_szFileName, CTokenVectorMap & rstTokenVectorMap)
{
LPCVOID pModelData;
CMappedFile File;
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData))
return false;
DWORD i;
CMemoryTextFileLoader textFileLoader;
CTokenVector stTokenVector;
textFileLoader.Bind(File.Size(), pModelData);
for (i = 0; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLine(i, &stTokenVector))
continue;
stl_lowers(stTokenVector[0]);
// Start or End
if (0 == stTokenVector[0].compare("start"))
{
CTokenVector stSubTokenVector;
stl_lowers(stTokenVector[1]);
std::string key = stTokenVector[1];
stTokenVector.clear();
for (i=i+1; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLine(i, &stSubTokenVector))
continue;
stl_lowers(stSubTokenVector[0]);
if (0 == stSubTokenVector[0].compare("end"))
{
break;
}
for (DWORD j = 0; j < stSubTokenVector.size(); ++j)
{
stTokenVector.push_back(stSubTokenVector[j]);
}
}
rstTokenVectorMap.insert(CTokenVectorMap::value_type(key, stTokenVector));
}
else
{
std::string key = stTokenVector[0];
stTokenVector.erase(stTokenVector.begin());
rstTokenVectorMap.insert(CTokenVectorMap::value_type(key, stTokenVector));
}
}
return true;
}
D3DXVECTOR3 TokenToVector(CTokenVector & rVector)
{
if (3 != rVector.size())
{
assert(!"Size of token vector which will be converted to vector is not 3");
return D3DXVECTOR3(0.0f, 0.0f, 0.0f);
}
return D3DXVECTOR3(atof(rVector[0].c_str()),
atof(rVector[1].c_str()),
atof(rVector[2].c_str()));
}
D3DXCOLOR TokenToColor(CTokenVector & rVector)
{
if (4 != rVector.size())
{
assert(!"Size of token vector which will be converted to color is not 4");
return D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
}
return D3DXCOLOR(atof(rVector[0].c_str()),
atof(rVector[1].c_str()),
atof(rVector[2].c_str()),
atof(rVector[3].c_str()));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// PORT: lines 142-296 of 40250 EterLib/Util.cpp (default code page and font face, with the Win32
// EnumFontFamExProc callback) live in platform/EterLib/Util.cpp, which owns the font backend.
int __base64_get( const int c )
{
if( 'A' <= c && c <= 'Z' )
return c-'A';
if( 'a' <= c && c <= 'z' )
return c - 'a' + 26;
if( '0' <= c && c <= '9' )
return c - '0' + 52;
if( c == '+' )
return 62;
if( c == '/' )
return 63;
if( c == '=' ) // end of line
return -1;
return -2; // non value;
}
void __strcat1(char * str,int i)
{
char result[2];
result[0] = i;
result[1] = NULL;
strcat(str,result);
}
void base64_decode(const char * str,char * resultStr)
{
int nCount=0, i=0, r, result;
int length = strlen(str);
char szDest[5]="";
strcpy(resultStr,"");
while(nCount < length)
{
i=0;
strcpy(szDest, "");
while(nCount<length && i<4) // 4개의 바이트를 얻는다.
{
r = str[nCount++];
result = __base64_get(r);
if(result!=-2)
{
if(result!=-1)
szDest[i++] = result;
else szDest[i++] = '@'; // It's end (64번은 디코딩시 사용되지 않기 때문)
}
}
if(i==4) // 4개의 소스를 모두 얻어냈다. 디코드 시작
{
if( nCount+3 >= length ) // 데이터의 끝에 도달했다.
{
if( szDest[1] == '@' )
{
__strcat1(resultStr,(szDest[0]<<2));
break;
}// exit while loop
else
__strcat1(resultStr,(szDest[0]<<2 | szDest[1]>>4)); // 1 Byte
if( szDest[2] == '@' )
{
__strcat1(resultStr,(szDest[1]<<4));
break;
}
else
__strcat1(resultStr,(szDest[1]<<4 | szDest[2]>>2)); // 2 Byte
if( szDest[3] == '@' )
{
__strcat1(resultStr,(szDest[2]<<6));
break;
}
else
__strcat1(resultStr,(szDest[2]<<6 | szDest[3])); // 3 Byte
}
else
{
__strcat1(resultStr,(szDest[0]<<2 | szDest[1]>>4)); // 1 Byte
__strcat1(resultStr,(szDest[1]<<4 | szDest[2]>>2)); // 2 Byte
__strcat1(resultStr,(szDest[2]<<6 | szDest[3])); // 3 Byte
}
}
}// end of while
for (i = 0; i < strlen(resultStr); i++)
{
char c = resultStr[i];
int xx = i + 5;
resultStr[i] = char(c ^ xx);
}
// E
}
+113
View File
@@ -0,0 +1,113 @@
#pragma once
#include "../EterBase/FileLoader.h"
#include <map>
#include <vector>
#include <d3dx8.h>
template<typename T>
class CTransitor
{
public:
CTransitor() {}
~CTransitor() {}
void SetActive(BOOL bActive = TRUE)
{
m_bActivated = bActive;
}
BOOL isActive()
{
return m_bActivated;
}
BOOL isActiveTime(float fcurTime)
{
if (fcurTime >= m_fEndTime)
return FALSE;
return TRUE;
}
DWORD GetID()
{
return m_dwID;
}
void SetID(DWORD dwID)
{
m_dwID = dwID;
}
void SetSourceValue(const T & c_rSourceValue)
{
m_SourceValue = c_rSourceValue;
}
void SetTransition(const T & c_rSourceValue, const T & c_rTargetValue, float fStartTime, float fBlendTime)
{
m_SourceValue = c_rSourceValue;
m_TargetValue = c_rTargetValue;
m_fStartTime = fStartTime;
m_fEndTime = fStartTime + fBlendTime;
}
BOOL GetValue(float fcurTime, T * pValue)
{
if (fcurTime <= m_fStartTime)
return FALSE;
float fPercentage = (fcurTime - m_fStartTime) / (m_fEndTime - m_fStartTime);
*pValue = m_SourceValue + (m_TargetValue - m_SourceValue) * fPercentage;
return TRUE;
}
protected:
DWORD m_dwID; // Public Transitor ID
BOOL m_bActivated; // Have been started to blend?
float m_fStartTime;
float m_fEndTime;
T m_SourceValue;
T m_TargetValue;
};
typedef CTransitor<float> TTransitorFloat;
typedef CTransitor<D3DXVECTOR3> TTransitorVector3;
typedef CTransitor<D3DXCOLOR> TTransitorColor;
///////////////////////////////////////////////////////////////////////////////////////////////////
void PrintfTabs(FILE * File, int iTabCount, const char * c_szString, ...);
//typedef CTokenVector TTokenVector;
extern bool LoadTextData(const char * c_szFileName, CTokenMap & rstTokenMap);
extern bool LoadMultipleTextData(const char * c_szFileName, CTokenVectorMap & rstTokenVectorMap);
extern D3DXVECTOR3 TokenToVector(CTokenVector & rVector);
extern D3DXCOLOR TokenToColor(CTokenVector & rVector);
#define GOTO_CHILD_NODE(TextFileLoader, Index) CTextFileLoader::CGotoChild Child(TextFileLoader, Index);
///////////////////////////////////////////////////////////////////////////////////////////////////
extern int CALLBACK EnumFontFamExProc(CONST LOGFONT* plogFont, CONST TEXTMETRIC* textMetric, DWORD dwWord, LPARAM lParam);
extern int GetCharsetFromCodePage(WORD codePage);
extern const char* GetFontFaceFromCodePageNT(WORD codePage);
extern const char* GetFontFaceFromCodePage9x(WORD codePage);
extern DWORD GetDefaultCodePage();
extern const char * GetDefaultFontFace();
extern const char* GetFontFaceFromCodePage(WORD codePage);
extern void SetDefaultFontFace(const char* fontFace);
extern bool SetDefaultCodePage(DWORD codePage);
extern void base64_decode(const char * str,char * resultStr);
extern DWORD GetMaxTextureWidth();
extern DWORD GetMaxTextureHeight();
+849
View File
@@ -0,0 +1,849 @@
/**************************************************************************************
| File: lineintersect_utils.cpp
| Purpose: Implementation of line segment intersection utility functions
| Book Title: Game Programming Gems II
| Chapter Title: Fast, Robust Intersection of 3D Line Segments
| Author: Graham Rhodes
| Revisions: 05-Apr-2001 - GSR. Original.
**************************************************************************************/
#include "StdAfx.h"
#include <math.h>
#include "lineintersect_utils.h"
#include <assert.h>
// uncomment the following line to have the code check intermediate results
//#define CHECK_ANSWERS
// uncomment the following line to use Cramer's rule instead of Gaussian elimination
//#define USE_CRAMERS_RULE
#define FMAX(a,b) ((a) > (b) ? (a) : (b))
#define FMIN(a,b) ((a) > (b) ? (b) : (a))
#define FABS(a) ((a) < 0.0f ? -(a) : (a))
#define OUT_OF_RANGE(a) ((a) < 0.0f || (a) > 1.f)
#define MY_EPSILON 0.1f
__forceinline void FindNearestPointOnLineSegment(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & L,
const D3DXVECTOR3 & B,
D3DXVECTOR3 & Nearest,
float &parameter)
{
// Line/Segment is degenerate --- special case #1
float D = D3DXVec3LengthSq(&L);
if (D < MY_EPSILON*MY_EPSILON)
{
Nearest = A1;
return;
}
D3DXVECTOR3 AB = B-A1;
// parameter is computed from Equation (20).
parameter = (D3DXVec3Dot(&AB,&L)) / D;
//if (false == infinite_line)
parameter = FMAX(0.0f, FMIN(1.0f, parameter));
Nearest = A1 + parameter * L;
return;
}
/**************************************************************************
|
| Method: FindNearestPointOfParallelLineSegments
|
| Purpose: Given two lines (segments) that are known to be parallel, find
| a representative point on each that is nearest to the other. If
| the lines are considered to be finite then it is possible that there
| is one true point on each line that is nearest to the other. This
| code properly handles this case.
|
| This is the most difficult line intersection case to handle, since
| there is potentially a family, or locus of points on each line/segment
| that are nearest to the other.
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
| infinite_lines - set to true if lines are to be treated as infinite
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
**************************************************************************/
__forceinline void FindNearestPointOfParallelLineSegments(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & A2,
const D3DXVECTOR3 & La,
const D3DXVECTOR3 & B1,
const D3DXVECTOR3 & B2,
const D3DXVECTOR3 & Lb,
//bool infinite_lines, float epsilon_squared,
D3DXVECTOR3 & OutA,
D3DXVECTOR3 & OutB)
{
float s[2], temp;
FindNearestPointOnLineSegment(A1, La, B1, OutA, s[0]);
/*if (true == infinite_lines)
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
}
else*/
{
//float tp[3];
D3DXVECTOR3 tp;
FindNearestPointOnLineSegment(A1, La, B2,
tp, s[1]);
if (s[0] < 0.f && s[1] < 0.f)
{
OutA = A1;
if (s[0] < s[1])
{
OutB =B2;
}
else
{
OutB = B1;
}
}
else if (s[0] > 1.f && s[1] > 1.f)
{
OutA = A2;
if (s[0] < s[1])
{
OutB = B1;
}
else
{
OutB = B2;
}
}
else
{
temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1])));
OutA = A1 + temp * La;
FindNearestPointOnLineSegment(B1, Lb,
OutA, OutB, temp);
}
}
}
/**************************************************************************
|
| Method: AdjustNearestPoints
|
| Purpose: Given nearest point information for two infinite lines, adjust
| to model finite line segments.
|
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
| s - parameter representing nearest point on infinite line A
| t - parameter representing nearest point on infinite line B
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
**************************************************************************/
__forceinline void AdjustNearestPoints(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & La,
const D3DXVECTOR3 & B1,
const D3DXVECTOR3 & Lb,
float s, float t,
D3DXVECTOR3 & OutA,
D3DXVECTOR3 & OutB)
{
// handle the case where both parameter s and t are out of range
if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t))
{
s = FMAX(0.0f, FMIN(1.0f, s));
OutA = A1 + s*La;
FindNearestPointOnLineSegment(B1, Lb,
OutA,
OutB, t);
if (OUT_OF_RANGE(t))
{
t = FMAX(0.0f, FMIN(1.0f, t));
OutB = B1 + t*Lb;
FindNearestPointOnLineSegment(A1, La, OutB,
OutA, s);
FindNearestPointOnLineSegment(B1, Lb, OutA,
OutB, t);
}
}
// otherwise, handle the case where the parameter for only one segment is
// out of range
else if (OUT_OF_RANGE(s))
{
s = FMAX(0.0f, FMIN(1.0f, s));
OutA = A1 + s*La;
FindNearestPointOnLineSegment(B1, Lb,
OutA,
OutB, t);
}
else if (OUT_OF_RANGE(t))
{
t = FMAX(0.0f, FMIN(1.0f, t));
OutB = B1 + t*Lb;
FindNearestPointOnLineSegment(A1, La, OutB,
OutA, s);
}
else
{
assert(0);
}
}
void IntersectLineSegments(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & A2,
const D3DXVECTOR3 & B1,
const D3DXVECTOR3 & B2,
//bool infinite_lines, /*float epsilon,*/
D3DXVECTOR3 & OutA,
D3DXVECTOR3 & OutB)
{
float temp = 0.f;
const float epsilon = MY_EPSILON;
const float epsilon_squared = MY_EPSILON*MY_EPSILON;
// Compute parameters from Equations (1) and (2) in the text
D3DXVECTOR3 La = A2-A1;
D3DXVECTOR3 Lb = B2-B1;
// From Equation (15)
float L11 = D3DXVec3LengthSq(&La);
float L22 = D3DXVec3LengthSq(&Lb);
// Line/Segment A is degenerate ---- Special Case #1
if (L11 < epsilon_squared)
{
OutA = A1;
FindNearestPointOnLineSegment(B1, Lb, A1,
OutB, temp);
}
// Line/Segment B is degenerate ---- Special Case #1
else if (L22 < epsilon_squared)
{
OutB = B1;
FindNearestPointOnLineSegment(A1, La, B1,
OutA, temp);
}
// Neither line/segment is degenerate
else
{
// Compute more parameters from Equation (3) in the text.
D3DXVECTOR3 AB = B1 - A1;
// and from Equation (15).
float L12 = -D3DXVec3Dot(&La, &Lb);
float DetL = L11 * L22 - L12 * L12;
// Lines/Segments A and B are parallel ---- special case #2.
if (FABS(DetL) < epsilon)
{
FindNearestPointOfParallelLineSegments(A1, A2,
La,
B1, B2,
Lb,
OutA, OutB);
}
// The general case
else
{
// from Equation (15)
float ra = D3DXVec3Dot(&La, &AB);//Lax * ABx + Lay * ABy + Laz * ABz;
float rb = D3DXVec3Dot(&Lb, &AB);//-Lbx * ABx - Lby * ABy - Lbz * ABz;
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
#ifdef USE_CRAMERS_RULE
float s = (L22 * ra - rb * L12)/DetL;
#else
float s = (ra-L12*t)/L11; // Equation (13)
#endif // USE_CRAMERS_RULE
#ifdef CHECK_ANSWERS
float check_ra = s*L11 + t*L12;
float check_rb = s*L12 + t*L22;
assert(FABS(check_ra-ra) < epsilon);
assert(FABS(check_rb-rb) < epsilon);
#endif // CHECK_ANSWERS
// if we are dealing with infinite lines or if parameters s and t both
// lie in the range [0,1] then just compute the points using Equations
// (1) and (2) from the text.
OutA = (A1 + s * La);
OutB = (B1 + t * Lb);
// otherwise, at least one of s and t is outside of [0,1] and we have to
// handle this case.
if ((OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
{
AdjustNearestPoints(A1,La,B1,Lb,
s, t,
OutA,
OutB);
}
}
}
}
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
const float A2x, const float A2y, const float A2z,
const float B1x, const float B1y, const float B1z,
const float B2x, const float B2y, const float B2z,
bool infinite_lines, float epsilon, float &PointOnSegAx,
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
float &PointOnSegBy, float &PointOnSegBz)
{
float temp = 0.f;
float epsilon_squared = epsilon * epsilon;
// Compute parameters from Equations (1) and (2) in the text
float Lax = A2x - A1x;
float Lay = A2y - A1y;
float Laz = A2z - A1z;
float Lbx = B2x - B1x;
float Lby = B2y - B1y;
float Lbz = B2z - B1z;
// From Equation (15)
float L11 = (Lax * Lax) + (Lay * Lay) + (Laz * Laz);
float L22 = (Lbx * Lbx) + (Lby * Lby) + (Lbz * Lbz);
// Line/Segment A is degenerate ---- Special Case #1
if (L11 < epsilon_squared)
{
PointOnSegAx = A1x;
PointOnSegAy = A1y;
PointOnSegAz = A1z;
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, A1x, A1y, A1z,
infinite_lines, epsilon, PointOnSegBx, PointOnSegBy,
PointOnSegBz, temp);
}
// Line/Segment B is degenerate ---- Special Case #1
else if (L22 < epsilon_squared)
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
infinite_lines, epsilon, PointOnSegAx, PointOnSegAy,
PointOnSegAz, temp);
}
// Neither line/segment is degenerate
else
{
// Compute more parameters from Equation (3) in the text.
float ABx = B1x - A1x;
float ABy = B1y - A1y;
float ABz = B1z - A1z;
// and from Equation (15).
float L12 = -(Lax * Lbx) - (Lay * Lby) - (Laz * Lbz);
float DetL = L11 * L22 - L12 * L12;
// Lines/Segments A and B are parallel ---- special case #2.
if (FABS(DetL) < epsilon)
{
FindNearestPointOfParallelLineSegments(A1x, A1y, A1z, A2x, A2y, A2z,
Lax, Lay, Laz,
B1x, B1y, B1z, B2x, B2y, B2z,
Lbx, Lby, Lbz,
infinite_lines, epsilon,
PointOnSegAx, PointOnSegAy, PointOnSegAz,
PointOnSegBx, PointOnSegBy, PointOnSegBz);
}
// The general case
else
{
// from Equation (15)
float ra = Lax * ABx + Lay * ABy + Laz * ABz;
float rb = -Lbx * ABx - Lby * ABy - Lbz * ABz;
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
#ifdef USE_CRAMERS_RULE
float s = (L22 * ra - rb * L12)/DetL;
#else
float s = (ra-L12*t)/L11; // Equation (13)
#endif // USE_CRAMERS_RULE
#ifdef CHECK_ANSWERS
float check_ra = s*L11 + t*L12;
float check_rb = s*L12 + t*L22;
assert(FABS(check_ra-ra) < epsilon);
assert(FABS(check_rb-rb) < epsilon);
#endif // CHECK_ANSWERS
// if we are dealing with infinite lines or if parameters s and t both
// lie in the range [0,1] then just compute the points using Equations
// (1) and (2) from the text.
PointOnSegAx = (A1x + s * Lax);
PointOnSegAy = (A1y + s * Lay);
PointOnSegAz = (A1z + s * Laz);
PointOnSegBx = (B1x + t * Lbx);
PointOnSegBy = (B1y + t * Lby);
PointOnSegBz = (B1z + t * Lbz);
// otherwise, at least one of s and t is outside of [0,1] and we have to
// handle this case.
if (false == infinite_lines && (OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
{
AdjustNearestPoints(A1x, A1y, A1z, Lax, Lay, Laz,
B1x, B1y, B1z, Lbx, Lby, Lbz,
epsilon, s, t,
PointOnSegAx, PointOnSegAy, PointOnSegAz,
PointOnSegBx, PointOnSegBy, PointOnSegBz);
}
}
}
}
// pragma to get rid of math.h inline function removal warnings.
#pragma warning(disable:4514)
/**************************************************************************
|
| Method: IntersectLineSegments
|
| Purpose: Find the nearest point between two finite length line segments
| or two infinite lines in 3-dimensional space. The function calculates
| the point on each line/line segment that is closest to the other
| line/line segment, the midpoint between the nearest points, and
| the vector between these two points. If the two nearest points
| are close within a tolerance, a flag is set indicating the lines
| have a "true" intersection.
|
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
| infinite_lines - set to true if lines are to be treated as infinite
| epsilon - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
| NearestPointX, - Midpoint between the two nearest points. This can be
| NearestPointY, treated as *the* intersection point if nearest points
| NearestPointZ are sufficiently close. This corresponds to point P
| in the text.
| NearestVectorX, - Vector between the nearest point on A to the nearest
| point on segment B. This vector is normal to both
| lines if the lines are infinite, but is not guaranteed
| to be normal to both lines if both lines are finite
| length.
| true_intersection - true if the nearest points are close within a small
| tolerance.
**************************************************************************/
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
const float A2x, const float A2y, const float A2z,
const float B1x, const float B1y, const float B1z,
const float B2x, const float B2y, const float B2z,
bool infinite_lines, float epsilon, float &PointOnSegAx,
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
float &PointOnSegBy, float &PointOnSegBz, float &NearestPointX,
float &NearestPointY, float &NearestPointZ, float &NearestVectorX,
float &NearestVectorY, float &NearestVectorZ, bool &true_intersection)
{
float temp = 0.f;
float epsilon_squared = epsilon * epsilon;
// Compute parameters from Equations (1) and (2) in the text
float Lax = A2x - A1x;
float Lay = A2y - A1y;
float Laz = A2z - A1z;
float Lbx = B2x - B1x;
float Lby = B2y - B1y;
float Lbz = B2z - B1z;
// From Equation (15)
float L11 = (Lax * Lax) + (Lay * Lay) + (Laz * Laz);
float L22 = (Lbx * Lbx) + (Lby * Lby) + (Lbz * Lbz);
// Line/Segment A is degenerate ---- Special Case #1
if (L11 < epsilon_squared)
{
PointOnSegAx = A1x;
PointOnSegAy = A1y;
PointOnSegAz = A1z;
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, A1x, A1y, A1z,
infinite_lines, epsilon, PointOnSegBx, PointOnSegBy,
PointOnSegBz, temp);
}
// Line/Segment B is degenerate ---- Special Case #1
else if (L22 < epsilon_squared)
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
infinite_lines, epsilon, PointOnSegAx, PointOnSegAy,
PointOnSegAz, temp);
}
// Neither line/segment is degenerate
else
{
// Compute more parameters from Equation (3) in the text.
float ABx = B1x - A1x;
float ABy = B1y - A1y;
float ABz = B1z - A1z;
// and from Equation (15).
float L12 = -(Lax * Lbx) - (Lay * Lby) - (Laz * Lbz);
float DetL = L11 * L22 - L12 * L12;
// Lines/Segments A and B are parallel ---- special case #2.
if (FABS(DetL) < epsilon)
{
FindNearestPointOfParallelLineSegments(A1x, A1y, A1z, A2x, A2y, A2z,
Lax, Lay, Laz,
B1x, B1y, B1z, B2x, B2y, B2z,
Lbx, Lby, Lbz,
infinite_lines, epsilon,
PointOnSegAx, PointOnSegAy, PointOnSegAz,
PointOnSegBx, PointOnSegBy, PointOnSegBz);
}
// The general case
else
{
// from Equation (15)
float ra = Lax * ABx + Lay * ABy + Laz * ABz;
float rb = -Lbx * ABx - Lby * ABy - Lbz * ABz;
float t = (L11 * rb - ra * L12)/DetL; // Equation (12)
#ifdef USE_CRAMERS_RULE
float s = (L22 * ra - rb * L12)/DetL;
#else
float s = (ra-L12*t)/L11; // Equation (13)
#endif // USE_CRAMERS_RULE
#ifdef CHECK_ANSWERS
float check_ra = s*L11 + t*L12;
float check_rb = s*L12 + t*L22;
assert(FABS(check_ra-ra) < epsilon);
assert(FABS(check_rb-rb) < epsilon);
#endif // CHECK_ANSWERS
// if we are dealing with infinite lines or if parameters s and t both
// lie in the range [0,1] then just compute the points using Equations
// (1) and (2) from the text.
PointOnSegAx = (A1x + s * Lax);
PointOnSegAy = (A1y + s * Lay);
PointOnSegAz = (A1z + s * Laz);
PointOnSegBx = (B1x + t * Lbx);
PointOnSegBy = (B1y + t * Lby);
PointOnSegBz = (B1z + t * Lbz);
// otherwise, at least one of s and t is outside of [0,1] and we have to
// handle this case.
if (false == infinite_lines && (OUT_OF_RANGE(s) || OUT_OF_RANGE(t)))
{
AdjustNearestPoints(A1x, A1y, A1z, Lax, Lay, Laz,
B1x, B1y, B1z, Lbx, Lby, Lbz,
epsilon, s, t,
PointOnSegAx, PointOnSegAy, PointOnSegAz,
PointOnSegBx, PointOnSegBy, PointOnSegBz);
}
}
}
NearestPointX = 0.5f * (PointOnSegAx + PointOnSegBx);
NearestPointY = 0.5f * (PointOnSegAy + PointOnSegBy);
NearestPointZ = 0.5f * (PointOnSegAz + PointOnSegBz);
NearestVectorX = PointOnSegBx - PointOnSegAx;
NearestVectorY = PointOnSegBy - PointOnSegAy;
NearestVectorZ = PointOnSegBz - PointOnSegAz;
// optional check to indicate if the lines truly intersect
true_intersection = (FABS(NearestVectorX) +
FABS(NearestVectorY) +
FABS(NearestVectorZ)) < epsilon ? true : false;
}
/**************************************************************************
|
| Method: FindNearestPointOnLineSegment
|
| Purpose: Given a line (segment) and a point in 3-dimensional space,
| find the point on the line (segment) that is closest to the
| point.
|
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of the line/segment
| Lx, Ly, Lz - Vector from (A1x, A1y, A1z) to the second defining point
| of the line/segment.
| Bx, By, Bz - Coordinates of the point
| infinite_lines - set to true if lines are to be treated as infinite
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
|
| Output:
| -------
| NearestPointX, - Point on line/segment that is closest to (Bx, By, Bz)
| NearestPointY,
| NearestPointZ
| parameter - Parametric coordinate of the nearest point along the
| line/segment. parameter = 0 at (A1x, A1y, A1z) and
| parameter = 1 at the second defining point of the line/
| segmetn
**************************************************************************/
void FindNearestPointOnLineSegment(const float A1x, const float A1y, const float A1z,
const float Lx, const float Ly, const float Lz,
const float Bx, const float By, const float Bz,
bool infinite_line, float epsilon_squared, float &NearestPointX,
float &NearestPointY, float &NearestPointZ,
float &parameter)
{
// Line/Segment is degenerate --- special case #1
float D = Lx * Lx + Ly * Ly + Lz * Lz;
if (D < epsilon_squared)
{
NearestPointX = A1x;
NearestPointY = A1y;
NearestPointZ = A1z;
return;
}
float ABx = Bx - A1x;
float ABy = By - A1y;
float ABz = Bz - A1z;
// parameter is computed from Equation (20).
parameter = (Lx * ABx + Ly * ABy + Lz * ABz) / D;
if (false == infinite_line) parameter = FMAX(0.0f, FMIN(1.0f, parameter));
NearestPointX = A1x + parameter * Lx;
NearestPointY = A1y + parameter * Ly;
NearestPointZ = A1z + parameter * Lz;
return;
}
/**************************************************************************
|
| Method: FindNearestPointOfParallelLineSegments
|
| Purpose: Given two lines (segments) that are known to be parallel, find
| a representative point on each that is nearest to the other. If
| the lines are considered to be finite then it is possible that there
| is one true point on each line that is nearest to the other. This
| code properly handles this case.
|
| This is the most difficult line intersection case to handle, since
| there is potentially a family, or locus of points on each line/segment
| that are nearest to the other.
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| A2x, A2y, A2z - Coordinates of second defining point of line/segment A
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| B2x, B2y, B2z - Coordinates of second defining point of line/segment B
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
| infinite_lines - set to true if lines are to be treated as infinite
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
**************************************************************************/
void FindNearestPointOfParallelLineSegments(float A1x, float A1y, float A1z,
float A2x, float A2y, float A2z,
float Lax, float Lay, float Laz,
float B1x, float B1y, float B1z,
float B2x, float B2y, float B2z,
float Lbx, float Lby, float Lbz,
bool infinite_lines, float epsilon_squared,
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz)
{
float s[2], temp;
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B1x, B1y, B1z,
true, epsilon_squared, PointOnSegAx, PointOnSegAy, PointOnSegAz, s[0]);
if (true == infinite_lines)
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
}
else
{
float tp[3];
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, B2x, B2y, B2z,
true, epsilon_squared, tp[0], tp[1], tp[2], s[1]);
if (s[0] < 0.f && s[1] < 0.f)
{
PointOnSegAx = A1x;
PointOnSegAy = A1y;
PointOnSegAz = A1z;
if (s[0] < s[1])
{
PointOnSegBx = B2x;
PointOnSegBy = B2y;
PointOnSegBz = B2z;
}
else
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
}
}
else if (s[0] > 1.f && s[1] > 1.f)
{
PointOnSegAx = A2x;
PointOnSegAy = A2y;
PointOnSegAz = A2z;
if (s[0] < s[1])
{
PointOnSegBx = B1x;
PointOnSegBy = B1y;
PointOnSegBz = B1z;
}
else
{
PointOnSegBx = B2x;
PointOnSegBy = B2y;
PointOnSegBz = B2z;
}
}
else
{
temp = 0.5f*(FMAX(0.0f, FMIN(1.0f, s[0])) + FMAX(0.0f, FMIN(1.0f, s[1])));
PointOnSegAx = (A1x + temp * Lax);
PointOnSegAy = (A1y + temp * Lay);
PointOnSegAz = (A1z + temp * Laz);
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz,
PointOnSegAx, PointOnSegAy, PointOnSegAz, true,
epsilon_squared, PointOnSegBx, PointOnSegBy, PointOnSegBz, temp);
}
}
}
/**************************************************************************
|
| Method: AdjustNearestPoints
|
| Purpose: Given nearest point information for two infinite lines, adjust
| to model finite line segments.
|
| Parameters: Input:
| ------
| A1x, A1y, A1z - Coordinates of first defining point of line/segment A
| Lax, Lay, Laz - Vector from (A1x, A1y, A1z) to the (A2x, A2y, A2z).
| B1x, B1y, B1z - Coordinates of first defining point of line/segment B
| Lbx, Lby, Lbz - Vector from (B1x, B1y, B1z) to the (B2x, B2y, B2z).
| epsilon_squared - tolerance value to be used to check for degenerate
| and parallel lines, and to check for true intersection.
| s - parameter representing nearest point on infinite line A
| t - parameter representing nearest point on infinite line B
|
| Output:
| -------
| PointOnSegAx, - Coordinates of the point on segment A that are nearest
| PointOnSegAy, to segment B. This corresponds to point C in the text.
| PointOnSegAz
| PointOnSegBx, - Coordinates of the point on segment B that are nearest
| PointOnSegBy, to segment A. This corresponds to point D in the text.
| PointOnSegBz
**************************************************************************/
void AdjustNearestPoints(float A1x, float A1y, float A1z,
float Lax, float Lay, float Laz,
float B1x, float B1y, float B1z,
float Lbx, float Lby, float Lbz,
float epsilon_squared, float s, float t,
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz)
{
// handle the case where both parameter s and t are out of range
if (OUT_OF_RANGE(s) && OUT_OF_RANGE(t))
{
s = FMAX(0.0f, FMIN(1.0f, s));
PointOnSegAx = (A1x + s * Lax);
PointOnSegAy = (A1y + s * Lay);
PointOnSegAz = (A1z + s * Laz);
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
PointOnSegAy, PointOnSegAz, true, epsilon_squared,
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
if (OUT_OF_RANGE(t))
{
t = FMAX(0.0f, FMIN(1.0f, t));
PointOnSegBx = (B1x + t * Lbx);
PointOnSegBy = (B1y + t * Lby);
PointOnSegBz = (B1z + t * Lbz);
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx,
PointOnSegBy, PointOnSegBz, false, epsilon_squared,
PointOnSegAx, PointOnSegAy, PointOnSegAz, s);
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
PointOnSegAy, PointOnSegAz, false, epsilon_squared,
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
}
}
// otherwise, handle the case where the parameter for only one segment is
// out of range
else if (OUT_OF_RANGE(s))
{
s = FMAX(0.0f, FMIN(1.0f, s));
PointOnSegAx = (A1x + s * Lax);
PointOnSegAy = (A1y + s * Lay);
PointOnSegAz = (A1z + s * Laz);
FindNearestPointOnLineSegment(B1x, B1y, B1z, Lbx, Lby, Lbz, PointOnSegAx,
PointOnSegAy, PointOnSegAz, false, epsilon_squared,
PointOnSegBx, PointOnSegBy, PointOnSegBz, t);
}
else if (OUT_OF_RANGE(t))
{
t = FMAX(0.0f, FMIN(1.0f, t));
PointOnSegBx = (B1x + t * Lbx);
PointOnSegBy = (B1y + t * Lby);
PointOnSegBz = (B1z + t * Lbz);
FindNearestPointOnLineSegment(A1x, A1y, A1z, Lax, Lay, Laz, PointOnSegBx,
PointOnSegBy, PointOnSegBz, false, epsilon_squared,
PointOnSegAx, PointOnSegAy, PointOnSegAz, s);
}
else
{
assert(0);
}
}
+80
View File
@@ -0,0 +1,80 @@
/* Copyright (C) Graham Rhodes, 2001.
* All rights reserved worldwide.
*
* This software is provided "as is" without express or implied
* warranties. You may freely copy and compile this source into
* applications you distribute provided that the copyright text
* below is included in the resulting source code, for example:
* "Portions Copyright (C) Graham Rhodes, 2001"
*/
/**************************************************************************************
|
| File: lineintersect_utils.h
|
| Purpose: Function prototypes for line segment intersection utility functions
|
| Book Title: Game Programming Gems II
|
| Chapter Title: Fast, Robust Intersection of 3D Line Segments
|
| Author: Graham Rhodes
|
| Revisions: 05-Apr-2001 - GSR. Original.
|
**************************************************************************************/
#ifndef _lineintersect_utils_h
#define _lineintersect_utils_h
void IntersectLineSegments(const D3DXVECTOR3 & A1,
const D3DXVECTOR3 & A2,
const D3DXVECTOR3 & B1,
const D3DXVECTOR3 & B2,
//bool infinite_lines, /*float epsilon,*/
D3DXVECTOR3 & OutA,
D3DXVECTOR3 & OutB);
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
const float A2x, const float A2y, const float A2z,
const float B1x, const float B1y, const float B1z,
const float B2x, const float B2y, const float B2z,
bool infinite_lines, float epsilon, float &PointOnSegAx,
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
float &PointOnSegBy, float &PointOnSegBz, float &NearestPointX,
float &NearestPointY, float &NearestPointZ, float &NearestVectorX,
float &NearestVectorY, float &NearestVectorZ, bool &true_intersection);
void IntersectLineSegments(const float A1x, const float A1y, const float A1z,
const float A2x, const float A2y, const float A2z,
const float B1x, const float B1y, const float B1z,
const float B2x, const float B2y, const float B2z,
bool infinite_lines, float epsilon, float &PointOnSegAx,
float &PointOnSegAy, float &PointOnSegAz, float &PointOnSegBx,
float &PointOnSegBy, float &PointOnSegBz);
void FindNearestPointOnLineSegment(const float A1x, const float A1y, const float A1z,
const float Lx, const float Ly, const float Lz,
const float Bx, const float By, const float Bz,
bool infinite_line, float epsilon_squared, float &NearestPointX,
float &NearestPointY, float &NearestPointZ,
float &parameter);
void FindNearestPointOfParallelLineSegments(float A1x, float A1y, float A1z,
float A2x, float A2y, float A2z,
float Lax, float Lay, float Laz,
float B1x, float B1y, float B1z,
float B2x, float B2y, float B2z,
float Lbx, float Lby, float Lbz,
bool infinite_lines, float epsilon_squared,
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz);
void AdjustNearestPoints(float A1x, float A1y, float A1z,
float Lax, float Lay, float Laz,
float B1x, float B1y, float B1z,
float Lbx, float Lby, float Lbz,
float epsilon_squared, float s, float t,
float &PointOnSegAx, float &PointOnSegAy, float &PointOnSegAz,
float &PointOnSegBx, float &PointOnSegBy, float &PointOnSegBz);
#endif // _lineintersect_utils_h
+443
View File
@@ -0,0 +1,443 @@
#include "StdAfx.h"
#include "parser.h"
using namespace script;
#define ishan(ch) (((ch) & 0xE0) > 0x90)
#define isnhspace(ch) (!ishan(ch) && isspace(ch))
extern DWORD GetDefaultCodePage();
const char* LocaleString_FindChar(const char* base, int len, char test)
{
if (!base)
return NULL;
DWORD codePage = GetDefaultCodePage();
int pos = 0;
while (pos < len)
{
const char* cur = base + pos;
const char* next = CharNextExA(codePage, cur, 0);
int cur_len = next - cur;
if (cur_len > 1)
{
pos += cur_len;
}
else if (1 == cur_len)
{
if (*cur == test)
return cur;
++pos;
}
else
{
break;
}
}
return NULL;
}
int LocaleString_RightTrim(char* base, int len)
{
DWORD codePage = GetDefaultCodePage();
int pos = len;
while (pos > 0)
{
char* cur = base + pos;
char* prev = CharPrevExA(codePage, base, cur , 0);
int prev_len = cur - prev;
if (prev_len != 1)
break;
if (!isspace((unsigned char) *prev) && *prev != '\n' && *prev != '\r')
break;
*prev = '\0';
pos -= prev_len;
}
if (pos > 0)
return pos;
return 0;
}
void LocaleString_RightTrim(char* base)
{
LocaleString_RightTrim(base, strlen(base));
}
void OLD_rtrim(char* base)
{
if (!base)
return;
DWORD codePage = GetDefaultCodePage();
if (949 == codePage || 936 == codePage)
{
char* end = base + strlen(base) - 1;
while (end != base)
{
if (!isnhspace((unsigned char) *end) && *end != '\n' && *end != '\r' || (end!=base && *((unsigned char*)end-1)>0xa0))
break;
*end = '\0';
end = CharPrevExA(codePage, base, end, 0);
}
}
else
{
char* end = base + strlen(base);
while (end != base)
{
char* prev = CharPrevExA(codePage, base, end, 0);
int prev_len = end - prev;
if (prev_len != 1)
break;
if (!isspace((unsigned char) *prev) && *prev != '\n' && *prev != '\r')
break;
*prev = '\0';
end = prev;
}
}
}
const char* LocaleString_Skip(DWORD codePage, const char* cur)
{
int loopCount = 0;
while (*cur)
{
if (++loopCount > 9216)
{
TraceError("Infinite loop in LocaleString_Skip [%s]", cur);
break;
}
const char* next = CharNextExA(codePage, cur, 0);
int cur_len = next - cur;
if (cur_len > 1)
{
cur = next;
}
else if (1 == cur_len)
{
if (!isspace((unsigned char) *cur) && *cur != '\n' && *cur != '\r')
return cur;
}
else
{
break;
}
}
return cur;
}
bool Group::GetArg(const char *c_arg_base, int arg_len, TArgList & argList)
{
char szName[32 + 1];
char szValue[64 + 1];
int iNameLen = 0;
int iValueLen = 0;
int iCharLen = 0;
int pos = 0;
bool isValue = false;
DWORD codePage = GetDefaultCodePage();
while (pos < arg_len)
{
const char* cur = c_arg_base + pos;
const char* next = CharNextExA(codePage, cur, 0);
iCharLen = next - cur;
if (iCharLen > 1)
{
if (isValue)
{
if (iValueLen >= 64)
{
TraceError("argument value overflow: must be shorter than 64 letters");
return false;
}
memcpy(szValue+iValueLen, cur, iCharLen);
iValueLen += iCharLen;
szValue[iValueLen] = '\0';
}
else
{
if (iNameLen >= 32)
{
TraceError("argument name overflow: must be shorter than 32 letters");
return false;
}
memcpy(szName+iNameLen, cur, iCharLen);
iNameLen += iCharLen;
szName[iNameLen] = '\0';
}
}
else if (iCharLen == 1)
{
const char c = *cur;
if (c == '|')
{
if (iNameLen == 0)
{
TraceError("no argument name");
return false;
}
isValue = false;
iNameLen = LocaleString_RightTrim(szName, iNameLen);
iValueLen = LocaleString_RightTrim(szValue, iValueLen);
argList.push_back(TArg(szName, szValue));
iNameLen = 0;
iValueLen = 0;
}
else if (c == ';')
{
isValue = true;
}
// 값이 아니고, 이름이 시작되지 않았을 경우 빈칸은 건너 뛴다.
else if (!isValue && iNameLen == 0 && isspace((unsigned char) c))
{
}
// 엔터는 건너 뛴다
else if (c == '\r' || c == '\n')
{
}
else
{
if (isValue)
{
if (iValueLen >= 64)
{
TraceError("argument value overflow: must be shorter than 64 letters");
return false;
}
memcpy(szValue+iValueLen, cur, iCharLen);
iValueLen += iCharLen;
szValue[iValueLen] = '\0';
}
else
{
if (iNameLen >= 32)
{
TraceError("argument name overflow: must be shorter than 32 letters");
return false;
}
memcpy(szName+iNameLen, cur, iCharLen);
iNameLen += iCharLen;
szName[iNameLen] = '\0';
}
}
}
else
{
break;
}
pos += iCharLen;
}
if (iNameLen != 0 && iValueLen != 0)
{
iNameLen = LocaleString_RightTrim(szName, iNameLen);
iValueLen = LocaleString_RightTrim(szValue, iValueLen);
argList.push_back(TArg(szName, szValue));
}
return true;
}
bool Group::Create(const std::string & stSource)
{
m_cmdList.clear();
if (stSource.empty())
return false;
const char *str_base = stSource.c_str();
if (!str_base || !*str_base)
{
TraceError("Source file has no content");
return false;
}
int str_len = stSource.length();
int str_pos = 0;
DWORD codePage = GetDefaultCodePage();
char box_data[1024 + 1];
static std::string stLetter;
while (str_pos < str_len)
{
TCmd cmd;
const char* word = str_base + str_pos;
const char* word_next = CharNextExA(codePage, word, 0);
int word_len = word_next - word;
if (word_len > 1)
{
str_pos += word_len;
{
stLetter.assign(word, word_next);
cmd.name.assign("LETTER");
cmd.argList.push_back(TArg("value", stLetter));
m_cmdList.push_back(cmd);
}
}
else if (word_len == 1)
{
const char cur = *word;
if ('[' == cur)
{
++str_pos;
const char* box_begin = str_base + str_pos;
const char* box_end = LocaleString_FindChar(box_begin, str_len - str_pos, ']');
if (!box_end)
{
TraceError(" !! PARSING ERROR - Syntax Error : %s\n", box_begin);
return false;
}
str_pos += box_end - box_begin + 1;
int data_len = 0;
{
const char* data_begin = LocaleString_Skip(codePage, box_begin);
const char* data_end = box_end;
data_len = data_end - data_begin;
if (data_len >= 1024)
{
TraceError(" !! PARSING ERROR - Buffer Overflow : %d, %s\n", data_len, str_base);
return false;
}
memcpy(box_data, data_begin, data_len);
box_data[data_len] = '\0';
data_len = LocaleString_RightTrim(box_data, data_len); // 오른쪽 빈칸 자르기
}
{
const char* space = LocaleString_FindChar(box_data, data_len, ' ');
if (space) // 인자가 있음
{
int name_len = space - box_data;
cmd.name.assign(box_data, name_len);
const char* space_next = CharNextExA(codePage, space, 0);
const char* arg = LocaleString_Skip(codePage, space_next);
int arg_len = data_len - (arg - box_data);
if (!GetArg(arg, arg_len, cmd.argList))
{
TraceError(" !! PARSING ERROR - Unknown Arguments : %d, %s\n", arg_len, arg);
return false;
}
}
else // 인자가 없으므로 모든 스트링이 명령어다.
{
cmd.name.assign(box_data);
cmd.argList.clear();
}
m_cmdList.push_back(cmd);
}
}
else if (cur == '\r' || cur == '\n')
{
++str_pos;
}
else
{
++str_pos;
{
stLetter.assign(1, cur);
cmd.name.assign("LETTER");
cmd.argList.push_back(TArg("value", stLetter));
m_cmdList.push_back(cmd);
}
}
}
else
{
break;
}
}
return true;
}
bool Group::GetCmd(TCmd & cmd)
{
if (m_cmdList.empty())
return false;
cmd = m_cmdList.front();
m_cmdList.pop_front();
return true;
}
bool Group::ReadCmd(TCmd & cmd)
{
if (m_cmdList.empty())
return false;
cmd = m_cmdList.front();
return true;
}
std::string & Group::GetError()
{
return m_stError;
}
void Group::SetError(const char * c_pszError)
{
m_stError.assign(c_pszError);
}
Group::Group()
{
}
Group::~Group()
{
}
+94
View File
@@ -0,0 +1,94 @@
#ifndef __INC_SCRIPT_PARSER_H__
#define __INC_SCRIPT_PARSER_H__
#include <list>
#include <string>
namespace script
{
typedef struct SArgumet
{
SArgumet(const std::string& c_stName, const std::string& c_stValue)
{
strName = c_stName;
strValue = c_stValue;
}
SArgumet(const SArgumet& c_arg)
{
strName = c_arg.strName;
strValue = c_arg.strValue;
}
void operator=(const SArgumet& c_arg)
{
strName = c_arg.strName;
strValue = c_arg.strValue;
}
std::string strName;
std::string strValue;
} TArg;
typedef std::list<TArg> TArgList;
typedef struct SCmd
{
std::string name;
TArgList argList;
SCmd()
{}
SCmd(const SCmd& c_cmd)
{
name = c_cmd.name;
argList = c_cmd.argList;
}
void operator=(const SCmd& c_cmd)
{
name = c_cmd.name;
argList = c_cmd.argList;
}
} TCmd;
class Group
{
public:
Group();
~Group();
public:
/** 스트링으로 부터 스크립트 그룹을 만든다.
*
* 실패하면 GetError 메소드로 확인할 수 있다.
*
* @param stSource 이 스트링으로 부터 그룹이 만들어 진다.
* @return 성공시 true, 실패하면 false
*/
bool Create(const std::string & stSource);
/** 명령어를 받는 메소드
*
* @param cmd 성공시에 이 구조체로 명령어가 복사 된다.
* @return 명령어가 남아 있다면 true, 없다면 false
*/
bool GetCmd(TCmd & cmd);
/*
명령어를 가져오되 꺼내지는 않는다.
*/
bool ReadCmd(TCmd & cmd);
/** 에러를 출력 받는 메소드
*
* @return stError 이 곳으로 에러가 출력 된다.
*/
std::string & GetError();
private:
void SetError(const char *str);
bool GetArg(const char * c_atr_base, int arg_len, TArgList & argList);
std::string m_stError;
std::list<TCmd> m_cmdList;
};
}
#endif