Files
Leviathan/Client/Game/game/Env/SEnvPrimitive.h
T
2026-06-01 12:46:52 +02:00

1057 lines
26 KiB
C++

#pragma once
#include "K3DTypes.h"
#include "KViewport.h"
#include "KRenderDevice.h"
#include "KPrimitive.h"
namespace env_fx {
const short c_WaterDetailSegment = 5; ///< 세부 세그먼트 개수
const short c_WaterDetailSegmentIndexedCount = (c_WaterDetailSegment-1)*(c_WaterDetailSegment-1)*2;
}
class SEnvPrimitive : public K3DPrimitive
{
public:
SEnvPrimitive()
{
m_pMtl = NULL;
m_pVertex = NULL;
m_pIndexed = NULL;
m_type = KPRIMITIVE_ENV;
m_fWaterHeight = 0.0f;
m_pVB = NULL;
m_fUAni = 0.0f;
m_fVAni = 0.0f;
}
virtual ~SEnvPrimitive()
{
if( m_pVB ) m_pVB->Release();
}
inline void SetMaterial( K3DMaterial *mtl )
{
m_pMtl = mtl;
}
inline void SetIndexBuffer( K3DIndexBuffer *buf )
{
m_spIB = buf;
}
inline void SetVertexBuffer( K3DVertexBuffer *buf )
{
m_pVB = buf;
if( m_pVB ) m_pVB->AddRef();
}
inline void SetTexture( int index, K3DTexture *tex )
{
m_spTexBack = tex;
}
// { [sonador]
inline void SetAlphaTexture( int index, K3DTexture *tex )
{
m_spTexAlpha = tex;
}
// } [sonador]
inline void SetCommonVertex( void* pVertex )
{
m_pVertex = pVertex;
}
inline void SetCommonIndexed( void* pIndexed )
{
m_pIndexed = pIndexed;
}
inline void SetHQWaterHeight( float fHeight )
{
m_fWaterHeight = fHeight;
}
inline void SetTextureUVAnimation( float fU, float fV )
{
m_fUAni = fU;
m_fVAni = fV;
}
virtual inline void SetTextureStage( int index, K3DTexture *tex )
{
assert(false);
}
K3DTexture * GetTexture() { return m_spTexBack; }
virtual void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true ) = 0;
// { [sonador] Interface for SWeatherPrimitive
virtual void SetVertexCnt( int nVtxCnt ) {}
virtual void SetVertexFmt( int nFmt ) {}
virtual void SetVertexStride( int nStride ) {}
virtual int GetVertexCnt() const { return 0; }
virtual int GetIndexCnt() const { return 0; }
// }
protected:
// K3DVertexBufferSPtr m_spVB;
K3DVertexBuffer* m_pVB;
K3DIndexBufferSPtr m_spIB;
K3DMaterial* m_pMtl;
K3DTextureSPtr m_spTexBack;
K3DTextureSPtr m_spTexAlpha; // [sonador] sub texture for multi-texturing
void* m_pVertex;
void* m_pIndexed;
float m_fWaterHeight;
float m_fUAni, m_fVAni;
};
//class SUVWrapPrimitive : public SEnvPrimitive
//{
// virtual void Render( KViewportObject* viewport, K3DRenderDevice* dev )
// {
//// dev->SetTransformIdentity( K3DRenderDevice::TS_WORLD );
// dev->SetTransform( K3DRenderDevice::TS_WORLD, *m_pTransform );
// dev->SetTransform( K3DRenderDevice::TS_TEXTURE0, *m_pShadowUV );
//
// dev->SetTexture( 0, m_spTexBack );
// dev->SetTexture( 1, NULL );
// dev->SetTexture( 2, NULL );
// dev->SetTexture( 3, NULL );
//
// dev->DrawIndexedTriangleVB( m_spVB, m_spIB );
// }
//};
//
//class SWaterPrimitive : public SEnvPrimitive
//{
//public:
// SWaterPrimitive( )
// {
// m_pBumpMat = NULL;
// }
//
// ~SWaterPrimitive()
// {
// }
//
// inline void SetBumpMat( K3DMatrix * pBumpMat )
// {
// m_pBumpMat = pBumpMat;
// }
//
// inline void SetTexture( int index, K3DTexture *tex )
// {
// if( index == 0 )
// m_spTexBump = tex;
// else
// m_spTexBack = tex;
// }
//
// virtual void Render( KViewportObject* viewport, K3DRenderDevice* dev )
// {
// dev->SetRenderState( K3DRenderDevice::RS_WATER );
//
// dev->SetTransform( K3DRenderDevice::TS_WORLD, *m_pTransform );
//
// dev->SetMaterial( m_pMtl );
//
// dev->SetTexture( 0, m_spTexBump );
// dev->SetTexture( 1, m_spTexBack );
//
// dev->SetBumpState( m_pBumpMat );
//
// dev->DrawIndexedTriangleVB( m_spVB, m_spIB );
//
// dev->SetTexture( 0, NULL );
// dev->SetTexture( 1, NULL );
// }
//
//public:
//
//
//protected:
// K3DTexture * m_spTexBack;
// K3DTexture * m_spTexBump;
//
// K3DMatrix * m_pBumpMat;
//};
/// [sonador] weather primitive(line) 클래스
class SWeatherLinedPrimitive : public SEnvPrimitive
{
public:
SWeatherLinedPrimitive()
: SEnvPrimitive()
, m_nVtxCnt( 0 )
, m_nVtxFmt( 0 )
, m_nVtxStride( 0 )
, m_nIdxCnt( 0 )
{
}
virtual void SetVertexCnt( int nVtxCnt )
{
m_nVtxCnt = nVtxCnt;
m_nIdxCnt = (int)( (float)nVtxCnt * 1.5f );
}
virtual void SetVertexFmt( int nFmt )
{
m_nVtxFmt = nFmt;
}
virtual void SetVertexStride( int nStride )
{
m_nVtxStride = nStride;
}
virtual int GetVertexCnt() const { return m_nVtxCnt; }
virtual void Render( KViewportObject* viewport, K3DRenderDevice* dev, bool bUseAccum = true )
{
dev->SetTexture( 0, m_spTexBack );
dev->SetTransform( K3DRenderDevice::TS_WORLD, m_pTransform );
dev->DrawLines( m_nVtxFmt, m_pVertex, m_nVtxCnt, m_nVtxStride );
}
public:
int m_nVtxCnt;
int m_nVtxFmt;
int m_nVtxStride;
int m_nIdxCnt;
};
/// [sonador] 날씨 primitive(텍스쳐) 클래스
class SWeatherTexturedPrimitive : public SEnvPrimitive
{
public:
SWeatherTexturedPrimitive()
: SEnvPrimitive()
, m_nVtxCnt( 0 )
, m_nVtxFmt( 0 )
, m_nVtxStride( 0 )
, m_nIdxCnt( 0 )
, m_vAreaPosition( 0, 0, 0 )
, m_vAreaVelocity( 0, 0, 0 )
{
}
virtual void SetVertexCnt( int nVtxCnt )
{
m_nVtxCnt = nVtxCnt;
m_nIdxCnt = (int)( (float)nVtxCnt * 1.5f );
}
virtual void SetVertexFmt( int nFmt )
{
m_nVtxFmt = nFmt;
}
virtual void SetVertexStride( int nStride )
{
m_nVtxStride = nStride;
}
virtual int GetVertexCnt() const { return m_nVtxCnt; }
void SetAreaPosition( const K3DVector& vPosition )
{
m_vAreaPosition = vPosition;
}
void SetAreaVelocity( const K3DVector& vVelocity )
{
m_vAreaVelocity = vVelocity;
}
virtual void Render( KViewportObject* viewport, K3DRenderDevice* dev, bool bUseAccum = true )
{
dev->SetVertexShaderConstant( CONSTANT_WEATHER_AREA_POSITION, (float*)&m_vAreaPosition, 3 );
dev->SetVertexShaderConstant( CONSTANT_WEATHER_AREA_VELOCITY, (float*)&m_vAreaVelocity, 3 );
dev->SetTransform( K3DRenderDevice::TS_WORLD, m_pTransform );
dev->SetTexture( 0, m_spTexBack );
dev->DrawIndexedPrimitiveUP_VS( m_nVtxFmt, m_pVertex, m_nVtxCnt, m_nVtxStride, (unsigned short*)m_pIndexed, m_nIdxCnt );
}
public:
int m_nVtxCnt;
int m_nVtxFmt;
int m_nVtxStride;
int m_nIdxCnt;
K3DVector m_vAreaPosition;
K3DVector m_vAreaVelocity;
};
/// [sonador] lightning primitive 클래스
class SWeatherLightningPrimitive : public SEnvPrimitive
{
public:
SWeatherLightningPrimitive()
: SEnvPrimitive()
//, m_nVtxCnt( 0 )
, m_nVtxFmt( 0 )
, m_nVtxStride( 0 )
//, m_nIdxCnt( 0 )
{
}
public:
struct SGeometryInfo
{
SGeometryInfo()
: vertexCount ( 0 )
, indexCount ( 0 )
//, vertexOffset ( 0 )
//, indexOffset ( 0 )
{}
SGeometryInfo( const SGeometryInfo& other )
{
texture = other.texture;
vertexCount = other.vertexCount;
indexCount = other.indexCount;
}
SGeometryInfo& operator = ( const SGeometryInfo& other )
{
if( this == &other ) return *this;
texture = other.texture;
vertexCount = other.vertexCount;
indexCount = other.indexCount;
return *this;
}
void IncreasePrimitiveCount( int prim = 1 )
{
vertexCount += 4 * prim;
indexCount += 6 * prim;
}
K3DTextureSPtr texture;
int vertexCount;
int indexCount;
//int vertexOffset;
//int indexOffset;
};
struct SResetGeomCounter
{
void operator () ( SGeometryInfo& info )
{
info.vertexCount = 0;
info.indexCount = 0;
}
};
struct SVertexCounter
{
SVertexCounter() : result( 0 ) {}
void operator () ( const SGeometryInfo& info )
{
result += info.vertexCount;
}
int result;
};
struct SIndexCounter
{
SIndexCounter() : result( 0 ) {}
void operator () ( const SGeometryInfo& info )
{
result += info.indexCount;
}
int result;
};
typedef std::vector< SGeometryInfo > geom_container_type;
public:
//virtual void SetVertexCnt( int nVtxCnt )
//{
// m_nVtxCnt = nVtxCnt;
// m_nIdxCnt = (int)( (float)nVtxCnt * 1.5f );
//}
virtual void SetVertexFmt( int nFmt )
{
m_nVtxFmt = nFmt;
}
virtual void SetVertexStride( int nStride )
{
m_nVtxStride = nStride;
}
virtual int GetVertexCnt() const
{
return std::for_each( m_ctGeometries.begin(),
m_ctGeometries.end(),
SVertexCounter() ).result;
}
virtual int GetIndexCnt() const
{
return std::for_each( m_ctGeometries.begin(),
m_ctGeometries.end(),
SIndexCounter() ).result;
}
void AddGeometryInfo( const SGeometryInfo& info )
{
m_ctGeometries.push_back( info );
}
void ResetGeometryCount()
{
std::for_each( m_ctGeometries.begin(), m_ctGeometries.end(), SResetGeomCounter() );
}
SGeometryInfo& GetGeometryInfoAt( int index )
{
assert( index >= 0 && index < (int)m_ctGeometries.size() );
return m_ctGeometries[ index ];
}
size_t GetGeometrySize() const { return m_ctGeometries.size(); }
bool IsGeometryEmpty() const { return m_ctGeometries.empty(); }
virtual void Render( KViewportObject* viewport, K3DRenderDevice* dev, bool bUseAccum = true )
{
dev->SetTransform( K3DRenderDevice::TS_WORLD, m_pTransform );
size_t size = m_ctGeometries.size();
int vertex_offset = 0, index_offset = 0;
for( size_t n = 0; n < size; ++n )
{
SGeometryInfo& info = m_ctGeometries[ n ];
if( info.vertexCount > 0 )
{
dev->SetTexture( 0, info.texture );
dev->DrawIndexedPrimitiveUP(
m_nVtxFmt,
((K3DSPRITEVERTEX*)m_pVertex) + vertex_offset, info.vertexCount,
m_nVtxStride,
((unsigned short*)m_pIndexed) + index_offset, info.indexCount );
}
vertex_offset += info.vertexCount;
index_offset += info.indexCount;
}
}
protected:
//int m_nVtxCnt;
int m_nVtxFmt;
int m_nVtxStride;
//int m_nIdxCnt;
geom_container_type m_ctGeometries;
};
class SCloudPrimitive : public SEnvPrimitive
{
public:
SCloudPrimitive()
: SEnvPrimitive()
, m_nVtxCnt( 0 )
{
}
virtual void SetVertexCnt( int nVtxCnt )
{
m_nVtxCnt = nVtxCnt;
}
virtual int GetVertexCnt() const { return m_nVtxCnt; }
virtual void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true )
{
// dev->SetTransform( K3DRenderDevice::TS_WORLD, m_pTransform );
//dev->SetVertexShaderConstant(CONSTANT_VISIBILITY, (const float *)&m_pMtl->Diffuse.a, 1);
// dev->SetMaterial( m_pMtl );
dev->SetTexture( 0, m_spTexBack );
dev->DrawIndexedTriangleVB_VS( m_pVB, m_spIB );
}
protected:
int m_nVtxCnt;
};
class SLensPrimitive : public SEnvPrimitive
{
public:
enum
{
NUM_VERTEX = 4,
NUM_INDEX = 6,
};
public:
virtual void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true )
{
dev->SetMaterial( m_pMtl );
dev->SetTexture( 0, m_spTexBack );
dev->DrawIndexedPrimitiveUP( VERTEX_LENS, m_pVertex, NUM_VERTEX, sizeof(K3DVERTEX_LENS), (WORD*)m_pIndexed, NUM_INDEX );
}
};
//class SShadowPrimitive : public SEnvPrimitive
//{
//public:
// virtual void Render( KViewportObject* viewport, K3DRenderDevice* dev )
// {
// dev->SetTransformIdentity( K3DRenderDevice::TS_WORLD );
// dev->SetTransform( K3DRenderDevice::TS_TEXTURE0, *m_pShadowUV );
//
// dev->SetTexture( 0, m_spTexBack );
// dev->SetTexture( 1, NULL );
// dev->SetTexture( 2, NULL );
// dev->SetTexture( 3, NULL );
//
// dev->DrawIndexedTriangleVB( m_spVB, m_spIB );
// }
//};
//
//class SLightMapPrimitive : public SEnvPrimitive
//{
//public:
// virtual void Render( KViewportObject* viewport, K3DRenderDevice* dev )
// {
// dev->SetTransformIdentity( K3DRenderDevice::TS_WORLD );
// dev->SetTransform( K3DRenderDevice::TS_TEXTURE0, *m_pShadowUV );
//
// dev->SetTexture( 0, m_spTexBack );
// dev->SetTexture( 1, NULL );
// dev->SetTexture( 2, NULL );
// dev->SetTexture( 3, NULL );
//
// dev->DrawIndexedTriangleVB( m_spVB, m_spIB );
// }
//};
class SLowQualityWaterPrimitive : public SEnvPrimitive
{
private:
K3DTextureSPtr m_pTexture[2];
public:
inline void SetTextureStage( int index, K3DTexture *tex )
{
m_pTexture[index] = tex;
}
public:
virtual void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true )
{
K3DVector4 uvani(m_fUAni, m_fVAni, -m_fUAni, -m_fVAni);
dev->SetVertexShaderConstant(CONSTANT_UVANIMATION, (float *)&uvani, 4);
dev->SetTexture( 0, m_spTexBack );
dev->SetTexture( 1, NULL/*m_pTexture[1]*/ );
dev->SetTexture( 2, NULL );
dev->SetTexture( 3, NULL );
// dev->SetTransform( K3DRenderDevice::TS_WORLD, m_pTransform );
// dev->DrawTriangleStrip( VERTEX_WATER, m_pVertex, 4, sizeof(K3DVERTEX_WATER));
// dev->DrawTriangles( VERTEX_WATER, m_pVertex, m_nVertexCount, sizeof(K3DVERTEX_WATER), (WORD*)m_pIndexed, m_nIndexedCount );
dev->DrawIndexedPrimitiveUP_VS(
0,
m_pVertex,
env_fx::c_WaterDetailSegment * env_fx::c_WaterDetailSegment,
sizeof( K3DVERTEX_H_WATER ),
(WORD*)m_pIndexed,
env_fx::c_WaterDetailSegmentIndexedCount * 3 );
}
};
class SHighQualityWaterPrimitive : public SEnvPrimitive
{
public:
enum
{
NUM_SEGMENTS = 60
};
virtual void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true )
{
viewport->SetHQWaterHeight( m_fWaterHeight );
K3DVERTEX_H_WATER* pWatervertex = (K3DVERTEX_H_WATER*)m_pVertex;
K3DVector* pFrustum = viewport->GetFrustum();
K3DVector pos[ 4 ], tpos[ 4 ];
float val;
K3DVector vTrans;
K3DMatrixGetPosVector( vTrans, m_RootMat );
float fWaterHeight = m_fWaterHeight + vTrans.z;
val = (fWaterHeight - pFrustum[0].z)/(pFrustum[3].z - pFrustum[0].z);
pos[0] = val*pFrustum[3] + (1 - val)*pFrustum[0];
val = (fWaterHeight - pFrustum[1].z)/(pFrustum[2].z - pFrustum[1].z);
pos[1] = val*pFrustum[2] + (1 - val)*pFrustum[1];
val = (fWaterHeight - pFrustum[4].z)/(pFrustum[7].z - pFrustum[4].z);
pos[2] = val*pFrustum[7] + (1 - val)*pFrustum[4];
val = (fWaterHeight - pFrustum[5].z)/(pFrustum[6].z - pFrustum[5].z);
pos[3] = val*pFrustum[6] + (1 - val)*pFrustum[5];
const K3DMatrix* pViewMatrix = viewport->GetViewMatrix();
const K3DMatrix* pProjMatrix = viewport->GetProjMatrix();
K3DMatrix mat;
mat = (*pViewMatrix) * (*pProjMatrix);
//K3DVector4 tpos4[ 4 ];
for( int i = 0; i < 4; i++ )
{
K3DVectorTransform( tpos[ i ], pos[ i ], mat );
//K3DVector4Transform( tpos4[ i ], pos[ i ], mat );
}
const float s_fRatio = 1.02f;
K3DVertex tempvtx[ 4 ];
tempvtx[ 0 ].x = -1.0f * s_fRatio; tempvtx[ 0 ].y = -1.0f * s_fRatio; tempvtx[ 0 ].z = tpos[ 0 ].z;
tempvtx[ 1 ].x = 1.0f * s_fRatio; tempvtx[ 1 ].y = -1.0f * s_fRatio; tempvtx[ 1 ].z = tpos[ 1 ].z;
tempvtx[ 2 ].x = 1.0f * s_fRatio; tempvtx[ 2 ].y = 1.0f * s_fRatio; tempvtx[ 2 ].z = tpos[ 2 ].z;
tempvtx[ 3 ].x = -1.0f * s_fRatio; tempvtx[ 3 ].y = 1.0f * s_fRatio; tempvtx[ 3 ].z = tpos[ 3 ].z;
//for( int i = 0; i < 4; i++ )
//{
// pWatervertex[ i ].p = tempvtx[ i ];
//}
const int c_numSegments = NUM_SEGMENTS;
float fX[ 2 ] = { tempvtx[ 0 ].x, tempvtx[ 1 ].x };
float fStartY = tempvtx[ 0 ].y;
float fIncY = ( tempvtx[ 3 ].y - tempvtx[ 0 ].y ) / ( float ) ( c_numSegments - 1 );
float fStartZ = tempvtx[ 0 ].z;
float fIncZ = ( tempvtx[ 3 ].z - tempvtx[ 0 ].z ) / ( float ) ( c_numSegments - 1 );
float w;
float unprojZ;
float nearZ = viewport->GetNearClip();
float farZ = viewport->GetFarClip();
K3DVertex resvtx;
float fog;
float distfog, heightfog, distfogstart, distfogend, heightfogstart, heightfogend;
DWORD fogmode;
KColor fogcolor;
dev->GetFogMode( fogmode, fogcolor, distfogstart, distfogend, heightfogstart, heightfogend );
heightfog = ( heightfogend - m_fWaterHeight ) / ( heightfogend - heightfogstart );
if( heightfog < 0.0f ) heightfog = 0.0f;
if( heightfog > 1.0f ) heightfog = 1.0f;
{
for( int i = 0; i < c_numSegments * 2; i++ )
{
resvtx.x = fX[ i % 2 ];
resvtx.y = fStartY + fIncY * ( float ) ( i / 2 );
resvtx.z = fStartZ + fIncZ * ( float ) ( i / 2 );
//if( resvtx.z > 1.0f ) w = farZ - w;
// 정확한 계산은 아니지만 포그는 제대로 나오므로 문제는 없다
if( resvtx.z <= 0.0f ) w = nearZ;
else if( resvtx.z >= 1.0f ) w = farZ;
else w = nearZ * farZ / ( resvtx.z * ( nearZ - farZ ) + farZ );
unprojZ = farZ * ( w - nearZ ) / (farZ - nearZ );
distfog = ( unprojZ - nearZ ) / ( farZ - nearZ );
if( distfog < 0.0f ) distfog = 0.0f;
if( distfog > 1.0f ) distfog = 1.0f;
fog = min( 1.0f - distfog * distfog, heightfog );
pWatervertex[ i ].p = K3DVector4( resvtx.x, resvtx.y, resvtx.z, fog );
}
}
//dev->SetTexture( 2, m_spTexBack );
//dev->DrawTriangleFan( VERTEX_H_WATER, pWatervertex, 4, sizeof(K3DVERTEX_H_WATER) );
//dev->DrawTriangleFan_VS( VERTEX_H_WATER, pWatervertex, 4, sizeof(K3DVERTEX_H_WATER) );
dev->DrawTriangleStrip_VS( VERTEX_H_WATER, pWatervertex, c_numSegments * 2, sizeof(K3DVERTEX_H_WATER) );
//// 폴리곤 짤라서 렌더링하다가 uv 삐꾸난 거.. 그냥 버릴려 했으나 나중에 쓸 일이 있을지 몰라 봉인만 한다..
//viewport->SetHQWaterHeight( m_fWaterHeight );
//K3DVERTEX_H_WATER* pWatervertex = (K3DVERTEX_H_WATER*)m_pVertex;
//K3DVertex* pFrustum = viewport->GetFrustum();
//K3DVertex campos = viewport->GetCameraPos();
//K3DVertex cpos1[ 2 ], cpos2[ 2 ];
//K3DVector pos[ 4 ], tpos[ 4 ];
//float val1, val2;
//float refu[ 4 ] = { 1.0f, 0.0f, 0.0f, 1.0f };
//float refv[ 4 ] = { 1.0f, 1.0f, 0.0f, 0.0f };
//float bumpu[ 4 ] = { 1.0f, 1.0f, 0.0f, 0.0f };
//float bumpv[ 4 ] = { 0.0f, 1.0f, 1.0f, 0.0f };
//float uvratio;
//K3DVector vTrans;
//K3DMatrixGetPosVector( vTrans, m_RootMat );
//float fWaterHeight = m_fWaterHeight + vTrans.z;
//if( fWaterHeight <= campos.z )
//{
// val1 = ( fWaterHeight - pFrustum[ 0 ].z ) / ( pFrustum[ 3 ].z - pFrustum[ 0 ].z );
// cpos1[ 0 ] = val1 * pFrustum[ 3 ] + ( 1 - val1 ) * pFrustum[ 0 ];
// cpos1[ 1 ] = val1 * pFrustum[ 2 ] + ( 1 - val1 ) * pFrustum[ 1 ];
// val2 = ( fWaterHeight - pFrustum[ 0 ].z ) / ( pFrustum[ 5 ].z - pFrustum[ 0 ].z );
// cpos2[ 0 ] = val2 * pFrustum[ 5 ] + ( 1 - val2 ) * pFrustum[ 0 ];
// cpos2[ 1 ] = val2 * pFrustum[ 4 ] + ( 1 - val2 ) * pFrustum[ 1 ];
// if( val1 >= 0.0f && val1 <= 1.0f )
// {
// pos[ 0 ] = cpos1[ 0 ];
// pos[ 1 ] = cpos1[ 1 ];
// }
// else
// {
// if( val2 >= 0.0f && val2 <= 1.0f )
// {
// pos[ 0 ] = cpos2[ 0 ];
// pos[ 1 ] = cpos2[ 1 ];
// uvratio = Magnitude( cpos2[ 0 ] - campos ) / Magnitude( cpos1[ 0 ] - campos );
// refv[ 0 ] = ( refv[ 0 ] - 0.5f ) * uvratio + 0.5f;
// refv[ 1 ] = ( refv[ 1 ] - 0.5f ) * uvratio + 0.5f;
// bumpu[ 0 ] = ( bumpu[ 0 ] - 0.5f ) * uvratio + 0.5f;
// bumpu[ 1 ] = ( bumpu[ 1 ] - 0.5f ) * uvratio + 0.5f;
// }
// else
// {
// return;
// }
// }
// val1 = ( fWaterHeight - pFrustum[ 4 ].z ) / ( pFrustum[ 7 ].z - pFrustum[ 4 ].z );
// cpos1[ 0 ] = val1 * pFrustum[ 7 ] + ( 1 - val1 ) * pFrustum[ 4 ];
// cpos1[ 1 ] = val1 * pFrustum[ 6 ] + ( 1 - val1 ) * pFrustum[ 5 ];
// val2 = ( fWaterHeight - pFrustum[ 2 ].z ) / ( pFrustum[ 7 ].z - pFrustum[ 2 ].z );
// cpos2[ 0 ] = val2 * pFrustum[ 7 ] + ( 1 - val2 ) * pFrustum[ 2 ];
// cpos2[ 1 ] = val2 * pFrustum[ 6 ] + ( 1 - val2 ) * pFrustum[ 3 ];
// if( val1 >= 0.0f && val1 <= 1.0f )
// {
// pos[ 2 ] = cpos1[ 0 ];
// pos[ 3 ] = cpos1[ 1 ];
// }
// else
// {
// if( val2 >= 0.0f && val2 <= 1.0f )
// {
// pos[ 2 ] = cpos2[ 0 ];
// pos[ 3 ] = cpos2[ 1 ];
// uvratio = Magnitude( cpos2[ 0 ] - campos ) / Magnitude( cpos1[ 0 ] - campos );
//
// refv[ 2 ] = ( refv[ 2 ] - 0.5f ) * uvratio + 0.5f;
// refv[ 3 ] = ( refv[ 3 ] - 0.5f ) * uvratio + 0.5f;
// bumpu[ 2 ] = ( bumpu[ 2 ] - 0.5f ) * uvratio + 0.5f;
// bumpu[ 3 ] = ( bumpu[ 3 ] - 0.5f ) * uvratio + 0.5f;
// }
// else
// {
// return;
// }
// }
//}
//else
//{
// val1 = ( fWaterHeight - pFrustum[ 5 ].z ) / ( pFrustum[ 6 ].z - pFrustum[ 5 ].z );
// cpos1[ 0 ] = val1 * pFrustum[ 6 ] + ( 1 - val1 ) * pFrustum[ 5 ];
// cpos1[ 1 ] = val1 * pFrustum[ 7 ] + ( 1 - val1 ) * pFrustum[ 4 ];
// val2 = ( fWaterHeight - pFrustum[ 0 ].z ) / ( pFrustum[ 5 ].z - pFrustum[ 0 ].z );
// cpos2[ 0 ] = val2 * pFrustum[ 5 ] + ( 1 - val2 ) * pFrustum[ 0 ];
// cpos2[ 1 ] = val2 * pFrustum[ 4 ] + ( 1 - val2 ) * pFrustum[ 1 ];
// if( val1 >= 0.0f && val1 <= 1.0f )
// {
// pos[ 0 ] = cpos1[ 0 ];
// pos[ 1 ] = cpos1[ 1 ];
// }
// else
// {
// if( val2 >= 0.0f && val2 <= 1.0f )
// {
// pos[ 0 ] = cpos2[ 0 ];
// pos[ 1 ] = cpos2[ 1 ];
// uvratio = Magnitude( cpos2[ 0 ] - campos ) / Magnitude( cpos1[ 0 ] - campos );
// refv[ 0 ] = ( refv[ 0 ] - 0.5f ) * uvratio + 0.5f;
// refv[ 1 ] = ( refv[ 1 ] - 0.5f ) * uvratio + 0.5f;
// bumpu[ 0 ] = ( bumpu[ 0 ] - 0.5f ) * uvratio + 0.5f;
// bumpu[ 1 ] = ( bumpu[ 1 ] - 0.5f ) * uvratio + 0.5f;
// }
// else
// {
// return;
// }
// }
//
// val1 = ( fWaterHeight - pFrustum[ 1 ].z ) / ( pFrustum[ 2 ].z - pFrustum[ 1 ].z );
// cpos1[ 0 ] = val1 * pFrustum[ 2 ] + ( 1 - val1 ) * pFrustum[ 1 ];
// cpos1[ 1 ] = val1 * pFrustum[ 3 ] + ( 1 - val1 ) * pFrustum[ 0 ];
// val2 = ( fWaterHeight - pFrustum[ 2 ].z ) / ( pFrustum[ 7 ].z - pFrustum[ 2 ].z );
// cpos2[ 0 ] = val2 * pFrustum[ 7 ] + ( 1 - val2 ) * pFrustum[ 2 ];
// cpos2[ 1 ] = val2 * pFrustum[ 6 ] + ( 1 - val2 ) * pFrustum[ 3 ];
// if( val1 >= 0.0f && val1 <= 1.0f )
// {
// pos[ 2 ] = cpos1[ 0 ];
// pos[ 3 ] = cpos1[ 1 ];
// }
// else
// {
// if( val2 >= 0.0f && val2 <= 1.0f )
// {
// pos[ 2 ] = cpos2[ 0 ];
// pos[ 3 ] = cpos2[ 1 ];
// uvratio = Magnitude( cpos2[ 0 ] - campos ) / Magnitude( cpos1[ 0 ] - campos );
//
// refv[ 2 ] = ( refv[ 2 ] - 0.5f ) * uvratio + 0.5f;
// refv[ 3 ] = ( refv[ 3 ] - 0.5f ) * uvratio + 0.5f;
// bumpu[ 2 ] = ( bumpu[ 2 ] - 0.5f ) * uvratio + 0.5f;
// bumpu[ 3 ] = ( bumpu[ 3 ] - 0.5f ) * uvratio + 0.5f;
// }
// else
// {
// return;
// }
// }
//}
//const K3DMatrix* pViewMatrix = viewport->GetViewMatrix();
//const K3DMatrix* pProjMatrix = viewport->GetProjMatrix();
//K3DMatrix mat;
//mat = (*pViewMatrix) * (*pProjMatrix);
//K3DVector4 tpos4[ 4 ];
//K3DVertex vpos[ 4 ];
//for( int i = 0; i < 4; i++ )
//{
// K3DVectorTransform( &tpos[ i ], &pos[ i ], &mat );
//
// K3DVector4Transform( &tpos4[ i ], &pos[ i ], &mat );
// K3DVectorTransform( &vpos[ i ], &pos[ i ], pViewMatrix );
//}
//for( int i = 0; i < 4; i++ )
//{
// //pWatervertex[ i ].p = tpos[ i ];
// pWatervertex[ i ].p = pos[ i ];
// //pWatervertex[ i ].tu = bumpu[ i ];
// //pWatervertex[ i ].tv = bumpv[ i ];
// //pWatervertex[ i ].tu2 = refu[ i ];
// //pWatervertex[ i ].tv2 = refv[ i ];
//}
////dev->SetTexture( 2, m_spTexBack );
//
//dev->DrawTriangleFan_VS( VERTEX_H_WATER, pWatervertex, 4, sizeof(K3DVERTEX_H_WATER) );
}
};
#ifdef CLOUD_LUA
enum ENUM_CLOUD_COLOR
{
C_BRIGHT = 0,
C_GRAY,
C_DARK,
C_MAX
};
extern float g_fRate;
extern float g_fRateG;
extern float g_fRateScale;
extern float g_fTestZ;
extern float g_fTestX;
extern float g_fTestY;
extern float g_fTestG;
extern bool g_bUseWorldTM;
extern float g_fZ;
extern float g_fX;
extern float g_fY;
class SCloudLumpPrimitive : public K3DPrimitive
{
public:
SCloudLumpPrimitive()
: K3DPrimitive()
{
for(int x=C_BRIGHT; x<C_MAX; x++)
{
m_nVtxCnt [x] = 0;
m_pVB [x] = NULL;
m_pIB [x] = NULL;
m_spTexBack[x] = NULL;
// m_pVertex [x] = NULL;
// m_pIndexed [x] = NULL;
}
m_pMtl = NULL;
}
virtual ~SCloudLumpPrimitive()
{
ClearVertexBuffer();
ClearIndexBuffer();
}
void ClearVertexBuffer()
{
for(int x=C_BRIGHT; x<C_MAX; x++)
{
if( m_pVB[x] )
m_pVB[x]->Release();
}
}
void ClearIndexBuffer()
{
for(int x=C_BRIGHT; x<C_MAX; x++)
{
if( m_pIB[x] )
m_pIB[x]->Release();
}
}
void SetVertexCnt( int nColorType, int nVtxCnt )
{
if(nColorType < C_BRIGHT || nColorType >= C_MAX)
return ;
m_nVtxCnt[ nColorType ] = nVtxCnt;
}
int GetVertexCnt( int nColorType ) const
{
if(nColorType < C_BRIGHT || nColorType >= C_MAX)
return 0;
return m_nVtxCnt[ nColorType ];
}
K3DVertexBuffer* GetVertexBuffer( int nColorType )
{
if(nColorType < C_BRIGHT || nColorType >= C_MAX)
return 0;
return m_pVB[ nColorType ];
}
K3DIndexBuffer* GetIndexBuffer( int nColorType )
{
if(nColorType < C_BRIGHT || nColorType >= C_MAX)
return NULL;
return m_pIB[ nColorType ];
}
//void SetMaterial( int nColorType, K3DMaterial *mtl )
//{
// if(nColorType < C_BRIGHT || nColorType >= C_MAX)
// return 0;
// m_pMtl[ nColorType ] = mtl;
//}
void SetIndexBuffer( int nColorType, K3DIndexBuffer *buf )
{
if(nColorType < C_BRIGHT || nColorType >= C_MAX || buf == NULL)
return ;
m_pIB[ nColorType ] = buf;
}
void SetVertexBuffer( int nColorType, K3DVertexBuffer *buf )
{
if(nColorType < C_BRIGHT || nColorType >= C_MAX || buf == NULL )
return ;
m_pVB[ nColorType ] = buf;
if( m_pVB[ nColorType ] )
m_pVB[ nColorType ]->AddRef();
}
void SetTexture( int nColorType, K3DTexture *tex )
{
if(nColorType < C_BRIGHT || nColorType >= C_MAX)
return ;
m_spTexBack[ nColorType ] = tex;
}
virtual void Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum = true )
{
if( m_pTransform )
{
// K3DVector vPos(m_pTransform->_41, m_pTransform->_42, m_pTransform->_43);
// K3DMatrixScaling(*m_pTransform, g_fRateScale, g_fRateScale, g_fRateScale );
// m_pTransform->_41 = vPos.x / (g_fRate * g_fRateG);
// m_pTransform->_42 = vPos.y / (g_fRate * g_fRateG);
// m_pTransform->_43 = vPos.z / (g_fRate * g_fRateG);
// m_pTransform->_41 = vPos.x;
// m_pTransform->_42 = vPos.y;
// m_pTransform->_43 = vPos.z;
dev->SetTransform( K3DRenderDevice::TS_WORLD, m_pTransform );
}
for(int x=C_BRIGHT; x<C_MAX; x++)
// for(int x=C_DARK; x>C_BRIGHT; x--)
{
if( m_pVB[x] == NULL || m_pIB[x] == NULL || m_nVtxCnt[x] == 0 )
continue ;
dev->SetTexture( 0, m_spTexBack[x] );
// dev->DrawTriangleStripVB_VS( m_pVB[x], m_nVtxCnt[x] );
dev->DrawIndexedTriangleVB_VS( m_pVB[x], m_pIB[x], m_nVtxCnt[x] );
}
if( m_pTransform )
{
K3DMatrix mat;
K3DMatrixIdentity( mat ); // 구름 위치
dev->SetTransform( K3DRenderDevice::TS_WORLD, &mat );
}
}
void SetMaterial( K3DMaterial* pMtl )
{
m_pMtl = pMtl;
}
protected:
K3DVertexBuffer* m_pVB[C_MAX];
K3DIndexBuffer* m_pIB[C_MAX];
K3DTextureSPtr m_spTexBack[C_MAX];
int m_nVtxCnt[C_MAX];
K3DMaterial* m_pMtl;
// void* m_pVertex[C_MAX];
// void* m_pIndexed[C_MAX];
};
#endif