• 티스토리 홈
  • 프로필사진
    유니얼
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
유니얼
  • 프로필사진
    유니얼
    • 분류 전체보기 (295)
      • Unity (17)
        • 게임 개발 (5)
      • Unreal (24)
        • 게임 개발 (20)
      • DirectX (36)
      • 코딩테스트 (91)
        • 프로그래머스 (25)
        • 백준 (66)
      • Google Workspace (1)
      • Programing (102)
        • C# (68)
        • C++ (24)
        • JavaScript (10)
      • 게임 서버 프로그래밍 (17)
      • Web (6)
        • 슈퍼코딩 (6)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
    등록된 댓글이 없습니다.
  • 최근 공지
    등록된 공지가 없습니다.
# Home
# 공지사항
#
# 태그
# 검색결과
# 방명록
  • [DirectX11] SceneManager와 MeshRenderer
    2024년 02월 19일
    • 유니얼
    • 작성자
    • 2024.02.19.:46
    728x90

    DirectX 11로 게임 엔진 아키텍처 만들기

    이번 블로그 글에서는 MeshRender와 Scene 관리에 대해 알아보고자 합니다. 특히, DirectX 11을 사용하여 각 게임 오브젝트마다 리소스를 그리는 작업을 효율적으로 나누는 방법에 초점을 맞출 것입니다. 이를 위해 MeshRenderer 구현 방법과 함께, Scene과 SceneManager의 역할과 구현 방법에 대해 상세히 다루어, 게임의 구조를 보다 효율적으로 관리하는 방법을 탐구할 예정입니다.

     

    Result

    참고강의 링크:

    https://www.inflearn.com/course/directx11-%EA%B2%8C%EC%9E%84%EA%B0%9C%EB%B0%9C-%EB%8F%84%EC%95%BD%EB%B0%98/dashboard

     

    [게임 프로그래머 도약반] DirectX11 입문 강의 - 인프런

    게임 프로그래머 공부에 있어서 필수적인 DirectX 11 지식을 초보자들의 눈높이에 맞춰 설명하는 강의입니다., [사진][사진] [사진] 게임 개발자는 Unreal, Unity만 사용할 줄 알면 되는 거 아닌가요? 엔

    www.inflearn.com

    MeshRender

    MeshRenderer는 게임 오브젝트에 부착되어 그 오브젝트의 메시를 화면에 그리는 역할을 합니다. DirectX 11에서는 이를 위해 각 메시의 정점 데이터를 GPU에 전송하고, 적절한 셰이더를 사용하여 이를 렌더링하는 과정이 필요합니다. MeshRenderer 컴포넌트는 다음과 같은 핵심 기능을 포함합니다:

    • 메시 데이터 관리: 오브젝트의 메시(정점, 인덱스, 텍스처 좌표 등)를 관리합니다.
    • 렌더링 설정: 사용할 셰이더 프로그램, 텍스처, 머티리얼 등 렌더링에 필요한 설정을 관리합니다.
    • 드로우 콜 실행: 게임 루프 내에서 적절한 시점에 GPU로 드로우 콜을 실행하여 메시를 그립니다.
    #pragma once
    #include "Component.h"
    
    class Mesh;
    class Material;
    #include "Material.h"
    #include "Shader.h"
    
    // MeshRenderer 클래스는 게임 오브젝트의 메시를 렌더링하는 컴포넌트입니다.
    class MeshRenderer : public Component
    {
    	using Super = Component; // 부모 클래스인 Component에 대한 별칭을 설정합니다.
    public:
    	// 생성자: DirectX 디바이스와 디바이스 컨텍스트를 인자로 받습니다.
    	MeshRenderer(ComPtr<ID3D11Device> device, ComPtr<ID3D11DeviceContext> deviceContext);
    	virtual ~MeshRenderer(); // 소멸자
    
    	// 머티리얼 설정 메소드
    	void SetMaterial(shared_ptr<Material> material) { _material = material; }
    	// 셰이더 설정 메소드
    	void SetShader(shared_ptr<Shader> shader) { _material->SetShader(shader); }
    	// 메시 설정 메소드
    	void SetMesh(shared_ptr<Mesh> mesh) { _mesh = mesh; }
    	// 텍스처 설정 메소드
    	void SetTexture(shared_ptr<Texture> texture) { _material->SetTexture(texture); }
    
    	// 머티리얼 가져오기 메소드
    	shared_ptr<Material> GetMaterial() { return _material; }
    	// 버텍스 셰이더 가져오기 메소드
    	shared_ptr<VertexShader> GetVertexShader() { return GetMaterial()->GetShader()->GetVertexShader(); }
    	// 인풋 레이아웃 가져오기 메소드
    	shared_ptr<InputLayout> GetInputLayout() { return GetMaterial()->GetShader()->GetInputLayout(); }
    	// 픽셀 셰이더 가져오기 메소드
    	shared_ptr<PixelShader> GetPixelShader() { return GetMaterial()->GetShader()->GetPixelShader(); }
    
    	// 메시 가져오기 메소드
    	shared_ptr<Mesh> GetMesh() { return _mesh; }
    	// 텍스처 가져오기 메소드
    	shared_ptr<Texture> GetTexture() { return _material->GetTexture(); }
    
    private:
    	ComPtr<ID3D11Device> _device; // DirectX 디바이스 인스턴스
    
    	friend class RenderManager; // RenderManager 클래스에서 MeshRenderer의 private 멤버에 접근할 수 있도록 허용
    
    	// 메시와 머티리얼 정보를 저장하는 멤버 변수
    	shared_ptr<Mesh> _mesh; // 메시 정보
    	shared_ptr<Material> _material; // 머티리얼 정보
    };
    #include "pch.h"
    #include "MeshRenderer.h"
    #include "Camera.h"
    #include "GameObject.h"
    #include "Game.h"
    #include "Pipeline.h"
    #include "Mesh.h"
    
    // 생성자 구현: MeshRenderer 컴포넌트를 초기화합니다.
    MeshRenderer::MeshRenderer(ComPtr<ID3D11Device> device, ComPtr<ID3D11DeviceContext> deviceContext) 
    	: Super(ComponentType::MeshRenderer), _device(device)
    {
    
    }
    
    // 소멸자 구현
    MeshRenderer::~MeshRenderer()
    {
    
    }

    Scene

    Scene은 게임의 한 장면을 구성하는 오브젝트들의 집합입니다. 예를 들어, 메인 메뉴, 각 게임 레벨, 종료 화면 등 게임의 다양한 단계를 각각 다른 Scene으로 구성할 수 있습니다. Scene 내에서는 다음과 같은 요소들을 관리합니다:

    • 게임 오브젝트: Scene에 속한 모든 게임 오브젝트들의 리스트를 관리합니다.
    • 라이팅과 카메라 설정: Scene의 라이팅, 카메라 뷰와 같은 환경 설정을 관리합니다.
    • 업데이트와 렌더링: Scene 내의 모든 게임 오브젝트를 업데이트하고, 렌더링 순서를 결정합니다.
    #pragma once
    
    class GameObject;
    
    // Scene 클래스는 게임의 장면을 관리하는 클래스입니다. 여러 게임 오브젝트들을 포함하고 있습니다.
    class Scene
    {
    public:
    	// 게임 오브젝트들의 초기화를 위한 메소드
    	void Awake();
    	// 게임 시작 시 호출되는 메소드
    	void Start();
    	// 매 프레임마다 호출되는 업데이트 메소드
    	void Update();
    	// 모든 업데이트 로직이 실행된 후 호출되는 메소드
    	void LateUpdate();
    	// 고정된 업데이트 주기로 호출되는 메소드, 물리 계산 등에 사용
    	void FixedUpdate();
    
    public:
    	// 새 게임 오브젝트를 장면에 추가하는 메소드
    	void AddGameObject(shared_ptr<GameObject> gameObject);
    	// 장면에서 게임 오브젝트를 제거하는 메소드
    	void RemoveGameObject(shared_ptr<GameObject> gameobject);
    
    	// 현재 장면에 있는 모든 게임 오브젝트들을 반환하는 메소드
    	const vector<shared_ptr<GameObject>>& GetGameObjects() { return _gameObjects; }
    
    private:
    	// 현재 장면에 있는 게임 오브젝트들을 저장하는 벡터
    	vector<shared_ptr<GameObject>> _gameObjects;
    };
    #include "pch.h"
    #include "Scene.h"
    #include "GameObject.h"
    
    // 장면의 모든 게임 오브젝트를 초기화합니다.
    void Scene::Awake()
    {
    	for (const shared_ptr<GameObject>& gameObejct : _gameObjects) {
    		gameObejct->Awake();
    	}
    }
    
    // 장면이 시작될 때 각 게임 오브젝트의 Start 메소드를 호출합니다.
    void Scene::Start()
    {
    	for (const shared_ptr<GameObject>& gameObejct : _gameObjects) {
    		gameObejct->Start();
    	}
    }
    
    // 매 프레임마다 각 게임 오브젝트의 Update 메소드를 호출합니다.
    void Scene::Update()
    {
    	for (const shared_ptr<GameObject>& gameObejct : _gameObjects) {
    		gameObejct->Update();
    	}
    }
    
    // 모든 Update 메소드 호출 후 각 게임 오브젝트의 LateUpdate 메소드를 호출합니다.
    void Scene::LateUpdate()
    {
    	for (const shared_ptr<GameObject>& gameObejct : _gameObjects) {
    		gameObejct->LateUpdate();
    	}
    }
    
    // 고정된 시간 간격으로 각 게임 오브젝트의 FixedUpdate 메소드를 호출합니다.
    void Scene::FixedUpdate()
    {
    	for (const shared_ptr<GameObject>& gameObejct : _gameObjects) {
    		gameObejct->FixedUpdate();
    	}
    }
    
    // 장면에 새로운 게임 오브젝트를 추가합니다.
    void Scene::AddGameObject(shared_ptr<GameObject> gameObject)
    {
    	_gameObjects.push_back(gameObject);
    }
    
    // 장면에서 특정 게임 오브젝트를 제거합니다.
    void Scene::RemoveGameObject(shared_ptr<GameObject> gameobject)
    {
    	auto findIt = std::find(_gameObjects.begin(), _gameObjects.end(), gameobject);
    	if (findIt != _gameObjects.end()) {
    		_gameObjects.erase(findIt);
    	}
    }

    SceneManager

    SceneManager는 게임의 전체적인 Scene 관리를 담당합니다. 이는 현재 활성화된 Scene을 추적하고, Scene 간 전환을 처리하는 역할을 합니다. SceneManager의 주요 기능은 다음과 같습니다:

    • Scene 로딩과 언로딩: 새 Scene을 로딩하거나 현재 Scene을 언로딩합니다.
    • Scene 전환: 사용자의 입력이나 게임 로직에 따라 다른 Scene으로의 전환을 관리합니다.
    • Scene 관리: 현재 활성화된 Scene에 대한 참조를 유지하고, 필요에 따라 다른 Scene으로의 정보 전달을 처리합니다.
    #pragma once
    
    class Scene;
    
    // SceneManager 클래스는 게임의 여러 장면(Scene)을 관리하는 역할을 합니다.
    class SceneManager
    {
    public:
    	// 생성자에서는 그래픽 관련 설정을 초기화합니다.
    	SceneManager(shared_ptr<Graphics> graphics);
    
    	// 초기화 함수, 현재 활성화된 장면을 초기화합니다.
    	void Init();
    	// 업데이트 함수, 현재 활성화된 장면을 업데이트합니다.
    	void Update();
    	// 새로운 장면을 로드하는 함수, 장면 이름을 기반으로 장면을 로드합니다.
    	void LoadScene(wstring sceneName);
    
    public:
    	// 현재 활성화된 장면을 가져오는 함수
    	shared_ptr<Scene> GetActiveScene() { return _activeScene; }
    
    private:
    	// 테스트 장면을 로드하는 내부 함수, 여기서 장면 설정을 진행합니다.
    	shared_ptr<Scene> LoadTestScene();
    
    private:
    	shared_ptr<Graphics> _graphics; // 그래픽스 관련 설정을 저장하는 변수
    
    private:
    	shared_ptr<Scene> _activeScene; // 현재 활성화된 장면
    };
    #include "pch.h" // 사전 컴파일된 헤더 포함
    #include "SceneManager.h" // SceneManager 클래스 헤더 포함
    #include "Scene.h" // Scene 클래스 헤더 포함
    #include "GameObject.h" // GameObject 클래스 헤더 포함
    #include "Camera.h" // Camera 클래스 헤더 포함
    #include "MeshRenderer.h" // MeshRenderer 클래스 헤더 포함
    #include "ResourceManager.h" // ResourceManager 클래스 헤더 포함
    #include "Game.h" // Game 클래스 헤더 포함
    #include "Mesh.h" // Mesh 클래스 헤더 포함
    #include "Animator.h" // Animator 클래스 헤더 포함
    
    // SceneManager 클래스의 생성자입니다. Graphics 객체를 인자로 받아 멤버 변수를 초기화합니다.
    SceneManager::SceneManager(shared_ptr<Graphics> graphics) : _graphics(graphics)
    {
    }
    
    // 초기화 함수입니다. 활성화된 장면이 없으면 함수를 종료합니다.
    // 활성화된 장면이 있으면, 해당 장면의 Awake와 Start 함수를 호출합니다.
    void SceneManager::Init()
    {
    	if (_activeScene == nullptr) {
    		return;
    	}
    
    	_activeScene->Awake();
    	_activeScene->Start();
    }
    
    // 매 프레임마다 호출되는 업데이트 함수입니다.
    // 활성화된 장면이 없으면 함수를 종료합니다.
    // 활성화된 장면이 있으면, 해당 장면의 FixedUpdate, Update, LateUpdate 함수를 차례로 호출합니다.
    void SceneManager::Update()
    {
    	if (_activeScene == nullptr) {
    		return;
    	}
    
    	_activeScene->FixedUpdate();
    	_activeScene->Update();
    	_activeScene->LateUpdate();
    }
    
    // 새로운 장면을 로드하는 함수입니다. 장면 이름을 인자로 받습니다.
    // 여기서는 장면 이름을 사용하지 않고, 단순히 LoadTestScene 함수를 호출하여 테스트 장면을 로드합니다.
    void SceneManager::LoadScene(wstring sceneName)
    {
    	// 장면 리소스 관련 로직은 여기에 구현될 수 있습니다.
    
    	_activeScene = LoadTestScene(); // 테스트 장면을 로드합니다.
    	Init(); // 로드된 장면을 초기화합니다.
    }
    
    // 테스트 장면을 로드하는 내부 함수입니다.
    // 실제 게임에서는 다양한 장면을 로드하기 위해 이 함수를 수정하거나 다른 함수를 추가할 수 있습니다.
    shared_ptr<Scene> SceneManager::LoadTestScene()
    {
    	shared_ptr<Scene> scene = make_shared<Scene>(); // 새로운 Scene 객체를 생성합니다.
    
    	// 카메라 객체를 생성하고 장면에 추가하는 코드 블록입니다.
    	{
    		shared_ptr<GameObject> camera = make_shared<GameObject>(_graphics->GetDevice(), _graphics->GetDeviceContext());
    		{
    			camera->GetOrAddTransform(); // 카메라의 Transform 컴포넌트를 추가합니다.
    			camera->AddComponent(make_shared<Camera>()); // 카메라 컴포넌트를 추가합니다.
    			scene->AddGameObject(camera); // 생성된 카메라 객체를 장면에 추가합니다.
    		}
    	}
    
    	// 몬스터 객체를 생성하고 장면에 추가하는 코드 블록입니다.
    		// 아래에는 몬스터 객체를 두 번 생성하는 예시가 있습니다. 실제 게임에서는 다양한 종류의 객체를 생성할 수 있습니다.
    	{
    		shared_ptr<GameObject> monster = make_shared<GameObject>(_graphics->GetDevice(), _graphics->GetDeviceContext());
    		monster->GetOrAddTransform()->SetWorldPosition(Vec3{ 2.0f,2.0f,0 }); // 몬스터의 위치를 설정합니다.
    		{
    			monster->GetOrAddTransform(); // 몬스터의 Transform 컴포넌트를 추가합니다.
    			auto meshRenderer = make_shared<MeshRenderer>(_graphics->GetDevice(), _graphics->GetDeviceContext());
    			monster->AddComponent(meshRenderer); // MeshRenderer 컴포넌트를 추가합니다.
    		}
    		scene->AddGameObject(monster); // 생성된 몬스터 객체를 장면에 추가합니다.
    	}
    
    	return scene; // 설정이 완료된 장면 객체를 반환합니다.
    }

    결론

    MeshRenderer와 SceneManager를 사용하여 게임 오브젝트마다 리소스를 그리는 작업을 나누고, Scene을 통해 게임의 다양한 장면을 효율적으로 관리하는 구조는 게임 개발에서 매우 중요합니다. 이러한 구조는 게임의 성능 최적화와 유지 보수성 향상에 기여하며, 개발자가 보다 복잡한 게임 로직과 장면 전환을 쉽게 구현할 수 있게 합니다.

     

     

     

    반응형
    다음글
    다음 글이 없습니다.
    이전글
    이전 글이 없습니다.
    댓글
조회된 결과가 없습니다.
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
목차
표시할 목차가 없습니다.
    • 안녕하세요
    • 감사해요
    • 잘있어요

    티스토리툴바