일단 만들다만 Input 클래스에 Mouse Position Event를 추가해 주었다.
대충 사양서 비스무리한 걸 적어보자.
Scene 클래스에 GameObject들이 있음.
Scene의 Update()를 호출하면 렌더링 작업까지 싹다 진행가능.
렌더링 작업은 GameObject가 가진 Component 중 Transform 컴포넌트와 MeshRenderer 컴포넌트를 활용.
구체적으로 어떤 식으로 활용하는 가?
Transform 컴포넌트는 오브젝트의 position, rotation, scale을 저장함. 그 외에 특이사항은 없다.
MeshRenderer가 하는 일은 우선 다음과 같다.
Mesh 정보를 가지고 있음.
vertex shader, pixel shader를 가지고 있음 (추후 Material로 대체할 예정) - 상수버퍼도 일단 같이 들고 있도록 함
MeshRenderer는 Transform에 있는 정보를 이용해 Transformation Matrix를 계산하고, Transpose 작업 후 Renderer에게 그려달라고 요청.
Renderer는 Mesh에게서 받은 정보들을 가지고 화면에 그려줌
후...어째 만드는 것 보다 생각하는 게 더 힘들다.
현재 App에 Window 안에 Graphics와 Input 객체가 있으며, Graphics 안에는 Renderer가 들어 있다. 이때 Scene 클래스를 만들고 Component에서 Input 객체와 Renderer 객체를 활용할 수 있도록 하기 위해서는 전역 변수를 활용해야 할 것 같다. Component는 무조건 기본 생성자만 가지고 있어야 AddComponent 등의 작업을 수행할 수 있기 때문이다.
Scene은 App에 하위로 갖고 있어야 할 것 같다. Scene에게 App에서 Input과 Graphics 정보를 넘겨주어야 Scene에서 자유자재로 이를 활용할 수 있게 될 것 같다.
계속해서 문제가 터져 나온다. 컴포넌트에서 생성자에 인수를 가질 수 없도록 해두어서 MeshRenderer가 직접 Graphics에 엑세스 하는 경우에도 gfx 정보가 있어야 하며, 그걸 생성 이후에 결정하는 것도 너무 이상하고, Component 베이스 클래스에 스태틱 변수로 집어넣는 것도 모양새가 이상하다. 게다가 static으로 필요한 녀석들의 포인터를 가져온다고 할 때, 이 녀석들이 실행도중 삭제가 되는 경우에는 어떡하라는 말인가? 꼬이고 꼬이고 있다. 대체 어떻게 처리를 해야할까?
설계를 다시 해볼 필요가 있다. 일단 위에서 언급한 문제중 한 가지는 해결할 수 있을 것 같다. COM 모델 자체가 AddComponent 등을 호출한다고 바로 그 객체를 할당해서 주는 게 아니라 내부에 객체를 만드는 Factory가 있어서 거기서 객체를 만들고, 만들어진 객체에 대한 참조나 인터페이스를 리턴해주는 식으로 수정을 해야할 것 같다.
그리고 필요한 객체를 static으로 만들어서 포인터를 갖고 오는 것도 너무 구린 설계다. Scene과 같은 객체가 있는 동안 Scene에서 사용하는 객체가 절대 파괴되지 않을 것을 보장받아야 한다. 그렇지 않으면 당장은 땜빵할 지 언정 언젠가 문제가 터지고 나서 멘붕에 빠질 지도 몰라.
그리고 unique_ptr을 너무 남용했다. unique_ptr을 사용하면 이 녀석의 참조를 위해서는 get() 메서드를 활용할 수 밖에 없는데, 그래서 해당 클래스 내부에 있는 객체를 외부로 전달하기 위해서는 포인터 형태로 전달해줄 수 밖에 없다. 외부에서 내가 delete를 할 일은 스마트 포인터만 믿고 아무것도 안하고 있긴 하지만 만약이라는 것이 있고, 객체가 이렇게 마구잡이로 참조되면 나중에 어떤 순서로 이 객체들이 파괴가 될 것인지 통제를 할 수가 없다. 그래서 weaked_ptr로 저장하고 shared_ptr을 보내주는 식으로 해야하지 않을까 하는 생각이 든다.
Factory 객체를 생성하다가 좋은 말이 생각나서 적어둔다.
이 클래스는 언제 생성되고 언제 파괴되는가?
헤더 파일을 만들고 이 질문에 대한 답변을 생각해야 클래스의 설계를 잘 할 수 있을 것 같다.
한번 지금까지 만든 객체들에 대해 이 질문을 해보자.
App : 프로그램 시작시 생성되며 이 클래스가 파괴되면 프로그램이 종료된다.
Window : App의 멤버이므로 App 생성자에서 생성되며, Window가 파괴되면 App도 종료되어야 한다.
Graphics : Window의 멤버로 화면에 뭔갈 그리기 위해서는 무조건 이 녀석이 필요함. 얘도 Window가 사라질 때 같이 사라짐.
Input : Window의 멤버로 Window에게 오는 메세지를 처리해야하기 때문에 Window가 사라지면 같이 사라짐.
그래, 여기 까진 괜찮다.
'진행과정 기록 > GameEngine' 카테고리의 다른 글
20200110 (0) | 2020.01.10 |
---|---|
20200109 (0) | 2020.01.09 |
20200107 (0) | 2020.01.07 |
20190106 삼각형 (0) | 2020.01.06 |
20200103 (0) | 2020.01.03 |