본문 바로가기
DirectX11/정보정리

[DirectX11] 정점 버퍼와 색인 버퍼

by 마두식 2022. 11. 7.
반응형

※  아래의 내용들은 DirectX 11을 이용한 3D 게임 프로그래밍 입문 책의 내용을 바탕으로 작성된 것입니다.

 

정점 및 정점 버퍼

-  원하는 자료(특성)를 가진 커스텀 정점 형식을 만들려면 우선 그러한 자료를 담을 수 있는 구조체를 정의해야 한다.

-  정점 구조체를 정의했다면, 해당 구조체의 각 성분(필드)이 어떤 용도인지 Direct3D에게 알려 주어야 한다.

=>  ID3D11InputLayer 형식의 입력 배치(input layer) 객체를 이용한다.
=>  입력 배치 객체는 D3D11_INPUT_ELEMENT_DESC 구조체들로 이루어진 배열을 통해서 구축한다.
=>  D3D11_INPUT_ELEMENT_DESC 배열을 이제부터 입력 배치 서술(input layer description) 배열이라고 부른다.
※  D3D11_INPUT_ELEMENT_DESC 구조체의 정의 책 211p


-  입력 배치 서술 배열을 완성했으며 입력 배치를 위한 ID3DInputLayout 인터페이스를 얻었다면, 이제 ID3D11Device::CreateInputLayout 메서드를 호출해서 입력 배치를 생성한다.

-  이렇게 생성한 입력 배치는 아직 장치에 묶이지 않은 상태이므로 입력 배치를 사용하고자 하는 장치에 묶어준다

-  GPU가 정점 배열에 접근하려면 배열의 정점들을 버퍼(Buffer)라고 부르는 특별한 자원에 담아 두어야 한다.

=>  D3D 코드에서 버퍼는 ID3D11Buffer 인터페이스로 대표된다.
=>  정점들을 담는 버퍼를 정점 버퍼라고 부른다.


-  Direct3D의 버퍼들은 자료를 담을 뿐만 아니라, CPU나 GPU가 자료에 어떻게 접근할 수 있고 버퍼가 파이프라인의 어디에 묶이는지에 대한 정보도 가진다.

-  정점 버퍼 생성 과정

1.  생성할 버퍼를 서술하는 D3D11_BUFFER_DESC 구조체를 채운다.
2.  버퍼 초기화에 사용할 자료를 서술하는 D3D11_SUBRESOURCE_DATA 구조체를 채운다.
3.  ID3D11Device::CreateBuffer를 호출해서 버퍼를 생성한다.


-  CPU가 자원을 기록하는 것은 읽는 것보다 빠르지만, 자료를 다시 비디오 메모리로 전송해야 하므로 여전히 추가 부담이 생긴다.

(왜 기록하는 것보다 읽는게 더 느린지 생각해보자)


-  생성된 버퍼의 정점들을 실제로 파이프라인에 공급하려면, 버퍼를 장치의 한 입력 슬롯에 붙여야(묶어야) 한다.

=>  ID3D11DeviceContext::IASetVertexBuffers(); 함수 이용

 

 

색인 및 색인 버퍼

-  색인 역시 GPU가 접근할 수 있는 특별한 자원에 넣어야 한다.

=>  해당 자원을 색인 버퍼라고 부른다.
=>  색인 버퍼의 생성은 정점 버퍼의 생성과 거의 비슷하다. (정점 대신 색인을 담는다)


-  다른 Direct3D 자원들과 마찬가지로 색인 버퍼를 사용하려면 먼저 색인버퍼를 파이프라인에 묶어야 한다.

=>  ID3D11DeviceContext::IASetIndexBuffers(); 함수 이용


-  색인 버퍼를 이용해서 기본 도형을 그릴 때에는 Draw 메서드 대신 DrawIndexed 메서드를 사용해야 한다.

-  도형 3개에 대한 각각의 정점 버퍼와 색인 버퍼가 있다고 할 때, 이것을 하나의 정점 버퍼와 색인 버퍼로 합칠 수 있다.(224p)(6장 예제 'Shapes' 에서 사용되는 기법)

=>  물체의 기준 정점 위치(base vertex location)
=>  일반적으로(버퍼들을 차례로 연결해서 합친 경우) 한 물체의 새 색인들은 그 기준 정점 위치를 각 색인에 더한 것이다.
=>  색인 갱신 작업을 CPU에서 직접 수행할 필요는 없다.
==>  DrawIndexed의 셋째 매개변수로 기준 정점 위치를 지정하면 Direct3D가 수행해준다.
=>  이렇게 하면 정점 버퍼들과 색인 버퍼들을 변경할 때 발생하는 API 상의 추가부담을 피할 수 있다.
=>  이러한 부담은 병목이 되는 수준은 아니므로 쉽게 합칠 수 있는 작은 정점, 색인 버퍼들이 많은 경우에, 성능을 위해 해당 버퍼들을 병합해볼 만하다.)



-  색인 버퍼를 생성할 때 삼각형의 생성 순서가 중요하다.

=>  D3D는 왼손잡이 좌표계를 사용한다. 따라서 삼각형을 생성하는 방향에 주의해야 한다.(검색 키워드 : 외적 방향, 왼손잡이 좌표계)
=>  현재까지는 도형을 그릴 때, 삼각형을 이어주는 방향은 생각하지 않아도 되는 것 같다.
ex: 사각형을 그린다고 했을 때, 사각형의 꼭짓점을 각각 왼쪽 아래 방향부터 시계방향으로 0, 1, 2, 3 으로 정한다고 가정하자.
사각형을 그리기 위해 삼각형 2개가 필요하며, 왼손잡이 좌표계에 기반해서 삼각형의 법선이 바깥쪽으로 나오도록 그려야 한다 => [0, 1, 2] [0, 2, 3]
여기서 두 삼각형간의 연결은 신경 쓸 필요가 없다. 삼각형 생성 방향만 신경써주면 된다
즉, [1, 2, 3][0, 1, 3], [2, 3, 0][1, 2, 0] 등등 어떠한 방식으로든 삼각형만 제대로 생성해주면 된다.
※  현재까지 공부한걸론 이렇지만 뒷부분 공부하면서 달라질 수 있는 내용임. 너무 확신하진 말자.

 

 

 

 


 

 

 

틀린 부분이나 이상한 부분이 있으면 댓글로 편하게 지적해주세요.

감사합니다!

반응형

'DirectX11 > 정보정리' 카테고리의 다른 글

[DirectX11] 조명  (0) 2022.11.23
[DirectX11] 효과 프레임워크  (0) 2022.11.08
[DirectX11] 렌더링 파이프라인(2)  (0) 2022.11.05
[DirectX11] 렌더링 파이프라인(1)  (0) 2022.11.03
[DirectX11] 색상  (0) 2022.11.03

댓글