DX11) VertexShader, PixelShader 초기화
내 목표에 연관 있는 VertexShader와 PixelShader를 초기화 하는 코드를 정리해보고자 한다.
Initialize
버퍼 정의
#define _DEVICE CDevice::GetInst()->GetDevice()
#define _CONTEXT CDevice::GetInst()->GetContext()
// 정점 데이터를 GPU 메모리에 저장하는 버퍼
ComPtr<ID3D11Buffer> VertexBuffer;
// Vertex Shader가 사용할 정점 데이터의 구조를 GPU에 알려주는 역할
// POSITION(위치)과 COLOR(색상) 등등
ComPtr<ID3D11InputLayout> Layout;
// System Mem 정점 정보
Vertex VtxArr[3] = {};
// Vertex Shader
ComPtr<ID3DBlob> VS_Blob; // 컴파일한 쉐이더 코드를 저장
ComPtr<ID3D11VertexShader> VS; // Vertex Shader
// Pixel Shader
ComPtr<ID3DBlob> PS_Blob; // 컴파일한 쉐이더 코드를 저장
ComPtr<ID3D11PixelShader> PS; // Pixel Shader
// Error Bolb
ComPtr<ID3DBlob> Err_Blob;
Shader들을 초기화하는데 필요한 버퍼들을 미리 정의 한다.
VertexBuffer
D3D11_BUFFER_DESC VertexBufferDesc = {};
VertexBufferDesc.ByteWidth = sizeof(Vertex) * 3; // 삼각형 그리기라 정점 3개
VertexBufferDesc.MiscFlags = 0;
VertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; // 만들어질때 용도(vertex) 지정
VertexBufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; // 버퍼가 생성된 이후에 cpu에서 접근해 덮어쓰기가 가능하게 설정
VertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
D3D11_SUBRESOURCE_DATA SubDesc = {};
SubDesc.pSysMem = VtxArr;
_DEVICE->CreateBuffer(&VertexBufferDesc,
&SubDesc,
VertexBuffer.GetAddressOf())
VertexBufferDesc.BindFlags
-
D3D11_USAGE_DYNAMIC
: CPU가 데이터를 업데이트할 수 있는 버퍼 (자주 변경되는 데이터에 적합). -
D3D11_USAGE_DEFAULT
: GPU 전용(빠르지만 CPU 접근 불가). -
CPUAccessFlags = D3D10_CPU_ACCESS_WRITE
: CPU가 메모리를 수정할 수 있도록 설정.
Input Layout
// 지금은 Position과 Color 두 요소만 들어가서 2
D3D11_INPUT_ELEMENT_DESC LayoutDesc[2] = {};
LayoutDesc[0].AlignedByteOffset = 0;
LayoutDesc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
LayoutDesc[0].InputSlot = 0;
LayoutDesc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
LayoutDesc[0].InstanceDataStepRate = 0;
LayoutDesc[0].SemanticIndex = 0;
LayoutDesc[0].SemanticName = "POSITION";
LayoutDesc[1].AlignedByteOffset = 12;
LayoutDesc[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
LayoutDesc[1].InputSlot = 0;
LayoutDesc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
LayoutDesc[1].InstanceDataStepRate = 0;
LayoutDesc[1].SemanticIndex = 0;
LayoutDesc[1].SemanticName = "COLOR";
_DEVICE->CreateInputLayout(LayoutDesc, 2,
VS_Blob->GetBufferPointer(),
VS_Blob->GetBufferSize(),
Layout.GetAddressOf())
LayoutDesc.Format
-
DXGI_FORMAT_R32G32B32_FLOAT
→ 32비트 부동소수점(float) X, Y, Z 좌표 -
DXGI_FORMAT_R32G32B32A32_FLOAT
→ 32비트 부동소수점(float) R, G, B, A 색상 값 -
AlignedByteOffset = 12
→ 위치 데이터(12바이트)를 읽은 후, 4바이트 색상 데이터를 읽음.
Shader 컴파일
// VertexShader 컴파일
D3DCompileFromFile(shaderPath,
nullptr,
D3D_COMPILE_STANDARD_FILE_INCLUDE,
"VS_Std2D",
"vs_5_0",
D3DCOMPILE_DEBUG, 0,
VS_Blob.GetAddressOf(),
Err_Blob.GetAddressOf())
// PixelShader 컴파일
D3DCompileFromFile(shaderPath,
nullptr,
D3D_COMPILE_STANDARD_FILE_INCLUDE,
"PS_Std2D",
"ps_5_0",
D3DCOMPILE_DEBUG, 0,
PS_Blob.GetAddressOf(),
Err_Blob.GetAddressOf())
-
"VS_Std2D"
→ 쉐이더 파일에서VS_Std2D
라는 함수(Entry Point)를 찾음. -
"vs_5_0"
→ DirectX 11에서 사용하는 Vertex Shader 5.0 버전 사용. -
D3DCOMPILE_DEBUG
→ 디버그 모드에서 컴파일, 오류 메시지 포함. -
"PS_Std2D"
→ 쉐이더 파일에서PS_Std2D
라는 함수(Entry Point)를 찾음. -
"ps_5_0"
→ DirectX 11에서 사용하는 Pixel Shader 5.0 버전 사용.
렌더링 과정
UINT Stride = sizeof(Vertex);
UINT Offset = 0;
// Vertex Buffer 바인딩
_CONTEXT->IASetVertexBuffers(0, 1, VertexBuffer.GetAddressOf(), &Stride, &Offset);
// 정점 레이아웃 적용
_CONTEXT->IASetInputLayout(Layout.Get());
// 정점 그리기 방식 (삼각형 리스트)
_CONTEXT->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Vertex Shader & Pixel Shader 적용
_CONTEXT->VSSetShader(VS.Get(), nullptr, 0);
_CONTEXT->PSSetShader(PS.Get(), nullptr, 0);
// 정점 3개를 사용하여 그리기
_CONTEXT->Draw(3, 0);
댓글남기기