일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 다이렉트X
- 프로그래밍
- CPU
- GPU
- DirectX12
- RenderTargetView
- 동기화
- Direct3D Init
- swapchain
- DirectX
- Direct3D
- 다중표본화
- 다이렉트X 튜토리얼
- c
- 다이렉트 초기화
- CommandList
- C언어
- View
- 세팅
- engine
- Direct Init
- vertex
- 게임수학
- 코딩
- DESC
- C++
- Input Assembler
- DirectXTK
- 전처리문
- UE4
- Today
- Total
비타Cpp
Direct3D 정점(Vertex) 입력과 배치 본문
Direct3D에서는 정점(Vertex)에 공간적인 좌표값과 다른 추가적인 데이터를 부여할 수 있다. 원하는 데이터(특성)를 커스텀 정점 형식(Vertex Format)을 만들려면 우선 그러한 자료를 담을 구조체를 정의해야 한다. 다음은 서로 다른 두 가지 정점 형식의 예이다.
Vertex1 구조체
struct Vertex1
{
XMFLOAT3 Pos;
XMFLOAT4 Color;
}
Vertex2 구조체
struct Vectex2
{
XMFLOAT3 Pos;
XMFLOAT3 Normal;
XMFLOAT2 Tex0;
XMFLOAT2 Tex1;
}
정점 구조체를 정의한 다음에는 정점 구조체의 각 필드, 즉 정점의 각 성분으로 무엇을 해야 하는지를 Direct3D에게 알려 주어야 한다. 그러한 정보를 Direct3D에게 알려주는 수단으로 쓰이는 것이 입력 배치 서술(Input Layout Description)이다. 이 서술은 다음과 같은 D3D12_INPUT_LAYOUT_DESC라는 구조체로 대표된다.
typedef struct D3D12_INPUT_LAYOUT_DESC {
const D3D12_INPUT_ELEMENT_DESC *pInputElementDescs;
UINT NumElements;
} D3D12_INPUT_LAYOUT_DESC;
https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_input_layout_desc
구조체의 정의에서 보듯이, 입력 배치 서술은 그냥 D3D12_INPUT_ELEMENT_DESC 형식의 원소들을 담은 배열과 그 원소의 개수이다.
D3D12_INPUT_ELEMENT_DESC 배열의 각 원소는 정점 구조체의 각 성분을 서술한다. 이 배열의 원소들과 정점 구조체의 성분들은 1:1로 대응되어야 한다. 따라서, 정점 구조체의 성분이 두 개이면 그에 해당하는 D3D12_INPUT_ELEMENT_DESC의 배열에는 원소가 두 개 있어야 한다.
typedef struct D3D12_INPUT_ELEMENT_DESC {
LPCSTR SemanticName;
UINT SemanticIndex;
DXGI_FORMAT Format;
UINT InputSlot;
UINT AlignedByteOffset;
D3D12_INPUT_CLASSIFICATION InputSlotClass;
UINT InstanceDataStepRate;
} D3D12_INPUT_ELEMENT_DESC;
https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_input_element_desc
1. SemanticName : 성분에 부여된 문자열 이름. 이것은 정점 셰이더(VS - Vertex Shader)에서 의미소(Semantic) 이름으로 쓰이므로, 반드시 유효한 변수 이름이어야 한다. 의미소는 정점 구조체의 성분을 정점 셰이더 입력 서명과 대응시키는 역할을 한다.
2. SemanticIndex : 의미소에 부여된 색인. 이런 색인이 필요한 이유가 위의 그림에서 처럼 TEXCOORD가 두 개가 있을 경우 각자 구분을 하기 위해 필요하다. 셰이더 코드에서 색인이 지정되지 않은 의미소는 색인이 0을 의미한다.
3. Format : DXGI_FORMAT 열거형의 한 멤버로, 이 정점 성분의 자료 형식을 Direct3D에게 알려주는 역할을 한다.
4. InputSlot : 이 성분의 자료를 가져올 정점 버퍼 슬롯의 색인이다. Direct3D에서는 총 16개의 정점 버퍼 슬롯(색인은 0~15까지)을 통해서 정점 자료를 공급할 수 있다.
5. AlignedByOffset : 지정된 입력 슬롯에서, C++정점 구조체의 시작 위치와 이 정점 성분의 시작 위치 사이의 거리를 나타내는 오프셋(바이트 단위)이다. 예를 들어 다음 정점 구조체에서 Pos성분의 오프셋은 0바이트이다. 구조체의 시작 위치와 성분의 시작 위치가 일치하기 때문이다. 다음 Normal성분은 Pos성분의 바이트들을 지나친 위치에서 시작하므로 오프셋이 12바이트(Pos = XMFLOAT3 = (4Byte, 4Byte, 4Byte))이다.
6. InputSlotClass : 일단 지금은 이 필드에 항상 D3D12_INPUT_PER_VERTEX_DATA를 지정한다. 다른 값은 고급 기법인 인스턴싱에 쓰인다.
7. InstaneDataStepRate : 일단 지금은 0을 지정한다. 다른 값들은 고급 기법인 인스턴싱에 쓰인다.
제일 처음 나왔던 두 개의 Vertex구조체 Vertex1과 Vertex2에 대한 입력 배치 서술 배열들은 다음과 같이 정의된다.
Vertex1_Input_Element_Desc
D3D12_INPUT_ELEMENT_DESC desc1[] =
{
{"POSITION", 0, DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}
};
Vertex2_Input_Element_Desc
D3D12_INPUT_ELEMENT_DESC desc2[] =
{
{"POSITION", 0, DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT::DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
{"TEXCOORD", 1, DXGI_FORMAT::DXGI_FORMAT_R32G32_FLOAT, 0, 32, D3D12_INPUT_CLASSIFICATION::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}
};
'DirectX12 > 튜토리얼' 카테고리의 다른 글
정점 버퍼(Vertex Buffer) (0) | 2021.12.12 |
---|---|
Direct3D 초기화 예제 (0) | 2021.12.04 |
메시지 처리부(Message Proc) (0) | 2021.12.04 |
FPS : Frames Per Second(초당 프레임 수) (0) | 2021.10.16 |
Direct3D Base 클래스 - D3DApp (0) | 2021.10.16 |