Files
Leviathan/Client/Game/engine/TerrainEngine/TerrainPrimitiveForSingleTile.h
2026-06-01 12:46:52 +02:00

145 lines
4.1 KiB
C++

#pragma once
#include "TerrainPrimitive.h"
class CTerrainPrimitiveForSingleTile : public CTerrainPrimitive
{
public:
CTerrainPrimitiveForSingleTile( float fTileLength, int nVertexCount, const K3DIndexBuffer* pCommonIndexBuffer, WORD wTile, CTerrainTextureInfo* pTextureInfo, const CTerrainInfo* pTerrainInfo, K3DRenderDevice* pDev, bool& rResult )
: CTerrainPrimitive( nVertexCount, pCommonIndexBuffer, pTerrainInfo )
, m_fTileLength( fTileLength )
{
if( !pTextureInfo->IsValidTexture( wTile ) ) { rResult = false; return; }
float fTexDetail = pTextureInfo->GetTextureDetailRatio( wTile );
m_spTexture = pTextureInfo->GetTexture( wTile );
K3DMatrixScaling(
&m_matScale,
1.f / ( m_fTileLength * fTexDetail ),
1.f / ( m_fTileLength * fTexDetail ),
0.f );
// 버텍스 버퍼 생성
int nTotalVertexCount = (m_nVertexCount * m_nVertexCount);
m_spVB = pDev->CreateVertexBuffer( K3DFVF_TERRAIN, nTotalVertexCount );
if( m_spVB == NULL || !m_spVB->IsValidVtx() ) { rResult = false; return; }
// transform 이동 좌표
m_vtWorldTransform = pTerrainInfo->GetVertex( 0, 0 );
m_vtWorldTransform.z = 0.f;
// 버텍스 버퍼 Lock
K3DTERRAINVERTEX* pVertices;
int nSize;
m_spVB->Lock( (void**)&pVertices, nSize );
if( !pVertices ) { rResult = false; return; }
for( int nY = 0; nY < m_nVertexCount; ++nY )
{
for( int nX = 0; nX < m_nVertexCount; ++nX )
{
pVertices->pos = K3DVertex( float(nX) * m_fTileLength, float(nY) * m_fTileLength, pTerrainInfo->GetHeight( nX, nY ) );
pVertices->normal = pTerrainInfo->GetVertexNormalVector( nX, nY );
pVertices->diffuse = KColor( pTerrainInfo->GetColor( nX, nY ) );
pVertices++;
}
}
m_spVB->Unlock();
rResult = true;
}
virtual ~CTerrainPrimitiveForSingleTile()
{
}
void Render( KViewportObject* viewport, K3DRenderDevice* dev )
{
if( NULL != m_spVB )
{
K3DMatrix matWorldTransform;
K3DMatrixIdentity( matWorldTransform );
K3DVector vtPos = m_vtWorldTransform;
if( NULL != m_pOriginCorrection ) vtPos -= *m_pOriginCorrection;
K3DMatrixSetPosVector( matWorldTransform, vtPos );
// render state 설정
dev->SetRenderState( K3DRenderDevice::RS_TERRAIN_SINGLETILE );
dev->SetTransform( K3DRenderDevice::TS_WORLD, matWorldTransform );
K3DMatrix matTexture;
K3DMatrixMultiply( &matTexture, viewport->GetInverseViewMatrix(), &m_matScale );
// 텍스쳐 몇 텍스쳐 변환 행렬 설정
dev->SetTransform( K3DRenderDevice::TS_TEXTURE0, matTexture );
dev->SetTexture( 0, m_spTexture );
// 그리기
dev->DrawIndexedTriangleVB( m_spVB, m_spCommonIndexBuffer );
// 텍스쳐 및 텍스쳐 변환 행렬 환원
dev->SetTexture( 0, NULL );
dev->SetTransformIdentity( K3DRenderDevice::TS_TEXTURE0 );
}
}
bool RefreshHeight( const CTerrainInfo* pTerrainInfo, K3DRenderDevice* pDev )
{
// 버텍스 버퍼 Lock
K3DTERRAINVERTEX* pVertices;
int nSize;
m_spVB->Lock( (void**)&pVertices, nSize );
if( !pVertices ) return false;
for( int nY = 0; nY < m_nVertexCount; ++nY )
{
for( int nX = 0; nX < m_nVertexCount; ++nX )
{
// 높이값과 normal vector값 변경
pVertices->pos = K3DVertex( float(nX) * m_fTileLength, float(nY) * m_fTileLength, pTerrainInfo->GetHeight( nX, nY ) );
pVertices->normal = pTerrainInfo->GetVertexNormalVector( nX, nY );
pVertices++;
}
}
m_spVB->Unlock();
return true;
}
bool RefreshTile( const CTerrainInfo* pTerrainInfo, K3DRenderDevice* pDev )
{ return true; } // 이 프리미티브는 타일 설정이 불가.
bool RefreshColor( const CTerrainInfo* pTerrainInfo, K3DRenderDevice* pDev )
{
// 버텍스 버퍼 Lock
K3DTERRAINVERTEX* pVertices;
int nSize;
m_spVB->Lock( (void**)&pVertices, nSize );
if( !pVertices ) return false;
for( int nY = 0; nY < m_nVertexCount; ++nY )
{
for( int nX = 0; nX < m_nVertexCount; ++nX )
{
// diffuse값 변경
pVertices->diffuse = KColor( pTerrainInfo->GetColor( nX, nY ) );
pVertices++;
}
}
m_spVB->Unlock();
return true;
}
protected:
float m_fTileLength;
K3DTextureSPtr m_spTexture;
K3DMatrix m_matScale;
};