'전체 글'에 해당되는 글 46건

  1. 2024.07.26 절두체 컬링 ( Frustum Culling )
  2. 2024.07.26 쿼드트리 ( QuadTree )
  3. 2024.07.26 높이맵 ( Heightmap )

 

* 절두체

- 사각뿔의 머리를 잘라놓은 형태로

근평면, 원평면, 좌평면, 우평면, 상평면, 하평면으로 구성되어있다.

 

* 절두체 컬링

- 대상이 카메라 시야 내에 포함되는지를 판별하여 출력 여부를 결정한다.

- quadTree자료구조로 생성된 지형에 절두체 컬링을 적용시 렌더링되는 삼각형의 수를 줄일 수 있다.

 

* 절두체 생성

1. 근평면, 원평면, 좌평면, 우평면, 상평면, 하평면을 생성한다.

2. 카메라 시야를 기준으로 잡으므로

IDirect3DDevice9의 멤버함수 GetTransform을 이용해 view행렬와 projection행렬을 얻는다.

3.위에 생성한 1.의 각 정점에 view * proj의 역행렬을 곱해준다.

invMat = D3DXMatrixInverse achieve view * proj

transPos = D3DXVec3TransformCoord achieve origV, invMat

( invMat = 카메라의 world행렬이 된다. )

4. 각 평면을 구성하는 transPos정점들을 이용해 D3DXPLANE을 생성한다.

( 본 블로그의 direct3dx->학습->평면방정식 참고 )

http://blog.naver.com/krlaghgn/220711303047

평면방정식

*평면방정식-평면의 법선벡터와 원점간의 거리d를 알고있을때 점P가 평면에 대해 어느 위치에 있는지 판별...

blog.naver.com

 

* D3DXVec3TransformCoord

D3DXVECTOR3와 D3DXMATRIX구조체의 포인터를 인자로 받아

벡터를 1x4 행렬로 변환하여 행렬곱 연산을 마친 후 D3DXVECTOR3로

변환하여 반환한다. 1x4행렬로 변환과정에서 벡터의 w의 값은 1로 고정되며

행렬 위치값의 영향을 받는다.

 

* 절두체 컬링 적용

1. quadTree의 각 노드가 가지고있는 정점들과 절두체컬링을 위해 생성한 D3DXPLANE을

평면방정식의 연산으로 사용하여 절두체 내에 포함되는 여부를 판단하여

포함 여부를 저장한다.

2.지형의 인덱스를 생성할때 cullMode가 적용된 노드라면 자신을 포함해 하위노드도 그려줄 필요가 없으므로

하위노드 탐색과, 인덱스 생성을 건너뛴다.

 

'programming > etc' 카테고리의 다른 글

지형 높이 조절( terrain height control )  (1) 2024.07.26
Level of detail ( LOD )  (0) 2024.07.26
쿼드트리 ( QuadTree )  (0) 2024.07.26
OBB 충돌  (0) 2024.07.26
*좌표계*삼각비*내적-정사영  (0) 2024.07.26
Posted by mainep
:

 

*QuadTree

- 부모의 노드가 4개의 자식 노드를 가진다.

- terrain의 경우 index를 정보로 가진다.

- 1. 전체를 표현할 수 있는 4개의 index를 가진 root노드로 부터 자식 노드가 파생된다.

2. 자신을 4분할 하여 각각의 노드들이 자신의 index를 가진다.

3. 더이상 분할 할 수 없을 때 까지 2.를 재귀적으로 반복한다.

 

 

 

root노드로부터 4개의 자식노드가 파생되어 그 4개의 자식노드들도 각각 4개씩의 자식을 갖는다.

( 더이상 나눌 수 없을 때 까지 )

 

 

 

*terrain에 quadtree만 적용시 속도적 측면에서 오히려 손해를 본다.

quadtree를 활용하려면 FrustumCulling과 함께 사용하자.

 

*의사코드

class CTerQuadTree;

 

private:

//자식노드 멤버변수

CTerQuadTree* m_ar_pChild[4];

//index를 저장할 멤버변수

DWORD m_ar_dwCorner[4];

 

//root 생성 메소드

VOID CTerQuadTree::CreateQuadTree( int _iWidth, int _iHeight )

{

//root index 생성

DWORD ar_dwIndex[4] =

{

0,

_iWidth- 1,

_iWidth* ( _iHeight - 1 ),

_iWidth* _iHeight - 1

};

 

//m_ar_dwCorner배열에 index 저장

CTerQuadTree::_SetupIndex( ar_dwIndex[0], ar_dwIndex[1], ar_dwIndex[2], ar_dwIndex[3] );

 

//quadtree 생성

CTerQuadTree::_Build();

}

 

//build를 재귀호출하여 자식노드를 할당한다.

VOID CTerQuadTree::_Build()

{

//나눌 수 있다면 자식노드 build

if( CTerQuadTree::_SubDivide() )

{

for( int i = 0; i < 4; ++i )

m_ar_pChild[i]->_Build();

}

}

 

