2. Direct3D 정점
Direct3D는 유연한 정점 포맷이라고 해서 프로그래머가 정점의 최적 정보만을 가질 수 있도록 그 형식을 설정할 수 있습니다.
1) 1단계 : float x, y, z 좌표값
2) 2단계 : float rhw (이미 변환된 정점에만 사용)
3) 3단계 : 블랜딩 값
4) 4단계 : 정점 법선
5) 5단계 : 정점 포인트의 크기
6) 6단계 : diffuse 값
7) 7단계 : specular 색
8) 1~8까지 텍스쳐 좌표쌍(u, v float 값)
멤버 변수의 순서가 바뀌면 렌더링이 않되므로 순서를 지켜서 정의해야 합니다.
정점의 구조체가 어떤 정보를 포함하는지에 대한 것은 아래의 값을 비트 OR연산하여 설정합니다.
D3DFVF_DIFFUSE, D3DFVF_NORMAL, D3DFVF_SPECULAR, D3DFVF_XYZ, D3DFVF_XYZRHW, D3DFVF_XYZW, D3DFVF_TEX0~ D3DFVF_TEX7
예시)x, y,z의 위치값과 정점의 색상을 한 개의 정점에 포함 시킨 것입니다.
struct CUSTOMVERTEX { FLOAT x,y,z; DWORD color; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
정점의 형식은 #define을 통해 정의한 D3DFVF_CUSTOMVERTEX으로 설정하게 됩니다.
*rhw의 설정은 현재의 정점을 2D좌표처럼 사용하는 것
다양한 사용예시 1)
struct CUSTOMVERTEX { D3DXVECTOR3 position; D3DXVECTOR3 normal; DWORD diffuse; float tu, tv; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL| D3DFVF_DIFFUSE | D3DFVF_TEX1)
다양한 사용예시 2)
struct CUSTOMVERTEX { FLOAT x,y,z, rhw; DWORD color; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
- 정점의 생성과 초기화
struct CUSTOMVERTEX { FLOAT x,y,z; DWORD color; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) CUSTOMVERTEX vertices[] = { {150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000,}, {250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00,}, { 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff,}, };
구조체에 맞춰 데이터를 설정하면 됩니다.
- 정점버퍼
출력할 정점을 저장하는 버퍼, 출력할 정점을 모두 정점 버퍼에 넣은 후 버퍼 안에 있는 정점을 한꺼번에 출력합니다.
1) 생성
HRESULT CreateVertexBuffer( [in] UINT Length, [in] DWORD Usage, [in] DWORD FVF, [in] D3DPOOL Pool, [out, retval] IDirect3DVertexBuffer9 **ppVertexBuffer, [in] HANDLE *pSharedHandle );
- Length : 정점 구조체의 크기 설정
- Usage : 항상 0으로 설정
- FVF : 정점 구조에 대한 값인 D3DFVF_CUSTOVERTEX가 설정
- Pool : 정점을 메모리에 생성하는 방법을 설정합니다. 기본값은 D3DPOOL_DEFAULT
정점 버퍼의 객체형은 LPDIRECT3DVERTEXBUFFER9이므로, 이 포인터 변수의 메모리 주소를 설정합니다.
pSharedHandle은 아직 사용하지 않으니 NULL을 입력
LPDIRECT3DVERTEXBUFFER9 m_pVB; m_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVB, NULL);
2) 정점을 정점 버퍼에 복사
- 정점 버퍼를 사용하기 위해서는 먼저 정점 버퍼의 메모리를 Lock()하여 독점합니다
- Lock()을 하게 되면 해당 메모리는 다른 자원에서 접근할 수 없으며 정점을 저장하기 위한 시작 메모리주소를 얻습니다.
- memcpy()를 통해 메모리 주소로 복사합니다.
- 끝난 후 UnLock()
VOID* pVertices; m_pVB->Lock(0, sizeof(vertices), (void**)&pVertices, 0); memcpy(pVertices, vertices, sizeof(vertices)); m_pVB->Unlock();
3) 렌더링
- 렌더링은 다음의 과정으로 진행됩니다.
m_pd3dDevice->SetStreamSource(0, m_pVB, 0, sizeof(CUSTOMVERTEX)); m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
-SetStreamSorce() : 정점 버퍼와 정점의 포맷을 d3d device에게 알려주는 함수
HRESULT SetStreamSource( [in] UINT StreamNumber, [in] IDirect3DVertexBuffer9 *pStreamData, [in] UINT OffsetInBytes, [in] UINT Stride );
- SetFVF : 정점 구조가 어떻게 되는지 device에 설정
HRESULT SetFVF( [in] DWORD FVF );
-DrawPrimitive : 정점 출력
HRESULT DrawPrimitive( [in] D3DPRIMITIVETYPE PrimitiveType, [in] UINT StartVertex, [in] UINT PrimitiveCount );
PrimitiveType은 다음과 같습니다.
-D3DPT_POINTLIST
-D3DPT_LINELIST
-D3DPT_LINESTRIP
-D3DPT_TRIANGLELIST
-D3DPT_TRIANGLESTRIP
-D3DPT_TRIANGLEFAN
4) 정점 버퍼와 Direct3D 해제
VOID CD3DApp::Cleanup() { if(pVB != NULL) pVB->Release(); if(m_pd3dDevice != NULL) m_pd3dDevice->Release(); if(m_pD3D != NULL) m_pD3D->Release(); }
'Software Development > Graphics' 카테고리의 다른 글
[Vulkan] LunarG Vulkan SDK 환경설정/샘플 빌드하기 - Windows (5) | 2016.03.13 |
---|---|
6. Matrices (0) | 2014.10.20 |
5. Vertices_1)Vector (0) | 2014.10.17 |
4. DirectX 프레임워크(framework) (0) | 2014.10.14 |
3. DirectX 기본환경 설정 (0) | 2014.10.14 |