프로그래밍/DirectX

Direct3D 그리기의 연산

이재만박사 2015. 8. 7. 16:14

렌더링 파이프 라인 구성,

정점 셰이더, 픽셀 셰이더를 정의

3차원 모형을 그리기 위해 기하구조를 렌더링 파이프라인에 제출하는데

필요한 Direct3D API의 여러 인터페이스와 메서드를 중점적으로 살펴본다

다양한 기하 도형을 색을 입혀서, 또는 와이어프레임 형태로 그릴 수 있다


이 글의 목표

1. 기하 자료의 정의와 저장, 그리기(drawing)를 위한 Direct3D 인터페이스와 메서드를 파악한다

2. 기본적인 정점, 픽셀 셰이더를 작성하는 방법을 배운다

3. 렌더 상태로 렌더링 파이프라인을 구성하는 방법을 파악한다

4. Direct3D 효과 프레임워크를 이용해서 논리적으로 연관된 셰이더들과

렌더 상태들을 하나의 렌더링 기법으로 묶는 방법과 효과 프레임워크를

일종의 '셰이더 생성기'로 사용하는 방법을 배운다.


* 정점과 입력 배치


- 정점은 공간적 위치 이외에 추가적인 자료를 가질 수 있다

- 원하는 자료를 가진 커스텀 정적 형식을 만들려면 우선 그러한 자료를 담을 구조체를 정의해야 한다

- 예를 들어 다음은 서로 다른 두 종류의 정점 형식을 보여준다

- 하나는 위치와 색상

- 하나는 위치, 법선, 텍스처 좌표로 구성


struct Vertex1

{

XMFLOAT3 Pos;

XMFLOAT4 Color;

};


struct Vertex2

{

    XMFLOAT3 Pos;

    XMFLOAT3 Normal;

    XMFLOAT2 Tex0;

    XMFLOAT2 Tex1;

};


정점 구조체를 정의했다면, 그 정점 구조체의 각 성분이 어떤 용도인지를 Direct3D에게 알려주어야 한다. 이 정보를 알려주는 수단이 바로 ID3D11InputLayout 형식의 입력 배치(input layout) 객체이다.

이 입력 배치 객체는 D3D11_INPUT_ELEMENT_DESC 구조체들로 이루어진 배열을 통해서 구축한다. 이 D3D11_INPUT_ELEMENT_DESC 배열의 각 원소는 정점 구조체의 각 성분을 서술하는 역할을 한다. 예를 들어 정점 구조체의 성분이 두 개라고 하면 D3D11_INPUT_ELEMENT_DESC 배열의 원소도 두 개이어야 한다. 


struct D3D11_INPUT_ELEMENT_DESC{

LPCSTR SementicName;

UINT SemanticIndex;

DXGI_FORMAT Format;

UINT InputSlot;

UINT AlignedByteOffset;

D3D11_INPUT_CLASSIFICATION InputSlotClass;

UINT InstanceDataStepRate;

};


- 정점 구조체의 각 성분을 D3D11_INPUT_ELEMENT_DESC 배열의 각 원소를 통해서 서술한다.


1. SemanticName : 성분에 부여된 문자열 이름

2. SemanticIndex : 의미소에 부여된 색인

3. Format : DXGI_FORMAT 열거형의 한 멤버

4. InputSlot : 이 성분의 자료가 공급될 정점 버퍼의 슬롯 색인

5. AlignedByteOffset : 입력 슬롯을 하나만 사용하는 경우 이 필드는 C++ 정점 구조체의 시작 위치와 이 정점 성분의 시작 위치 사이의 오프셋이다.

6. InputSlotClass : D3D11_INPUT_PER_VERTEX_DATA를 지정

7. InstanceDataStepRate : 지금은 0으로 지정


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


HRESULT ID3D11Device::CreateInputLayout(

const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs,

UINT NumElements,

const void* pShaderBytecodeWith InputSignature,

SIZE_T BytecodeLength,

ID3D11InputLayout** ppInputLayout);


1. pInputElementDescs : 정점 구조체를 서술하는 D3D11_INPUT_ELEMENT_DESCE들의 

2. NumElements : 그 D3D11_INPUT_ELEMENT_DESC 배열의 원소 개수

3. pShaderBytecodeWithInputSignature : 정점 셰이더를 포함한 컴파일해서 얻은 바이트 코드를 가리키는 포인터.

4. BytecodeLength : 그 바이트 코드의 크기(바이트 단위)

5. ppInputLayout : 생성된 입력 배치를 이 포인터를 통해서 돌려준다


* 입력 서명(input signature) : 정점 셰이더는 일단의 정점 성분들을 입력 매개변수들로서 받는데, 그 입력 매개 변수들의 형식과 개수를 통칭

- 커스텀 정점 구조체의 성분들은 반드시 정점 셰이더의 적절한 입력 매개변수에 대응되어야 한다