수업


🧩 주제

  • 이 강의의 핵심은 3D 객체를 구성하는 도형 정보를 단일 클래스로 통합한 Mesh 시스템 설계이다.
  • Geometry, VertexBuffer, IndexBuffer를 묶은 Mesh 클래스를 정의하고, 이 데이터를 기반으로 GPU에 전달하여 그릴 수 있도록 MeshRenderer 컴포넌트를 구현한다.
  • 이 구조는 나중에 오브젝트를 조립해서 배치하는 방식, 즉 Prefab 기반 조립식 렌더링 구조의 기반이 된다.

📘 개념

개념설명
MeshGeometry + VertexBuffer + IndexBuffer를 묶은 데이터 구조. 3D 도형 단위 렌더링 객체
MeshRendererMesh 데이터를 기반으로 화면에 렌더링하는 컴포넌트. Shader와 Texture와도 연결됨
GameObjectMeshRenderer 등의 컴포넌트를 보유하며 Transform(위치, 회전, 크기) 정보를 가진 오브젝트
ResourceManagerMesh와 같은 리소스를 재사용하기 위한 중앙 리소스 관리 클래스
CreateBuffers()Geometry 데이터를 바탕으로 GPU에 전달할 버퍼(VertexBuffer, IndexBuffer)를 생성하는 함수

📗 용어정리

용어설명
Geometry도형의 정점 및 인덱스 데이터를 가지는 구조체
VertexBuffer정점 정보를 담은 GPU 버퍼
IndexBuffer삼각형을 구성할 정점 순서를 담은 GPU 버퍼
ComponentGameObject에 부착되어 동작을 부여하는 모듈 단위 클래스
ShaderHLSL 기반으로 렌더링 방식 정의
Texture도형 표면에 입힐 이미지
LightDir광원의 방향 벡터

🧠 코드 분석

✅ 1. 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()를 호출한다.

✅ 2. 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에 필요한 정보를 전달해 렌더링을 수행한다.

✅ 3. 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()는 비워도 무방하며, 렌더링은 컴포넌트 내부에서 처리됨.

✅ 핵심

  1. Mesh 클래스는 Geometry → 버퍼 생성 → GPU 전달까지를 하나로 묶은 구조이다.
  2. MeshRenderer 컴포넌트는 GameObject에 부착되어, Shader/Texture와 함께 렌더링을 담당한다.
  3. GameObject 내부에는 Transform이 있어 WorldMatrix 생성이 자동화된다.
  4. Demo 코드에서는 더 이상 _vertexBuffer, _indexBuffer를 관리할 필요 없이, 조립만 하면 된다.
  5. 향후 Material, LightManager 등 추가 시스템과 결합 시 재사용성과 확장성이 높아진다.

profile
李家네_공부방

0개의 댓글