Material과 Mesh 시스템의 분리 및 통합 구조 설계
기존 MeshRenderer 내부에 혼재되어 있던 렌더링 요소(정점 버퍼, 인덱스 버퍼, 셰이더, 텍스처 등)를 명확하게 역할별로 분리하여 각각 Mesh, Shader, Material 클래스로 나누고, 이들을 모두 ResourceManager를 통해 중앙 관리하는 구조를 만드는 것입니다.
Unity와 유사한 Component 기반 조립형 렌더링 구조를 실현하고, 유지보수성과 재사용성을 극대화합니다.
Geometry, VertexBuffer, IndexBuffer를 사용합니다.Shader, Texture를 포함하고 있으며, 이후 Lighting, Animation 등으로 확장됩니다.VertexShader, 픽셀 처리용 PixelShader, 정점 구조 정의용 InputLayout으로 구성됩니다.Mesh, Material, Shader, Texture와 같은 리소스를 이름 기반(Key)으로 중앙에서 관리합니다.| 용어 | 설명 |
|---|---|
Mesh | 물체의 기하 구조 (정점 + 인덱스) |
Material | 시각적 특성 정의 (Shader + Texture) |
Shader | GPU 프로그램 (VS + PS + InputLayout) |
VertexBuffer | 정점 정보를 담은 GPU 버퍼 |
IndexBuffer | 도형 그리기 순서를 담은 GPU 버퍼 |
InputLayout | 정점 데이터의 구성 정의 |
ResourceManager | 리소스 생성 및 이름 기반 조회 담당 |
MeshRenderer | Mesh와 Material을 보유하며 렌더링 수행 |
Pipeline | 렌더링 명령 수행 클래스 |
// 분리 전 구조
shared_ptr<Geometry<VertexTextureData>> _geometry;
shared_ptr<VertexBuffer> _vertexBuffer;
shared_ptr<IndexBuffer> _indexBuffer;
➡️ 이 구조는 기하정보와 렌더링 버퍼가 모두 MeshRenderer에 포함되어 있어 응집도가 낮음. 이들을 Mesh 클래스로 추출하여 독립적 관리가 가능하게 함.
Mesh 클래스 선언 및 구현class Mesh : public ResourceBase
{
public:
Mesh(ComPtr<ID3D11Device> device);
virtual ~Mesh();
void CreateDefaultRectangle();
shared_ptr<VertexBuffer> GetVertexBuffer();
shared_ptr<IndexBuffer> GetIndexBuffer();
private:
ComPtr<ID3D11Device> _device;
shared_ptr<Geometry<VertexTextureData>> _geometry;
shared_ptr<VertexBuffer> _vertexBuffer;
shared_ptr<IndexBuffer> _indexBuffer;
};
void Mesh::CreateDefaultRectangle()
{
_geometry = make_shared<Geometry<VertexTextureData>>();
GeometryHelper::CreateRectangle(_geometry);
_vertexBuffer = make_shared<VertexBuffer>(_device);
_vertexBuffer->Create(_geometry->GetVertices());
_indexBuffer = make_shared<IndexBuffer>(_device);
_indexBuffer->Create(_geometry->GetIndices());
}
MeshRenderer에서 Mesh 통합 적용shared_ptr<Mesh> _mesh;
void SetMesh(shared_ptr<Mesh> mesh) { _mesh = mesh; }
shared_ptr<Mesh> GetMesh() { return _mesh; }
➡️ Mesh를 내부 필드로 보관하고, 외부에서 설정/접근 가능한 구조로 변경.
RenderManager에서 Mesh 접근 방식 변경_pipeline->SetVertexBuffer(meshRenderer->GetMesh()->GetVertexBuffer());
_pipeline->SetIndexBuffer(meshRenderer->GetMesh()->GetIndexBuffer());
_pipeline->DrawIndexed(meshRenderer->GetMesh()->GetIndexBuffer()->GetCount(), 0, 0);
➡️ 더 이상 _vertexBuffer, _indexBuffer를 직접 접근하지 않고, Mesh 객체를 통해 버퍼 정보를 얻음.
void ResourceManager::CreateDefaultMesh()
{
auto mesh = make_shared<Mesh>(_device);
mesh->SetName(L"Rectangle");
mesh->CreateDefaultRectangle();
Add(mesh->GetName(), mesh);
}
➡️ "Rectangle"이라는 이름으로 사각형 Mesh를 생성하고 ResourceManager에 등록.
auto mesh = RESOURCES->Get<Mesh>(L"Rectangle");
meshRenderer->SetMesh(mesh);
➡️ SceneManager는 ResourceManager에서 Mesh를 가져와 MeshRenderer에 세팅.
Shader 클래스 정의class Shader : public ResourceBase
{
public:
Shader();
virtual ~Shader();
shared_ptr<InputLayout> GetInputLayout();
shared_ptr<VertexShader> GetVertexShader();
shared_ptr<PixelShader> GetPixelShader();
private:
friend class ResourceManager;
shared_ptr<InputLayout> _inputLayout;
shared_ptr<VertexShader> _vertexShader;
shared_ptr<PixelShader> _pixelShader;
};
ResourceManager만이 생성 및 내부 데이터 접근이 가능하도록 friend로 지정.InputLayout, VertexShader, PixelShader 세 가지 요소를 보유.void ResourceManager::CreateDefaultShader()
{
auto vertexShader = make_shared<VertexShader>(_device);
vertexShader->Create(L"Default.hlsl", "VS", "vs_5_0");
auto inputLayout = make_shared<InputLayout>(_device);
inputLayout->Create(VertexTextureData::descs, vertexShader->GetBlob());
auto pixelShader = make_shared<PixelShader>(_device);
pixelShader->Create(L"Default.hlsl", "PS", "ps_5_0");
auto shader = make_shared<Shader>();
shader->SetName(L"Default");
shader->_vertexShader = vertexShader;
shader->_inputLayout = inputLayout;
shader->_pixelShader = pixelShader;
Add(shader->GetName(), shader);
}
Default.hlsl을 통해 정점/픽셀 셰이더 생성."Default"로 ResourceManager에 등록.Material 클래스 선언 및 정의class Material : public ResourceBase
{
public:
Material();
virtual ~Material();
auto GetShader();
auto GetTexture();
void SetShader(shared_ptr<Shader> shader);
void SetTexture(shared_ptr<Texture> texture);
private:
shared_ptr<Shader> _shader;
shared_ptr<Texture> _texture;
};
Material은 시각적 속성을 담당하는 핵심 클래스입니다.Shader와 Texture를 포함하며, 이후 조명, 애니메이션, 머티리얼 파라미터 등을 추가 확장할 수 있도록 설계되어 있습니다.void ResourceManager::CreateDefaultMaterial()
{
shared_ptr<Material> material = make_shared<Material>();
material->SetName(L"Default");
material->SetShader(Get<Shader>(L"Default"));
material->SetTexture(Get<Texture>(L"chiikawa")); // 또는 "Cat", "Test"
Add(material->GetName(), material);
}
"Default"라는 이름으로 Material을 생성하여 ResourceManager에 등록."Default" 셰이더, Texture는 "chiikawa" 등을 사용함.MeshRenderer에서 Material 통합shared_ptr<Material> _material;
void SetMaterial(shared_ptr<Material> material) { _material = material; }
void SetShader(shared_ptr<Shader> shader) { _material->SetShader(shader); }
void SetTexture(shared_ptr<Texture> texture) { _material->SetTexture(texture); }
auto GetMaterial() { return _material; }
auto GetVertexShader() { return GetMaterial()->GetShader()->GetVertexShader(); }
auto GetInputLayout() { return GetMaterial()->GetShader()->GetInputLayout(); }
auto GetPixelShader() { return GetMaterial()->GetShader()->GetPixelShader(); }
auto GetTexture() { return GetMaterial()->GetTexture(); }
MeshRenderer가 Material을 내부에 포함하고 있고, 외부에서 쉽게 Shader, Texture에 접근할 수 있도록 헬퍼 함수들을 제공함.auto material = RESOURCES->Get<Material>(L"Default");
meshRenderer->SetMaterial(material);
"Default" Material을 가져와서 MeshRenderer에 세팅.info.inputLayout = meshRenderer->GetInputLayout();
info.vertexShader = meshRenderer->GetVertexShader();
info.pixelShader = meshRenderer->GetPixelShader();
_pipeline->SetVertexBuffer(meshRenderer->GetMesh()->GetVertexBuffer());
_pipeline->SetIndexBuffer(meshRenderer->GetMesh()->GetIndexBuffer());
_pipeline->SetTexture(0, SS_PixelShader, meshRenderer->GetTexture());
_pipeline->DrawIndexed(meshRenderer->GetMesh()->GetIndexBuffer()->GetCount(), 0, 0);
MeshRenderer의 헬퍼 함수들을 통해 필요한 모든 렌더링 요소(InputLayout, Shader, Texture 등)를 일괄 추출 가능.RenderManager는 이를 기반으로 VertexBuffer, IndexBuffer 세팅 → Shader & Texture 바인딩 → Draw 호출까지 렌더링 전체를 담당.| 항목 | 요약 |
|---|---|
| Mesh 분리 | 정점/인덱스 버퍼 → Mesh 클래스로 독립 |
| Material 설계 | Shader + Texture 조합으로 재질 정의 |
| Shader 구조 | VS, PS, InputLayout을 내부 구성 요소로 보유 |
| ResourceManager | 모든 리소스를 이름 기반으로 중앙 관리 |
| MeshRenderer 역할 변화 | Mesh + Material 보유, 렌더링 전용 |
| RenderManager | 헬퍼 함수 기반으로 렌더링 요소 추출 및 처리 |
| Unity 스타일 설계 | 컴포넌트 기반 조립형 구조 완성 |
| 확장성 보장 | 향후 Animation, Lighting, 파일 입출력 구조로 자연스럽게 확장 가능 |