컴퓨터 프로그래밍 공부

런타임 게임 아키텍처

게임 개발 2023. 11. 18. 00:01

 

아키텍처란?

아키텍처란 간단히 말해, 
하나의 서비스가 어떻게 구성되며 어떻게 작동된다라는 것을 표현한 것이다.
주로 시스템 구성 및 동작 원리와 구성 요소 간의 관계 및 시스템 외부 환경과의 관계를 묘사한다.
 

 
 

런타임 게임  아키텍처

게임 엔진은 크게 제작 도구와 런타임 구성 요소로 나뉜다.
먼저, 런타임 구성 요소를 살펴보고 제작 도구에 관해 살펴보겠다.
 
게임 엔진은 그 자체로 거대한 소프트웨어 시스템이라 할 수 있다.
여타 소프트웨어와 마찬가지로 게임 엔진도 계층적으로 구성된다.
상위 계층은 하위 계층에 의존하지만 그 반대는 아니다.
하위 계층이 상위 계층에 의존할 때 '순환 의존(circular dependency)'라고 한다.
선형 의존(순환 의존)은 시스템 간의 불필요한 결합을 생기게 하고, 
테스트를 어렵게 만들며 재사용을 저해하기 때문에 어떤 소프트웨어라도 피해야 한다.
특히 게임 엔진처럼 규모가 큰 소프트웨어에서는 더욱이 그렇다.
 

전체 시스템 안에서 런타임 아키텍처를 추상화한 것이다.

 

목표 하드웨어 계층은 게임이 동작할 컴퓨터나 콘솔 시스템을 뜻하며,
여기에는 마이크로 소프트 윈도우, 리눅스, 맥 os 등의 PC, 안드로이드 폰 등이 있다.
 

그 위에 존재하는 디바이스 드라이버는
운영체제나 하드웨어 제조사에서 제공하는 로우레벨 구성 요소이다.
하드웨어를 관리하고 운영체제나 다른 상위 계층 소프트웨어에서
불필요한 하드웨어 요인들을 신경 쓰지 않게 하는 역할을 한다.
 

운영체제 없이 PC는 작동할 수 없다.
운영체제는 게임과 같은 어플리케이션들을 조율하는 역할을 한다.
 

1.6.4 서드파티 SDK와 미들웨어

대부분의 게임 엔진은 다양한 서브파티 소프트웨어 개발 도구(SDK, Software Development Kit)와
미들웨어(middleware)를 적극 이용한다.
SDK가 제공하는 함수 또는
클래스 형태의 인터페이스를 애플리케이션 프로그래밍 인터페이스라고 한다.
몇 가지 예를 들어보아 살펴보면,
 

1.6.4.1 자료 구조와 알고리듬

 
 여타 소프트웨어와 마찬가지로 게임 엔진도 여러 가지 자료 구조와 알고리듬을 많이 사용한다.
다음은 이런 기능을 제공하는 외부 라이브러리를 몇 가지 들어본 것이다.
 

  • Boost : 부스트는 뛰어난 자료 구조 및 알고리듬 라이브러리이며
    C++ 라이브러리와 그 전신인 표준 템플릿 라이버리리의 디자인 스타일과 유사하다.
  • Folly : 폴리는 페이스북에서 쓰는 라이브러리이며,
    표준 C++ 라이브러리와 부스트의 여러 가지 유용한 기능을 더함으로써 확장하는 것을 목표로 하며,
    이 과정에서 코드 퍼포먼스 향상을 주안점으로 삼는다.
  • Loki : 로키는 매우 강력한 제너릭 프로그래밍 템플릿 라이브러리이며,
    아주 복잡하다.

 
 
++ Plus ++

제네릭(generic)

우리가 만든 코드(code)가 특정 인터페이스나 클래스가 아닌
"어떤 미지정 타입" 과 동작 할 수 있도록 더욱 일반화된 코드를 작성하기 위해 나타난 개념이다.
파라미터화 타입(parameterized type)의 개념,
다수의 타입을 허용. 파리미터화 타입의 인스턴스를 생성하면 캐스팅이 이루어질 것이고,
타입이 정확한지 컴파일 시점에서 확인된다.

타입 파라미터란?

나중에 결정될 수 있는 미지정 타입.
클래스명 다음에 꺽쇠 괄호 "<>"를 붙여서 그 안에 타입 파라미터를 넣는다.

컨테이너란?

