태그 : Nebula3

Nebula3 Render Layer : CoreGraphics

이 포스트는 floh님의 블로그에 포스팅된 Nebula3 관련 내용을번역한 글입니다. Nebula3는 Nebula2의 기본적인 아키텍쳐를 계승하지만 구현에서는 이전과 비교해 보면 여러 면에서 많이 다릅니다. 특히 세 개의 레이어로 구성되어 있는 점이 가장 큰 특징 중의 하나인데이것은 이전의 망갈로(Mangalore)가 게임엔진에 포함되었기 때문입니다. 그래서 이 세 개의 레이어에 대한 이해를 위해서 관련된 포스트들만 먼저 번역해서 올립니다.

Nebula3 Render Layer : CoreGraphics

http://flohofwoe.blogspot.com/2007/07/nebula3-render-layer-coregraphics.html

CoreGraphics
서브시스템은 호스트 렌더링 API의 래퍼이다. 기능이나 성능을 희생하지 않고 프로그래밍 가능한 쉐이더와 함께 Direct3D나 OpenGL를 지원하도록 설계되었다. CoreGraphics의 일반적인 기능은 Nebula2의 gfx2 서브시스템과 동일하다.그러나 Nebula2를 사용하면서 겪은 많은 문제점들을 해결하였다.

이전의 Nebula2에 비해서 많은 클래스들이 존재하기 때문에 복잡해 보일 수도 있다. 이렇게 한 이유는 CoreGraphics 클래스들은 보다 작으면서도 특화되어 있기 때문이다. 대부분 클래스들의 기능은 한 문장으로 정의할 수 있다. 반면에 Nebula2의  클래스- nGfxServer2와 같은 - 는 여러가지 일을 처리하기 때문에 다소 몇개의 클래스를 합해 놓은 큰 클래스였다.

전형적인 Nebula3 애플리케이션에서는 CoreGraphics를 다룰 필요가 거의 없다. 대신에 Graphics와 같은 상위 레벨의 서브시스템을 다루게 된다.

CoreGraphics의 중요한 디자인 목표는 다음과 같다.
  • 절충없이 Direct3D9, Direct3D10, XBbox360으로 포팅하는 것이 가능하다.
    • CoreGraphics는 Nebula2에서 사용한 가상함수를 이용해서 포팅하는 방법 대신에 조건에 따른 매크로(typedef)를 사용함으로써 다른 플랫폼으로 훨씬 수월하게 포팅할 수 있다. 포팅은 이를 위해 희생하거나 절충하는 것 없이 하나의 클래스 상속만으로 처리할 수있다. 심지어는 플랫폼에 의존적인 인라인 함수를 사용하는 것도 가능하다.
  • 향상된 리소스 관리
    • Nebula3에서는 리소스의 사용과 초기화가 디커플링 되었다. 초기화는 ResourceLoader 클래스를 통해서 처리함으로써 실제 리소스클래스의 코드는 훨씬 적으며 리소스 시스템은 더욱 모듈화 되었다. (왜 이것이 해결했어야 할 문제인지는 Nebula2의nTexture2 클래스를 참고)
  • (다수의 여러 클래스로)분리되어 있다.
    • nGfxServer2 클래스와 같은 하나의 큰 클래스 대신에 몇 개의 특화된 싱글레톤 클래스로 분리되어 있다.
      • RenderDevice : 렌더링 타겟으로 프리미티브 그룹을 렌더링하는 것을 처리한다.
      • DisplayDevice : 디스플레이 설정과 관리를 다룬다. (win32에서는 응용 프로그램 윈도우를 가지며, 윈도우즈 메시지 펌프를 실행한다. 또 풀스크린 화면에 대한 질의 등도 처리한다)
      • TransformDevice : 렌더링시 필요한 행렬 변환을 관리한다. 뷰, 프로젝션, 모델 행렬을 입력으로 ModelViewProjection, InvView 등의 연결된 행렬 연산 결과를 제공한다.
      • ShaderServer : 쉐이더 처리의 핵심. 아래를 참조할 것.
  • 향상된 오프스크린 렌더링
    • Nebula2에서는 백버퍼에 렌더링하도록 디자인 되었는데 이와 반대로 이제 오프스크린 렌더링 타겟에 렌더링하는 것이 보편화 되었다. 다소 불편하긴 하지만 백버퍼에 렌더링하는 것도 가능하다.
  • 쉐이더 시스템에 대한 중대한 향상
    • 수많은 오브젝트와 재질을 가지고 있는 전형적인 장면을 렌더링할 때 일어나는 쉐이더의 스위칭과 갱신에 따른 때 오버헤드를 감소할 수 있는 기반을 제공한다.
    • Nebula2에서처럼 쉐이더는 Direct3D의 이펙트 파일이다. ( 여러가지 pass로 구성된 technique의 집합이거나 렌더링 상태의 집합)
    • ShaderInstance는 자기 자신만의 쉐이더 파라미터 값을 가지는 복제된 이펙트이다.
    • ShaderVariable을 통해서 (DirectX10에서 하듯) 직접적으로(직관적으로?) 쉐이더 파라미터를 설정할수 있다.
    • ShaderVariations와 ShaderFeature 비트: A shader may offer different specialized variationswhich are selectedthrough a feature bit mask. 예를 들어 특징(??)은 "Depth", "Color", "Opaque","Translucent", "Skinned", "Unlit","PointLight"과 같은 이름을 가지고 쉐이더는 특징(??)에 대해서 "Depth | Skinned", "Color |Skinned | Unlit", "Color| Skinned | PointLight"와 같은 조합을 사용하는 특별한 변형을 제공할 수도 있다.. The high levelrendering code would setfeature bits as needed (during the depth pass, the Depth feature wouldbe switched on for instance), and depending on the current feature bitmask, the right specialized shader variation would automatically beselected for rendering. 적절한 에셋 툴과 함께ShaderVariations와 ShaderFeatures는 프로그래밍 가능한 쉐이더와 관련한 여러가지 유지 보수 문제나 실행시문제점들을 수정하는 것을 돕는다. (think shader-library vs. über-shaders and so on...).
