1. 03. ConstantBufferDemo 클래스 생성하기
탐색기의 Client 프로젝트 폴더로 가서
02. QuadDemo클래스를 복제하고, 03. ConstBufferDemo라고 이름을 바꾼다.
그리고 솔루션 탐색기의 Client/Game 필터에 넣는다.
그리고 코드에서 QuadDemo라 되어 있는 걸 ConstBufferDemo라고 바꿔준다.
여기서 새로운 실습을 하면 된다.
2. 03. ConstantBuffer.fx 생성하기
02. Quad.fx도 탐색기 Shaders 폴더에서 복제하고 03. ConstBuffer.fx로 이름을 바꾼다.
그리고 솔루션 탐색기에서 Shaders 필터에 넣어준다.
3. 03. ConstantBufferDemo를 Main에서 GameDesc에 세팅하기
Main.cpp에도
#include "03. ConstBufferDemo.h"
를 추가한다.
그리고 WinMain함수에서
desc.app = make_shared<ConstBufferDemo>(); // 실행 단위
이렇게 app을 채운다.
03. ConstantBufferDemo 클래스는 상수 버퍼를 사용하기 위해 어떻게 했었는지를 복기해서 사용한다.
4. 03. ConstantBuffer.fx에서 matrix 변수 World, View, Projection을 선언하고, VS에서 사용하기
World, View, Projection 같은 걸 꽂아주는 부분들을 상수 버퍼를 이용해서 해줬었다.
원래
cbuffer CameraData : register(b0)
{
row_major matrix matView;
row_major matrix matProjection;
}
cbuffer TransformData : register(b1)
{
row_major matrix matWorld;
}
하면서 했었는데 이 부분들이 깔끔하게 그냥
03. ConstantBuffer.fx에서
matrix World;
matrix View;
matrix Projection;
이렇게 하면 된다.
VS에서 World, View, Projection을 곱해준다.
VertexOutput VS( VertexInput input)
{
VertexOutput output;
output.position = mul(input.position, World);
output.position = mul(output.position, View);
output.position = mul(output.position, Projection);
output.color = input.color;
return output;
}
나머지는 딱히 안 고쳐도 된다.
5. 03. ConstantBufferDemo클래스에서 _world, _view, _projection 행렬을 Matrix::Identity로 초기화 하기
실습하고 싶은 건 밖에서 뭔가 꽂아주고 싶거나 uint 라거나 뭔가를 받아주게 된다.
뭔가를 꽂아주는 게 상수 버퍼의 개념이었는데
이거를 03. ConstantBufferDemo 클래에서는 어떻게 할지 실습을 해본다.
03. ConstantBufferDemo.h에
Matrix _world = Matrix::Identity;
Matrix _view = Matrix::Identity;
Matrix _projection = Matrix::Identity;
를 추가한다.
_view랑 _projection은 카메라를 관리하는 것이고,
_world는 물체마다 transform이 있을 테니까 transform에서 world행렬 추출할 수 있다.
지금은 identity로 설정을 하고 고쳐가는 식으로 한다.
6. STR중 Translation을 선언하고, 이를 이용해 ConstantBufferDemo::Update에서 키보드 입력에 따라 _world 행렬을 변경하여 이동하게 하기
STR 중에서 Translation만 적용시켜 본다.
Vec3 _translation = Vec3(0.f, 0.f, 0.f);
이걸 추가하고 얘를 이용해서 키보드를 누르면 위치가 변하는 걸 해본다.
03. ConstBufferDemo.cpp에서
void ConstBufferDemo::Init()
{
_shader = make_shared<Shader>(L"03. ConstBuffer.fx");
이렇게 수정하고 나머지는 그대로 Quad 그리는 걸 실습을 해본다.
Update에
void ConstBufferDemo::Update()
{
float dt = TIME->GetDeltaTime();
if (INPUT->GetButton(KEY_TYPE::A))
{
_translation.x -= 3.f * dt;
}
else if (INPUT->GetButton(KEY_TYPE::D))
{
_translation.x += 3.f * dt;
}
else if (INPUT->GetButton(KEY_TYPE::W))
{
_translation.y += 3.f * dt;
}
else if (INPUT->GetButton(KEY_TYPE::S))
{
_translation.y -= 3.f * dt;
}
// SRT
// 지금은 Scale, Rotation은 Identity 행렬이라고 하고
_world = Matrix::CreateTranslation(_translation);
}
키보드로 이동하는 코드를 넣었다.
DeltaTime을 곱해줘야 사양에 상관 없이 일정한 속도로 이동하게 된다.
_view가 Identity라는 걸 월드 기준 0, 0, 0에 카메라가 있고, World의 z 축을 카메라가 바라보고 있다는 얘기가 된다. 그런 식으로 완전히 일치한 상황이라고 보면 된다.
7. ConstBufferDemo::Render에서 _shader->GetMatrix함수를 이용해서 World, View, Projection을 찾아서 각 값을 세팅 후 실행하기
ConstBufferDemo::Render에서 상수 버퍼를 어떻게 넘겨줄 것인가가 관건이다.
굉장히 단순하게 되어있다.
World, View, Projection을 각각 세팅해야 하는데
_shader에 material도 포함이 된다고 했다. Material이라는 개념을 통해서 재질에다가 이런저런 값들을 건네어주는데, shader가 하나의 함수라고 보면 함수에다 건네주는 인자값들이 사실상 material의 값들이라고 볼 수 있다. 그거를 _shader→ 보면 GetMatrix를 이용해서 이름을 찾아주면 된다.
void ConstBufferDemo::Render()
{
// ?
_shader->GetMatrix("World")->SetMatrix((float*)&_world);
_shader->GetMatrix("View")->SetMatrix((float*)&_view);
_shader->GetMatrix("Projection")->SetMatrix((float*)&_projection);
_shader→ 해서 보면 Get 시리즈가 많이 있다. 이 중에서 이용해서 얻어오면 된다.
그때 그때마다 필요한 걸 찾으면 된다.
DrawIndexed의 pass 인자를 1에서 다시 0으로 바꿔서 wireframe에서 일반 버전으로 바꾸고
void ConstBufferDemo::Render()
{
// ?
_shader->GetMatrix("World")->SetMatrix((float*)&_world);
_shader->GetMatrix("View")->SetMatrix((float*)&_view);
_shader->GetMatrix("Projection")->SetMatrix((float*)&_projection);
uint32 stride = _vertexBuffer->GetStride();
uint32 offset = _vertexBuffer->GetOffset();
// DeviceContext에서 IA단계에서 사용할 VertextBuffer를 묶어주는 함수였다.
DC->IASetVertexBuffers(0, 1, _vertexBuffer->GetComPtr().GetAddressOf(), &stride, &offset);
DC->IASetIndexBuffer(_indexBuffer->GetComPtr().Get(), DXGI_FORMAT_R32_UINT, 0);
//_shader->Draw(1, 0, 3);
_shader->DrawIndexed(0, 0, _indexBuffer->GetCount(), 0, 0);
}
빌드를 하면 shader에서 에러가 나는데 "UTF-8 without BOM" 혹은 "UTF-8 without signature" 인코딩으로 하니 해결된다.
실행을 한다.
키 입력에 따라 사각형이 움직인다.
굉장히 편하다.
쉐이더와 ConstBufferDemo에만 집중할 수 있었다.
상수 버퍼를 이용해서 건네주고 하는 부분도 이렇게 할 수 있다는 걸 알 수 있다.
상수 버퍼로 했던 걸 조금 더 단순화해서 빠르게 할 수 있는 방식이다.
ConstBufferDemo::Render의 _shader→GetMatrix는 매번 렌더링 할 때마다 하는 건 좀 느리고, GetMatrix의 반환 값 ComPtr<ID3DX11EffectMatrixVariable> 이 아이를 따로 저장해서 파싱 해서 쓰는 게 조금 더 효과적이다. 너무 난무해도 좋진 않다.
성공적으로 상수 버퍼를 테스트하는 것도 완료를 했다.
'DirectX' 카테고리의 다른 글
36. DirectX11 3D 입문_텍스처 (0) | 2024.02.06 |
---|---|
35. DirectX11 3D 입문_카메라 (0) | 2024.02.05 |
33. DirectX11 3D 입문_사각형 띄우기 (0) | 2024.02.01 |
32. DirectX11 3D 입문_프로젝트 설정 (0) | 2024.01.31 |
31. 엔진구조_Data (0) | 2024.01.29 |
댓글