컨테이너는 우리가 사용하는 객체를 저장하는 곳으로서 
비슷한 배열이 있지만 이에 비해 더욱 유연하며 
다른 특성들을 갖기 때문에 객체 저장등에 많이 쓰이는 클래스 라이브러리이다.
 
++
 

 그래픽스는 게임 렌더링 엔진 내에 다음과 같은 하드웨어 인터페이스 라이브러리 위에 작동된다.
글라이드(SDK), OpenGL, DirectX, Edge, Vulkan 등이 있다.
충돌 감지와 강체 역학 등 물리 기능을 제공하는 SDK는 다음과 같은
Havok, PhysX, ODE 등의 것들이 있다.
 
이 외에도 메모리 관리 측면도 중요하며,
독자적 자료 구조와 알고리듬 또한 아키텍처를 구성하는 핵심 요소이다.
자원 관리자 기능으로는 게임 애셋을 관리한다.
 
게임 엔진 아키텍처를 구성하는데에는 많은 구성요소가 있지만,
렌더링 엔진은 게임 엔진에서 제일 복잡하고 광범위한 요소 중 하나이다.
렌더링 엔진에 대하여 더 자세히 알아봐보자.
 

1.6.8 렌더링 엔진

 
렌더링 엔진의 설계 방식은 굉장히 다앙하며,
표준적 설계 방식이 있는 것은 아니지만,
대부분의 렌더링 엔진은 3D 하드웨어의 특성에서 기인한 몇 가지 근본적인 디자인 철학을 공유한다.
 
 

1.6.8.1 로우레벨 렌더러

 
로우레벨 렌더러는 렌더링 엔진에서 가장 기초적인 부분이다.
기하학적 기본 단위를 가능한 빠르게 그리면서 다양한 방식을 지원하는 데 중점을 두며,
화면의 가시성 등 좀 더 추상적인 문제에는 관여하지 않는다.
 

 
 

 

그래픽 디바이스 인터페이스
 
DX나 OpenGL 또는 Vulkan 같은 그래픽 SDK를 사용할 때
그래픽 하드웨어를 찾아내고,
초기화나 후 렌더 표면( 후면 버퍼, 스텐실 버퍼 등)을 설정하는 것과 같은
간단한 일을 하는 데도 상당히 긴 코드를 짜야 한다.
엔진마다 서로 다르게 부르긴 하지만 이런 역할을 담당하는 부분을
해당 책에서는 그래픽 디바이스 인터페이스라고 부르기도 한다
초기화한 후 렌더 표면(후면 버퍼, 스텐실 버퍼 등을) 설정하는 것과 같은 간단한 일을 하는 데도
상당히 긴 코드를 작성해야한다.
엔진 마다 서로 다르게 부르기는 하지만, 이런 역할을 담당하는 부분을 해당 책에서는
그래픽 디바이스 인터페이스라고 부른다.
PC용 게임 엔진을 만들 때는 렌더러를 윈도우의 메시지 루프와 어떻게 해서든 연결해야 한다.
대개 메시지 펌프를 써서 윈도우 메시지가 도착하면 처리를 하고 나머지 시간에는 가능한 빨리
렌더러의 루프를 돌리는 방법을 쓴다.
이 방법의 단점은 키보드 메시지를 처리하는 루프와 스크린을 업데이트하는 렌더러 루프 사이에
의존성이 생긴다는 점이다.
간단하지는 않지만 의존성을 줄일 수 있는 방법이 없지는 않다.
 
 
장면 그래프와 추려내기 최적화

 

 
게임월드가 굉장히 작다면 단순한 절두체 추려내기 정도로 충분하다.
(= 카메라가 볼 수 없는 물체를 그리지 않는 방식)
하지만 큰 월드 게임(ex 오픈월드)에서는 좀 더 고급 공간 분할 방식을 사용한다.

이러한 방식은 게임 객체들 중에 보일 가능성이 있는 집합(PVS Potentially Visible Set)을 빨리 찾아내 
렌더링 성능을 향상시키기 위해서이다.
이러한 공간 분할을 장면 그래프라고도 부르고,
엄밀히 따지면 일종의 자료구조이다.
 
 
 
이 외에도 충돌과 물리, 애니메이션, 온라인 멀티플레이어와 네트워킹 등이 있다.
 

'컴퓨터 프로그래밍 공부' 카테고리의 다른 글

데이터베이스 트리거  (0) 2023.06.20
Yaw, Roll, Pitch  (0) 2023.04.20
CPU와 메모리  (0) 2023.03.27
정리 230319  (0) 2023.03.19
행렬  (0) 2023.03.02