gfx2와 비교했을 때 CoreGraphics 서브시스템은 다음과 같은 점에서도 작지만 향상이 있었다.
  • DeviceRestore/Lost, WinProc, 마우스, 키보드 메시지의 처리가 그래픽 시스템에 고정된 것이 아니라 일반적인 EventHandler를 사용하여 관리된다.
  • VertexBuffer와 IndexBuffer가 다시 공용 클래스로 제공된다.
  • 버텍스 컴포넌트가 Short2, Short4, UByte4N와 같은 압축된 형태로 제공된다.
  • DisplayDevice는 지원하는 렌더링 모드의 목록을 얻거나 현재 데스크탑 모드의 정보나 하드웨어, 벤더, 드라이버의 정보를 알아 내는데 유용한 몇 가지 메쏘드를 제공한다.
  • 윈도우를 오픈하기 전에 RenderDevice::CanCreate() 메쏘드를 통해 호스트 플랫폼에서 3D 렌더링이 가능한지 미리 검사해 볼 수 있다.
이 정도가 CoreGraphics 서브시스템에 대해서 알아야 내용이다. 다음에는 리소스, 모델, 그래픽스 서브시스템에 대한 내용이 이어진다.


by kimsama | 2009/02/05 10:53 | Nebula Device | 트랙백 | 핑백(1) | 덧글(0)

Nebula2와 Nebula3의 GameFramework의 차이점

The Brain Dump: Adding functionality to threaded subsystems으로부터 트랙백

Nebula3의 Feature과 프로퍼티


Nebula3에서는 프로퍼티(property) 시스템과 메시지들이 각각의 모듈에 종속되어 있다.

해당 모듈은 다음의 세 가지이다.

  • basegamefeature
  • graphicsfeature
  • physicsfeatue

basegamefeature에는 게임 엔티티와 관련한 내용들이, graphicsfeature 에는 렌더링과 관련한 내용들이 마지막으로 physicsfeature에는 충돌 및 이에 따른 물리 반응과 관련한 처리들이 포함된다.

