✅ 기존 구조의 문제점

기존에는 RenderDemo에서 직접적으로 _camera, _objs, LightDesc 등을 관리하면서 모든 오브젝트와 조명을 수동으로 Update 및 렌더링했음.

_camera->Update(); 
RENDER->Update(); 
RENDER->PushLightData(lightDesc);
INSTANCING->Render(_objs);

이 방식은 기능이 추가될수록 관리 포인트가 늘어나며, 재사용성도 떨어지는 구조.
Scene 단위로 관리하고, 컴포넌트 기반 시스템으로 리팩토링이 필요


🎯 목표

  • 모든 렌더링과 업데이트를 Scene 단위로 통합
  • 조명은 Light 컴포넌트로, 카메라는 Camera 컴포넌트로, 애니메이션/모델/메쉬도 각각 컴포넌트화
  • SceneManager를 통해 씬 전환 및 관리
  • Update, LateUpdate, Render게임 루프 분리 처리

1️⃣ Light 컴포넌트 추가

기존 LightDesc를 단순 변수로 처리하지 않고, GameObject에 붙이는 방식으로 리팩토링

🔸 Light.h

class Light : public Component
{
public:
    virtual void Update() override;
    LightDesc& GetLightDesc() { return _desc; }
    void SetAmbient(const Color& color);
    void SetLightDirection(Vec3 dir);
    // ...
private:
    LightDesc _desc;
};

🔸 Light::Update()

void Light::Update()
{
    RENDER->PushLightData(_desc);
}

이제 Light도 다른 컴포넌트처럼 GameObject에 붙여서 씬에 배치하면 자동으로 렌더링 시 반영됨.


2️⃣ GameObject에 Light 컴포넌트 접근 함수 추가

shared_ptr<Light> GameObject::GetLight()
{
    auto component = GetFixedComponent(ComponentType::Light);
    return static_pointer_cast<Light>(component);
}

3️⃣ Scene / SceneManager 클래스 설계

🔸 Scene

오브젝트 추가/제거, Update/LateUpdate 호출, Instancing 처리까지 담당

class Scene
{
    void Add(shared_ptr<GameObject> object);
    void Update();
    void LateUpdate();
private:
    unordered_set<shared_ptr<GameObject>> _objects;
    unordered_set<shared_ptr<GameObject>> _cameras;
    unordered_set<shared_ptr<GameObject>> _lights;
};

🔸 SceneManager

현재 Scene 관리 및 Scene 전환 기능

class SceneManager
{
    template<typename T>
    void ChangeScene(shared_ptr<T> scene) { _currentScene = scene; scene->Start(); }
    void Update() { _currentScene->Update(); _currentScene->LateUpdate(); }
};

SCENE, CUR_SCENE 매크로 등록해서 전역에서 쉽게 접근하도록 설정:

#define SCENE      GET_SINGLE(SceneManager)
#define CUR_SCENE  SCENE->GetCurrentScene()

4️⃣ Game과 RenderManager에서 Update 책임 분산

  • SCENE->Update() → Game 루프에 추가
  • Camera::Update() → View/Proj 행렬 Push 책임 분담
void Camera::Update()
{
    UpdateMatrix();
    RENDER->PushGlobalData(Camera::S_MatView, Camera::S_MatProjection);
}

5️⃣ SceneDemo 클래스 도입

기존 RenderDemo는 삭제하고 SceneDemo에서 모든 객체와 컴포넌트는 CUR_SCENE->Add(...) 방식으로 Scene에 등록

auto obj = make_shared<GameObject>();
obj->AddComponent(...);
CUR_SCENE->Add(obj);

Camera, Light, Animation, Model, Mesh 모두 이 방식으로 처리함


🎥 실행 흐름

  1. SceneDemo::Init()에서 GameObject 구성하고 CUR_SCENE에 Add
  2. Game::Update()에서 SCENE->Update() 호출
  3. Scene::Update()에서 각 오브젝트 Update + Instancing 처리
  4. Scene::LateUpdate()에서 카메라나 기타 요소 LateUpdate
  5. Render는 Shader pass 설정만 맞춰주면 Shader 하나로 통합 처리 가능

profile
李家네_공부방

0개의 댓글