Files
2026-06-01 12:46:52 +02:00

521 lines
18 KiB
C++

#ifndef __KVIEWPORT__
#define __KVIEWPORT__
#include "K3DTypes.h"
#include <toolkit/khash.h>
#include "KResource.h"
#include "KResourceDX.h"
#include "KCustomVector.h"
#include "KSortVector.h"
#include "k3dcamera.h"
#include "kprimitive.h"
#include "KPrimitiveTile.h"
#include <list>
struct K3DLight;
class K3DPrimitive;
class KSpritePrimitive;
class KBillboardPrimitive;
class KWireUtilPrimitive;
class K3DRenderDevice;
class K3DCamera;
#ifdef _RAC
#define MESH_POOL_COUNT (1024)
#define AFTER_SPRITE_MESH_POOL_COUNT (128)
#else
#define MESH_POOL_COUNT (7168)
#define AFTER_SPRITE_MESH_POOL_COUNT (256)
#endif
class KViewportObject
{
public:
enum {
VIEWPORT_GAME = 1,
VIEWPORT_SHADOW = 2,
VIEWPORT_DUSK = 4,
VIEWPORT_WATER = 8,
// { [sonador]
#ifdef _KUI_INVALIDATION
VIEWPORT_GUI = 16,
#endif
// }
VIEWPORT_USER0 = 32,
VIEWPORT_USER1 = 64,
VIEWPORT_USER2 = 128,
VIEWPORT_MAPTOOL= 256, ///< 맵 툴용
VIEWPORT_VIEWER = 512, ///< 뷰어 용
};
enum
{
SHADOW_DEFAULT = 0, ///< 안 그린다.
SHADOW_RENDER, ///< 프로젝션 쉐도우
SHADOW_MAP_RENDER, ///< 쉐도우 맵
};
KViewportObject( DWORD attr, bool bClearColorBuffer, bool bClearDepthBuffer );
virtual ~KViewportObject();
DWORD GetAttributes() { return m_dwAttributes; }
virtual void SetRenderFlag( int nFlag ) {};
virtual void Initilaize( K3DRenderDevice *dev, const KViewportStruct &viewarea, float nearClip, float farClip );
KViewportStruct * GetViewportStruct() { return &m_viewport; }
virtual void SetViewArea( const KRect &viewarea );
virtual float GetVertexAspect() const { return (float)m_viewwidth/m_viewheight; }
float GetFarClip() const { return m_fFarClip; }
float GetNearClip() const { return m_fNearClip; }
const K3DMatrix* GetInverseViewMatrix() const
{
return &m_matInvView;
}
int GetFSAA() { return m_nFSAA; }
void SetFSAA( int size ) { m_nFSAA = size; }
float GetMipBias() { return m_fMipBias; }
void SetMipBias( float fBias ) { m_fMipBias = fBias; }
void SetMipRange( float fRange) { m_fMipRange = fRange; }
float GetMipRange() { return m_fMipRange; }
void SetMipMode( bool mode ) { m_bMipMode = mode; }
bool IsMipMode() { return m_bMipMode; }
void SetClipRange( float nearclip, float farclip )
{
m_fNearClip = nearclip;
m_fFarClip = farclip;
}
void SetSceneAmbient( const KColor &color ) { m_colSceneAmbient = color; }
void SetFillColor( const KColor &color ) { m_colFill = color; }
void SetFillMode( bool bColorBuf, bool bDepthBuf ) { m_bClearColorBuf = bColorBuf; m_bClearDepthBuf = bDepthBuf; }
void SetSkyColor( K3DColor start, K3DColor mid, K3DColor end )
{
m_SkyColorStart = start;
m_SkyColorMid = mid;
m_SkyColorEnd = end;
}
void SetSkyColorHeight( float fMinHeight, float fMaxHeight, float fMidPercent = 0.5f )
{
m_fSkyMinHeight = fMinHeight;
m_fSkyMaxHeight = fMaxHeight;
m_fSKyMidPercent = fMidPercent;
}
void SetFogMode(DWORD fogmode, KColor fogcolor, float p1, float p2, float p3, float p4)
{
m_fogMode = fogmode;
m_fogColor = fogcolor;
m_fogFactor1 = p1;
m_fogFactor2 = p2;
m_fogFactor3 = p3;
m_fogFactor4 = p4;
}
void GetFogMode(DWORD &fogmode, KColor &fogcolor, float &p1, float &p2, float &p3, float &p4) const
{
fogmode = m_fogMode;
fogcolor = m_fogColor;
p1 = m_fogFactor1;
p2 = m_fogFactor2;
p3 = m_fogFactor3;
p4 = m_fogFactor4;
}
void GetFogFactor( float &p1, float &p2, float &p3, float &p4) const
{
p1 = m_fogFactor1;
p2 = m_fogFactor2;
p3 = m_fogFactor3;
p4 = m_fogFactor4;
}
/*void SetViewTransform( const K3DVector &campos, const K3DVector &tarpos, const K3DMatrix &view, const K3DMatrix &projection )
{ m_matView = view; m_matProjection = projection; m_vCamPos = campos; K3DMatrixInverse( &m_matInvView, NULL, &m_matView );
m_vTarPos = tarpos;
K3DMatrixIdentity( m_matBlendShader );
K3DMatrixMultiply(&m_matBlendShader, &m_matView, &m_matProjection);
K3DMatrixTranspose( &m_matBlendShader, &m_matBlendShader );
}*/
int GetViewportX() { return m_viewx; }
int GetViewportY() { return m_viewy; }
int GetViewportWidth() { return m_viewwidth; }
int GetViewportHeight() { return m_viewheight; }
const K3DVector& GetCameraPos() { return m_vCamPos; }
const K3DVector& GetCameraTargetPos() { return m_vTarPos; }
float GetCameraFOV() { return m_ViewCamera.GetFOV(); }
//const K3DCamera* GetCamera() { return &m_ViewCamera; }
const K3DMatrix * GetProjMatrix() { return &m_matProjection; }
const K3DMatrix * GetViewMatrix() { return &m_matView; }
const K3DMatrix * GetBlendMatrix(){ return &m_matBlendShader; } //Speed Tree
virtual void SetCamera( const K3DCamera *cam );
K3DVector* GetFrustum();
void GetCameraSegmentView(float o_scrX, float o_scrY, K3DVector &nearPt, K3DVector &farPt);
void GetCameraFrustum(float left, float top, float right, float bottom, K3DVector *cube);
void SetClipOffsetRatio( float fRatio );
float GetClipOffsetRatio();
void PickScreenPoint(const K3DVector &pos, int &x, int &y);
virtual void AddLight( const K3DLight *lit );
virtual void Register( KSpritePrimitive *spr, bool isFront = false );
virtual void Register( KBillboardPrimitive *pBillboard );
virtual void Register( K3DPrimitive *pr, DWORD flag );
virtual void Register(KTilePrimitive* tpr);
virtual void RegisterWire( KWireUtilPrimitive *wpr );
virtual void Render( K3DRenderTarget *pRT, DWORD flag = 0, bool bClearRegister = true );
virtual void Render( bool bClearRegister = true, bool bSetRenderTarget = true );
virtual void ClearRegisteredList();
virtual const K3DLight * GetLight( int nIndex = 0 );
KViewportObject* GetChildViewportObj() const { return m_pChildViewportObj; }
KViewportObject* SetChildViewportObj( KViewportObject* pChild )
{
KViewportObject* pOldChild = m_pChildViewportObj;
m_pChildViewportObj = pChild;
return pOldChild;
}
virtual void OcclusionCulling() { };
void SetUseWater( bool bUseWater );
void SetUseSpecular( int nUseSpecular );
void SetUseViewPort( bool bUseViewPort );
void SetRenderWater( bool bRenderWater );
int GetUseSpecular() { return m_nUseSpecular; }
bool GetUseViewPort() { return m_bUseViewPort; }
bool GetUseWater() { return m_bUseWater; }
bool IsRenderWater() { return m_bRenderWater; }
void SetRenderBumpMapMode( bool bRender ) { m_bRenderBumpMap = bRender; }
bool GetRenderBumpMapMode() { return m_bRenderBumpMap; }
void SetTerrainSpecularFactor( float fFactor ) { m_fTerrainSpecularFactor = fFactor; }
float GetTerrainSpecularFactor() { return m_fTerrainSpecularFactor; }
void SetSkinAmbientFactor( float fFactor ) { m_fSkinAmbientFactor = fFactor; }
float GetSkinAmbientFactor() { return m_fSkinAmbientFactor; }
void SetSkinDiffuseFactor( float fFactor ) { m_fSkinDiffuseFactor = fFactor; }
float GetSkinDiffuseFactor() { return m_fSkinDiffuseFactor; }
void SetSkinSpecularFactor( float fFactor ) { m_fSkinSpecularFactor = fFactor; }
float GetSkinSpecularFactor() { return m_fSkinSpecularFactor; }
virtual void SetHQWaterHeight( float fHeight ){};
void SetWaterHeight( bool bExistence, float fHeight = -3.0000000e+038f );
void SetInsideWater( bool bInside );
//void SetLocalCoordMode(bool bLocalCoord) { m_bLocalCoord = bLocalCoord; }
//bool IsLocalCoordMode() { return m_bLocalCoord; }
float DoesExistWaterHeight() { return m_bExistenceWaterHeight; }
float GetWaterHeight() { return m_fWaterHeight; }
void BackUpViewCamera() { m_BackUpViewCamera = m_ViewCamera; }
const K3DCamera* GetBackUpViewCamera() { return &m_BackUpViewCamera ; }
void RestoreBackUpViewCamera() { SetCamera( &m_BackUpViewCamera ); }
bool IsLocalCoord() { return m_bLocalCoord; }
/// 2D -> 3D
void Get2DVto3DV( const K3DVector & v2D, K3DVector & v3D );
/// 3D -> 2D
void Get3DVto2DV( const K3DVector & v3D, K3DVector & v2D );
void SetSpeedTreeTransparent( bool bMode ) { m_bSpeedTreeTransMode = bMode; }
bool IsSpeedTreeTransparent() { return m_bSpeedTreeTransMode; }
const int GetUsedMeshEXPoolCount() { return m_nUsedMeshEXPool; }
#ifdef _KUI_INVALIDATION
// { [sonador]
virtual void RearrangeSpriteOffset( const K3DVector& vOffset );
// }
#endif
// z,x 로 조절하는 spec_factor 과 spec_color
int m_nSpecularFactor;
int m_nSpecularColor;
protected:
HRESULT TestCooperativeLevel();
void renderDefault();
void updateLight();
void drawSprite( KSpritePrimitive** prSpriteList, int nSpriteCount );
void sortCenter( K3DPrimitive** prList, int nPrCount );
void sortDepth( K3DPrimitive** prList, int nPrCount );
void sortDepth( KBillboardPrimitive** prList, int nPrCount );
protected:
DWORD m_dwAttributes;
bool m_bMipMode;
bool m_bClearColorBuf;
bool m_bClearDepthBuf;
int m_viewx;
int m_viewy;
int m_viewwidth;
int m_viewheight;
float m_fVertexAspect;
float m_fNearClip, m_fFarClip;
KColor m_colFill;
KColor m_colSceneAmbient;
K3DCamera m_ViewCamera;
K3DCamera m_BackUpViewCamera;
K3DVector m_pFrustum[8];
K3DMatrix m_matView;
K3DMatrix m_matProjection;
K3DVector m_vCamPos;
K3DVector m_vTarPos;
K3DMatrix m_matInvView;
K3DMatrix m_matBlendShader;
K3DVector m_vCameraCorrection; ///< 위치 보정을 통해 오차를 최소화 한다.
float m_fMipBias;
float m_fMipRange;
int m_nFSAA;
DWORD m_fogMode;
KColor m_fogColor;
float m_fogFactor1;
float m_fogFactor2;
float m_fogFactor3;
float m_fogFactor4;
KViewportObject* m_pChildViewportObj;
K3DColor m_SkyColorStart;
K3DColor m_SkyColorMid;
K3DColor m_SkyColorEnd;
float m_fSkyMaxHeight; ///< 하늘 칼라 시작 점
float m_fSkyMinHeight; ///< 하늘 칼라 끝 점
float m_fSKyMidPercent; ///< 하늘 중점 비율
//Specular
bool m_bUseWater;
int m_nUseSpecular;
bool m_bUseViewPort;
bool m_bRenderWater;
bool m_bRenderBumpMap;
float m_fTerrainSpecularFactor;
float m_fSkinAmbientFactor;
float m_fSkinDiffuseFactor;
float m_fSkinSpecularFactor;
K3DRenderDevice* m_dev;
KViewportStruct m_viewport;
// light
KCustomVector<const K3DLight*> m_pLightList;
// 환경
KCustomVector<K3DPrimitive*> m_prListSky;
KCustomVector<K3DPrimitive*> m_prListLensFlare;
KCustomVector<K3DPrimitive*> m_prListCloud;
KCustomVector<K3DPrimitive*> m_prListWeather; ///< [sonador][2007.03.19] custom vector of weather primitives
KCustomVector<K3DPrimitive*> m_prListLightning; ///< [sonador][2007.04.25] custom vector of lightning primitives
// 지형
KCustomVector<K3DPrimitive*> m_prListTerrain;
KCustomVector<K3DPrimitive*> m_prListTerrainShadow;
//Speed Tree - 알파 블렌드를 사용하지 않음
KCustomVector<K3DPrimitive*> m_prListBranch;
KCustomVector<K3DPrimitive*> m_prListFrond;
KCustomVector<K3DPrimitive*> m_prListLeaf;
KCustomVector<K3DPrimitive*> m_prListTreeBillboard;
KCustomVector<K3DPrimitive*> m_prListSpeedGrass;
//KCustomVector<K3DPrimitive*> m_prListPathEffect;
KCustomVector<K3DPrimitive*> m_prListQuad;
KCustomVector<K3DPrimitive*> m_prListLine;
KCustomVector<K3DPrimitive*> m_prListPolyLine;
struct RENDER_MESHEX
{
RENDER_MESHEX() { primitive = NULL; }
void Set( K3DPrimitive* p, DWORD f, int l, bool bump, bool spec, bool vsmode, bool lightmap, float depth, int pass = 0 )
{
primitive = p;
render_flag = f;
nLitIndex = l;
bUseBump = bump;
bUseSpecular = spec;
bUseVSMode = vsmode;
bUseLightmap = lightmap;
fDepth = depth;
nPass = pass;
dwPriority = ( ( WORD ) p->GetBlendMode() << 16 ) | ( ( WORD ) pass );
bForcePriority = ( p->GetBlendMode() == K3DMaterial::MBM_ADDITIVE || p->GetBlendMode() == K3DMaterial::MBM_ADDTIVE_BILLBOARD );
}
float GetHashNumber() const { return fDepth; }
// basic render object
K3DPrimitive* primitive;
DWORD render_flag;
// state
bool bUseBump; ///< bump map을 사용하는 경우
bool bUseSpecular; ///< specular map을 사용하는 경우(일반 specular와 다름)
bool bUseVSMode;
bool bUseLightmap;
float fDepth;
int nLitIndex;
int nPass;
DWORD dwPriority;
bool bForcePriority;
//K3DMatrix matRoot; // root(world positioning) matrix
//K3DMatrix matLocal; // local to world matrix
bool operator== (const RENDER_MESHEX* rhs) const { return (this->GetHashNumber() == rhs->GetHashNumber()); }
bool operator!= (const RENDER_MESHEX* rhs) const { return (this->GetHashNumber() != rhs->GetHashNumber()); }
bool operator> (const RENDER_MESHEX* rhs) const { return (this->GetHashNumber() > rhs->GetHashNumber()); }
bool operator>= (const RENDER_MESHEX* rhs) const { return (this->GetHashNumber() >= rhs->GetHashNumber()); }
bool operator< (const RENDER_MESHEX* rhs) const { return (this->GetHashNumber() < rhs->GetHashNumber()); }
bool operator<= (const RENDER_MESHEX* rhs) const { return (this->GetHashNumber() <= rhs->GetHashNumber()); }
float operator- (const RENDER_MESHEX* rhs) const { return (this->GetHashNumber() - rhs->GetHashNumber()); }
bool operator== (const RENDER_MESHEX& rhs) const { return (this->GetHashNumber() == rhs.GetHashNumber()); }
bool operator!= (const RENDER_MESHEX& rhs) const { return (this->GetHashNumber() != rhs.GetHashNumber()); }
bool operator> (const RENDER_MESHEX& rhs) const { return (this->GetHashNumber() > rhs.GetHashNumber()); }
bool operator>= (const RENDER_MESHEX& rhs) const { return (this->GetHashNumber() >= rhs.GetHashNumber()); }
bool operator< (const RENDER_MESHEX& rhs) const { return (this->GetHashNumber() < rhs.GetHashNumber()); }
bool operator<= (const RENDER_MESHEX& rhs) const { return (this->GetHashNumber() <= rhs.GetHashNumber()); }
float operator- (const RENDER_MESHEX& rhs) const { return (this->GetHashNumber() - rhs.GetHashNumber()); }
};
struct PRIMITIVE_CONTAINER
{
// PRIMITIVE_CONTAINER(const RENDER_MESHEX *p) { pr = p; }
bool operator==(const PRIMITIVE_CONTAINER& p) const { return (pr->GetHashNumber() == p.pr->GetHashNumber()); }
bool operator!=(const PRIMITIVE_CONTAINER& p) const { return (pr->GetHashNumber() != p.pr->GetHashNumber()); }
bool operator>(const PRIMITIVE_CONTAINER& p) const { return (pr->GetHashNumber() > p.pr->GetHashNumber()); }
bool operator>=(const PRIMITIVE_CONTAINER& p) const { return (pr->GetHashNumber() >= p.pr->GetHashNumber()); }
bool operator<(const PRIMITIVE_CONTAINER& p) const { return (pr->GetHashNumber() < p.pr->GetHashNumber()); }
bool operator<=(const PRIMITIVE_CONTAINER& p) const { return (pr->GetHashNumber() <= p.pr->GetHashNumber()); }
float operator-(const PRIMITIVE_CONTAINER& p) const { return (pr->GetHashNumber() - p.pr->GetHashNumber()); }
bool IsValid() { return pr != NULL; }
void SetRenderMesh(const RENDER_MESHEX *p) { pr = p; }
const RENDER_MESHEX *pr;
};
typedef KCustomVector<RENDER_MESHEX> vec_rendermesh;
// RENDER_MESHEX m_pAfterSpriteMeshEXPool[AFTER_SPRITE_MESH_POOL_COUNT];
int m_nAfterSpriteUsedMeshEXPool;
float m_fAfterSpriteDepth;
bool AllocAfterSpriteNewMeshEX( RENDER_MESHEX & container, K3DPrimitive* p, DWORD f, int l, bool bump, bool spec, bool vsmode, bool lightmap, float depth, int pass = 0 )
{
#ifdef _RELEASE
if( m_nAfterSpriteUsedMeshEXPool >= AFTER_SPRITE_MESH_POOL_COUNT )
return false;
#else
if( m_nAfterSpriteUsedMeshEXPool >= AFTER_SPRITE_MESH_POOL_COUNT )
{
if( m_fDepth < depth )
return false;
}
#endif
if( m_fDepth < depth ) m_fDepth = depth;
// RENDER_MESHEX* alloc = &m_pAfterSpriteMeshEXPool[ m_nAfterSpriteUsedMeshEXPool ];
++m_nAfterSpriteUsedMeshEXPool;
container.Set( p, f, l, bump, spec, vsmode,lightmap, depth, pass );
return true;
}
// 메쉬 pool
// RENDER_MESHEX m_pMeshEXPool[MESH_POOL_COUNT];
int m_nUsedMeshEXPool;
float m_fDepth;
bool AllocNewMeshEX( RENDER_MESHEX & container, K3DPrimitive* p, DWORD f, int l, bool bump, bool spec, bool vsmode, bool lightmap, float depth, int pass = 0, bool forceRender = false )
{
// sonador 7.0.14 카메라 위치에 따른 물효과 컬링 문제 수정
// soandor 1.6.2 프랍 렌더링시 정렬 문제 해결
// if( !forceRender )
// {
//#ifdef _RELEASE
// //1024개 제한 설정
// if( m_nUsedMeshEXPool >= MESH_POOL_COUNT )
// return false;
//#else
// if( m_nUsedMeshEXPool >= MESH_POOL_COUNT )
// {
// if( m_fDepth < depth )
// return false;
// }
//#endif
// ++m_nUsedMeshEXPool;
// }
++m_nUsedMeshEXPool;
if( m_fDepth < depth ) m_fDepth = depth;
// RENDER_MESHEX* alloc = &m_pMeshEXPool[ m_nUsedMeshEXPool ];
container.Set( p, f, l, bump, spec, vsmode,lightmap, depth, pass );
return true;
}
/// 메쉬(건물, 프랍)
vec_rendermesh m_prMesh;
vec_rendermesh m_prTransMesh;
// KSortVector<PRIMITIVE_CONTAINER> m_prAdditiveMesh;
vec_rendermesh m_prAfterSpriteMesh;
vec_rendermesh m_prAfterSpriteTransMesh;
vec_rendermesh m_prSelectMesh;
// sprite & billboard
KCustomVector<KBillboardPrimitive*> m_prBliiboardList;
KCustomVector<KBillboardPrimitive*> m_prAdditiveBliiboardList;
KCustomVector<KSpritePrimitive*> m_prFrontSpriteList;
KCustomVector<KSpritePrimitive*> m_prFrontAdditiveSpriteList;
KCustomVector<KSpritePrimitive*> m_prSpriteList;
KCustomVector<KSpritePrimitive*> m_prAdditiveSpriteList;
KCustomVector<KTilePrimitive*> m_prTileList;
std::list<KWireUtilPrimitive*> m_wprList;
// bool m_bLocalCoord;
float m_fClipOffsetRatio;
bool m_bLocalCoord;
bool m_bSpeedTreeTransMode;
/// 수위(물 높이)
float m_fWaterHeight;
bool m_bInsideWater;
bool m_bExistenceWaterHeight;
};
#endif