예를 들어 MoveTo 메시지는 basegamefeature 시스템에 속해 있고, CameraFocus, SetAnimation 등의 메시지는 graphicsfeature 시스템에, 그리고 ApplyImpulseAtPos 메시지등은 physicsfeatue 시스템으로 각각 분리되어 속해 있는 것이 Nebula2와는 다른 점이다. (Nebula2에서는 모든 메시지는 msg 폴더 내에, 그리고 property 들은 properties 폴더 내에 위치해 있다)


Nebula3 멀티 쓰레드 시스템과 메시지 시스템

Nebula3의 멀티 코어 시스템이 메시지를 통해서 구현되는 점으로 미루어 보면 위의 세 시스템은 서로 각기 다른 코어를 사용하는 시스템으로 예상된다. 즉, ___feature 별로 하나의 코어를 사용하지 않을까 생각된다. 일반적으로 코어당 복수개의 쓰레드 사용이 가능한데 경우에 따라서는 이를 이용해서 시스템 내에서 다중 쓰레드를 사용하는 방법도 고려해 봄직하다. 예를 들어 graphicsfeature 시스템 내에서 렌더링 모듈과 그림자 모듈을 두 개의 쓰레도로 분리해서 처리하는 것이다.

예를 들어 디버깅 메시지 혹은 디버깅 객체(shape)를 렌더링하는 시스템을 살펴 보면 이를 두 개의 모듈로 구분해서 처리한다.

1) 디버깅 메시지나 디버깅 객체에 대한 정보를 처리하는 모듈
2) 이를 렌더링 하는 모듈

이 두개의 모듈은 별도의 쓰레드로 각각의 처리를 한다. 여기까지는 큰 문제가 없다. 그런데 두 개의 쓰레드로 구분하는 경우 두 쓰레드간의 동기화의 문제가 발생한다. 하나의 쓰레드로 처리할 때 처럼 sync가 맞아 떨어지면 아무런 문제가 없겠지만 그렇지 않은 경우에는 문제가 발생한다.

1) 디버깅 정보 처리를 하는 모듈 > 렌더링 모듈
이 경우에는 디버깅 정보에 대한 메시지를 프레임마다 렌더링 모듈 쪽으로 전달해 주지 못하므로 실제 화면에서의 디버깅 정보가 깜박이게 된다.

2) 디버깅 정보 처리를 하는 모듈 < 렌더링 모듈
디버깅 정보에 대한 메시지 처리는 한 프레임에 한번의 렌더링으로 족하지만 디버깅 정보 처리를 하는 모듈의 프레임 레이트가 렌더링 모듈보다 높은 경우 디버깅 정보 처리에 대한 메시지가 필요 이상으로 발생하게 되여 불필요한 디버깅 메시지의 렌더링으로 퍼포먼스 저하(overhead)가 발생한다. 디버겅 메시지 렌더링은 렌더링 한 프레임 당 한번만 처리하면 되는데도 말이다. 그러므로 디버깅 정보를 처리하는 모듈에서는 메시지를 바로 렌더링 모듈로 전송하지 말고 렌더링 모듈의 프레임을 고려해서 필요한 메시지를 한번만 전송하도록 처리해야 한다.


이상 두 가지의 문제점에 대한 해결이 Nebula3의 멀티 쓰레드와 메시지 시스템의 핵심이다.

메시지 시스템에 대해서 한 가지 덧붙이자면 이 메시지는 NIDL(Nebula Interface Define Language)로 정의된다는 것이다. 이것은 XML에 생성해야 할 메시지를 정의하면 컴파일러에서 빌드시 NIDL 툴(idl.exe라는 별도의 nebula3 in-house 툴이 있다)로 지정된 XML을 읽어 들여 메시지에 대한 소스 코드를 자동으로 생성하게 된다. 즉, 메시지는 손으로 코딩하는 것이 아니라 미리 정의된 형식을 통해서 XML에 정의하면 이를 NIDL 툴을 사용하여 자동으로 생성하는 방식을 사용한다.


by kimsama | 2008/09/22 23:11 | Nebula Croquis | 트랙백 | 핑백(1) | 덧글(0)

◀ 이전 페이지다음 페이지 ▶