| 개념 | 설명 |
|---|---|
| Mesh | Geometry + VertexBuffer + IndexBuffer를 묶은 데이터 구조. 3D 도형 단위 렌더링 객체 |
| MeshRenderer | Mesh 데이터를 기반으로 화면에 렌더링하는 컴포넌트. Shader와 Texture와도 연결됨 |
| GameObject | MeshRenderer 등의 컴포넌트를 보유하며 Transform(위치, 회전, 크기) 정보를 가진 오브젝트 |
| ResourceManager | Mesh와 같은 리소스를 재사용하기 위한 중앙 리소스 관리 클래스 |
| CreateBuffers() | Geometry 데이터를 바탕으로 GPU에 전달할 버퍼(VertexBuffer, IndexBuffer)를 생성하는 함수 |
| 용어 | 설명 |
|---|---|
| Geometry | 도형의 정점 및 인덱스 데이터를 가지는 구조체 |
| VertexBuffer | 정점 정보를 담은 GPU 버퍼 |
| IndexBuffer | 삼각형을 구성할 정점 순서를 담은 GPU 버퍼 |
| Component | GameObject에 부착되어 동작을 부여하는 모듈 단위 클래스 |
| Shader | HLSL 기반으로 렌더링 방식 정의 |
| Texture | 도형 표면에 입힐 이미지 |
| LightDir | 광원의 방향 벡터 |
Mesh 클래스 정의 및 구현Mesh.h
class Mesh : public ResourceBase
{
public:
Mesh();
virtual ~Mesh();
void CreateQuad();
void CreateCube();
void CreateGrid(int32 sizeX, int32 sizeZ);
void CreateSphere();
shared_ptr<VertexBuffer> GetVertexBuffer();
shared_ptr<IndexBuffer> GetIndexBuffer();
private:
void CreateBuffers();
private:
shared_ptr<Geometry<VertexTextureNormalData>> _geometry;
shared_ptr<VertexBuffer> _vertexBuffer;
shared_ptr<IndexBuffer> _indexBuffer;
};
Mesh.cpp
void Mesh::CreateBuffers()
{
_vertexBuffer = make_shared<VertexBuffer>();
_vertexBuffer->Create(_geometry->GetVertices());
_indexBuffer = make_shared<IndexBuffer>();
_indexBuffer->Create(_geometry->GetIndices());
}
CreateBuffers()는 Geometry에서 가져온 정점과 인덱스를 GPU 버퍼로 변환한다.CreateQuad, CreateCube, CreateSphere 등은 도형별 Geometry 데이터를 만든 뒤 CreateBuffers()를 호출한다.MeshRenderer 클래스 구성 및 렌더링 구현MeshRenderer.h
class MeshRenderer : public Component
{
public:
MeshRenderer();
virtual ~MeshRenderer();
virtual void Update() override;
void SetMesh(shared_ptr<Mesh> mesh);
void SetTexture(shared_ptr<Texture> texture);
void SetShader(shared_ptr<Shader> shader);
};
MeshRenderer.cpp
void MeshRenderer::Update()
{
if (_mesh == nullptr || _texture == nullptr || _shader == nullptr)
return;
auto world = GetTransform()->GetWorldMatrix();
_shader->GetMatrix("World")->SetMatrix((float*)&world);
_shader->GetMatrix("View")->SetMatrix((float*)&Camera::S_MatView);
_shader->GetMatrix("Projection")->SetMatrix((float*)&Camera::S_MatProjection);
_shader->GetSRV("Texture0")->SetResource(_texture->GetComPtr().Get());
Vec3 lightDir = {0.f, 0.f, 1.f}; // 임시 광원 방향
_shader->GetVector("LightDir")->SetFloatVector((float*)&lightDir);
uint32 stride = _mesh->GetVertexBuffer()->GetStride();
uint32 offset = _mesh->GetVertexBuffer()->GetOffset();
DC->IASetVertexBuffers(0, 1, _mesh->GetVertexBuffer()->GetComPtr().GetAddressOf(), &stride, &offset);
DC->IASetIndexBuffer(_mesh->GetIndexBuffer()->GetComPtr().Get(), DXGI_FORMAT_R32_UINT, 0);
_shader->DrawIndexed(0, 0, _mesh->GetIndexBuffer()->GetCount(), 0, 0);
}
MeshRenderer::Update()는 객체의 Transform을 기반으로 World 행렬을 생성하고, GPU에 필요한 정보를 전달해 렌더링을 수행한다.MeshDemo에서 GameObject로 통합 테스트MeshDemo.h
class MeshDemo : public IExecute
{
public:
void Init() override;
void Update() override;
void Render() override;
shared_ptr<GameObject> _obj;
shared_ptr<GameObject> _camera;
};
MeshDemo.cpp
void MeshDemo::Init()
{
_camera = make_shared<GameObject>();
_camera->GetOrAddTransform();
_camera->AddComponent(make_shared<Camera>());
_camera->AddComponent(make_shared<CameraScript>());
_obj = make_shared<GameObject>();
_obj->GetOrAddTransform();
_obj->AddComponent(make_shared<MeshRenderer>());
{
auto shader = make_shared<Shader>(L"07. Normal.fx");
_obj->GetMeshRenderer()->SetShader(shader);
}
{
RESOURCES->Init();
auto mesh = RESOURCES->Get<Mesh>(L"Sphere");
_obj->GetMeshRenderer()->SetMesh(mesh);
}
{
auto texture = RESOURCES->Load<Texture>(L"Veigar", L"..\\Resources\\Textures\\veigar.jpg");
_obj->GetMeshRenderer()->SetTexture(texture);
}
}
void MeshDemo::Update()
{
_camera->Update();
_obj->Update();
}
void MeshDemo::Render()
{
// 렌더링은 MeshRenderer::Update에서 처리됨
}
_obj 하나만으로 도형 생성, 셰이더 연결, 텍스처 적용, 렌더링까지 자동화됨.Render()는 비워도 무방하며, 렌더링은 컴포넌트 내부에서 처리됨._vertexBuffer, _indexBuffer를 관리할 필요 없이, 조립만 하면 된다.