//더 나눌 수 있는지 검토한 후 index를 생성할수있는 데이터를 인자로 넘겨주며 자식 노드를 생성한다.

BOOL CTerQuadTree::_SubDivide()

{

if( ! CTerQuadTree::_IsDivisible() )

return FALSE;

 

DWORD dwTopCen, dwBotCen, dwLefCen, dwRigCen;

 

dwTopCen = ( m_ar_dwCorner[COR_TR] + m_ar_dwCorner[COR_TL] ) / 2;

dwBotCen = ( m_ar_dwCorner[COR_BR] + m_ar_dwCorner[COR_BL] ) / 2;

dwLefCen = ( m_ar_dwCorner[COR_TL] + m_ar_dwCorner[COR_BL] ) / 2;

dwRigCen = ( m_ar_dwCorner[COR_TR] + m_ar_dwCorner[COR_BR] ) / 2;

 

m_ar_pChild[COR_TL] = CTerQuadTree::_CreateChild( m_ar_dwCorner[COR_TL], dwTopCen, dwLefCen, m_dwCenter );

m_ar_pChild[COR_TR] = CTerQuadTree::_CreateChild( dwTopCen, m_ar_dwCorner[COR_TR], m_dwCenter, dwRigCen );

m_ar_pChild[COR_BL] = CTerQuadTree::_CreateChild( dwLefCen, m_dwCenter, m_ar_dwCorner[COR_BL], dwBotCen );

m_ar_pChild[COR_BR] = CTerQuadTree::_CreateChild( m_dwCenter, dwRigCen, dwBotCen, m_ar_dwCorner[COR_BR] );

 

 

return TRUE;

}

 

'programming > etc' 카테고리의 다른 글

Level of detail ( LOD )  (0) 2024.07.26
절두체 컬링 ( Frustum Culling )  (0) 2024.07.26
OBB 충돌  (0) 2024.07.26
*좌표계*삼각비*내적-정사영  (0) 2024.07.26
카메라  (0) 2024.07.26
Posted by mainep
:

 

*Heightmap

- texture를 읽어와 texture의 크기 만큼 지형의 크기를 잡아주고

해당 픽셀의 음영값을 vertex의 높낮이로 정해준해준다.

 

*D3DCreateTextureFromFileEx()

- Heightmap texture를 LPDIRECT3DTEXTURE9 com객체에 메모리를 할당하여 texture 정보를 읽어온다.

 

*D3DSURFACE_DESC 구조체

- LPDIRECT3DTEXTURE9의 GetLevelDesc() 함수를 이용하여

D3DSURFACE_DESC구조체에 texture정보를 추출한다.

- texture의 width와 height는 2^n의 수로 변환되며

본래 texture의 크기가 2^n보다 클경우 log_2( size ) = k, 2^(k+1)로 변환한다.

 

*D3DLOCKED_RECT 구조체

- texture에 lock을 걸어 pixel정보에 접근할 수 있게 한다.

- .pBits : pixel정보를 가지고있는 포인터로 첫 주소를 가리킨다.

- .Pitch : 한 열의 길이

 

*의사 코드

LPDIRECT3DTEXTURE9 pTex = NULL;

 

D3DCreateTextureFromFileEx( pDevice, pszPath, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0

, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pTex );

 

D3DSURFACE_DESC ddsd;

pTex->GetLevelDesc( 0, &ddsd );

POINT ptSize;

 

ptSize.x = ddsd.Width;

ptSize.y = ddsd.Height;

 

D3DLOCKED_RECT ddlr;

pTex->LockRect( 0, &ddlr, NULL, D3DLOCK_READONLY );

 

DWORD dwRowPixelSize = ddlr.Pitch / 4;

 

//반복문을 사용하여 픽셀의 포인터를 갱신한다.

for( int iZ = 0; iZ < ptSize.z; ++iZ )

{

for( int iX = 0; iX < ptSize.x; ++iX )

{

//해당 픽셀의 주소 계산

DWORD dwPixel = *( (LPDWORD)ddlr.pBits + iX + iZ * dwRowPixelSize );

 

//필요정보는 픽셀의 색상이 아니라 음영값이므로

//0x000000ff와 비트& 연산을 하여 한 byte값(blue value)을 구한다.

float fHeight = (float)( dwPixel & 0x000000ff );

}

}

 

pTex->UnlockRect( 0 );

 

pTex->Release();

 

'programming > direct3d' 카테고리의 다른 글

picking  (0) 2024.07.26
directx terrain 약 2주간 업데이트 사항  (0) 2024.07.26
dirextx xFile 띄우기  (0) 2024.07.26
directx 지형 알파 멀티텍스쳐의 복수 사용  (0) 2024.07.26
directx 지형 알파 텍스쳐 입히기  (0) 2024.07.26
Posted by mainep
: