OpenGL ES 2.0에서 Direct3D로의 포팅 계획

중요 API

iOS 또는 Android 플랫폼에서 게임을 포팅하는 경우 OpenGL ES 2.0에 상당한 투자를 했을 수 있습니다. 그래픽 파이프라인 코드베이스를 Direct3D 11 및 Windows 런타임으로 이동할 준비를 할 때 시작하기 전 몇 가지 사항을 고려해야 합니다.

대부분의 포팅 작업은 일반적으로 처음에 코드베이스를 탐색하고 두 모델 간에 일반적인 API와 패턴을 매핑하는 것과 관련이 있습니다. 시간을 들여 이 항목을 읽고 검토하면 이 프로세스가 좀 더 쉬워질 수 있습니다.

다음은 OpenGL ES 2.0에서 Direct3D 11로 그래픽을 포팅할 때 알아야 할 몇 가지 사항입니다.

특정 OpenGL ES 2.0 공급자에 대한 참고 사항

이 섹션의 포팅 항목은 Khronos 그룹에서 만든 OpenGL ES 2.0 사양의 Windows 구현을 참조합니다. 모든 OpenGL ES 2.0 코드 샘플은 Visual Studio 2012 및 기본 Windows C 구문을 사용하여 개발되었습니다. Objective-C(iOS) 또는 Java(Android) 코드베이스에서 제공되는 경우 제공된 OpenGL ES 2.0 코드 샘플에서 유사한 API 호출 구문 또는 매개 변수를 사용하지 않을 수 있습니다. 이 지침은 플랫폼에 관계없이 가능한 한 유지하려고 합니다.

이 설명서는 OpenGL ES 코드 및 참조에 2.0 사양 API만 사용합니다. OpenGL ES 1.1 또는 3.0에서 포팅하는 경우 일부 OpenGL ES 2.0 코드 예제 및 컨텍스트가 익숙하지 않을 수 있지만 이 콘텐츠는 여전히 유용할 수 있습니다.

이 항목의 Direct3D 11 샘플은 CX(구성 요소 확장)와 함께 Microsoft Windows C++를 사용합니다. 이 버전의 C++ 구문에 대한 자세한 내용은 Visual C++, 런타임 플랫폼용 구성 요소 확장빠른 참조(C++\CX)를 읽어 보세요.

하드웨어 요구 사항 및 리소스 이해

OpenGL ES 2.0에서 지원하는 그래픽 처리 기능 집합은 Direct3D 9.1에서 제공하는 기능에 대략적으로 매핑됩니다. Direct3D 11에서 제공하는 고급 기능을 활용하려면 포트를 계획할 때 Direct3D 11 설명서를 검토하거나 초기 작업을 완료하면 DirectX 9에서 UWP(유니버설 Windows 플랫폼) 항목으로 포트를 검토합니다.

초기 포팅 작업을 간단하게 하려면 Visual Studio Direct3D 템플릿으로 시작합니다. 이미 구성된 기본 렌더러를 제공하고 창 변경 내용 및 Direct3D 기능 수준에서 리소스를 다시 만드는 것과 같은 UWP 앱 기능을 지원합니다.

Direct3D 기능 수준 이해

Direct3D 11은 11_1용 9_1(Direct3D 9.1)의 하드웨어 "기능 수준"에 대한 지원을 제공합니다. 이러한 기능 수준은 특정 그래픽 기능 및 리소스의 가용성을 나타냅니다. 일반적으로 대부분의 OpenGL ES 2.0 플랫폼은 Direct3D 9.1(기능 수준 9_1) 기능 집합을 지원합니다.

DirectX 그래픽 기능 및 API 검토

API 제품군 설명
DXGI DXGI(DirectX Graphics Infrastructure)는 그래픽 하드웨어와 Direct3D 간의 인터페이스를 제공합니다. IDXGIAdapterIDXGIDevice1 COM 인터페이스를 사용하여 디바이스 어댑터 및 하드웨어 구성을 설정합니다. 버퍼 및 기타 창 리소스를 만들고 구성하는 데 사용합니다. 특히, 스왑 체인(프레임 버퍼 집합)을 포함하여 그래픽 리소스를 획득하는 데 사용되는 IDXGIFactory2 팩터리 패턴 IIS입니다. DXGI는 스왑 체인을 소유하므로 IDXGISwapChain1 인터페이스를 사용하여 화면에 프레임을 표시합니다.
Direct3D Direct3D는 그래픽 인터페이스의 가상 표현을 제공하고 이를 사용하여 그래픽을 그릴 수 있도록 하는 API 집합입니다. 버전 11은 OpenGL 4.3과 기능 면에서 거의 비슷합니다. (반면 OpenGL ES 2.0은 기능별 DirectX9 및 OpenGL 2.0과 유사하지만 OpenGL 3.0의 통합 셰이더 파이프라인을 사용합니다.) 대부분의 어려운 작업은 각각 개별 리소스 및 하위 리소스 및 렌더링 컨텍스트에 대한 액세스를 제공하는 ID3D11Device1 및 ID3D11DeviceContext1 인터페이스를 사용하여 수행됩니다.
Direct2D Direct2D는 GPU 가속 2D 렌더링을 위한 API 집합을 제공합니다. OpenVG와 유사한 용도로 간주할 수 있습니다.
DirectWrite DirectWrite는 GPU 가속 고품질 글꼴 렌더링을 위한 API 집합을 제공합니다.
DirectXMath DirectXMath는 일반적인 선형 대수 및 삼각 형식, 값 및 함수를 처리하기 위한 API 및 매크로 집합을 제공합니다. 이러한 형식 및 함수는 Direct3D 및 셰이더 작업에서 잘 작동하도록 설계되었습니다.
DirectX HLSL Direct3D 셰이더에서 사용하는 현재 HLSL 구문입니다. Direct3D 셰이더 모델 5.0을 구현합니다.

 

Windows 런타임 API 및 템플릿 라이브러리 검토

Windows 런타임 API는 UWP 앱에 대한 전체 인프라를 제공합니다. 여기에서 검토할 수 있습니다.

그래픽 파이프라인을 포팅하는 데 사용되는 주요 Windows 런타임 API는 다음과 같습니다.

또한, WRL(Windows 런타임 C++ 템플릿 라이브러리)은 Windows 런타임 구성 요소를 만들고 사용하기 위한 간단한 방법을 제공하는 템플릿 라이브러리입니다. UWP 앱용 Direct3D 11 API는 스마트 포인터(ComPtr)와 같이 이 라이브러리의 인터페이스 및 형식과 함께 사용하는 것이 가장 좋습니다. WRL에 대한 자세한 내용은 Windows 런타임 C++ 템플릿 라이브러리(WRL)를 참조하세요.

좌표계 변경

초기 포트 작업에서 종종 혼동하는 한 가지 차이점은 OpenGL의 기존 오른손 좌표계에서 Direct3D의 기본 왼손 좌표계로 변경된 것입니다. 이러한 좌표 모델링 변경은 꼭짓점 버퍼의 설정 및 구성에서부터 많은 행렬 수학 함수에 이르기까지 게임의 많은 부분에 영향을 줍니다. 가장 중요한 두 가지 변경 사항은 다음과 같습니다.

  • Direct3D가 앞쪽에서부터 시계 방향으로 트래버스하도록 삼각형 꼭짓점의 순서를 대칭 이동합니다. 예를 들어 꼭짓점이 OpenGL 파이프라인에서 0, 1 및 2로 인덱싱되는 경우 대신 Direct3D에 0, 2, 1로 전달합니다.
  • 뷰 행렬을 사용하여 z 방향에서 세계 공간의 크기를 -1.0f로 조정하여 z축 좌표를 효과적으로 반전합니다. 이렇게 하려면 뷰 행렬에서 M31, M32 및 M33 위치에 있는 값의 기호를 대칭 이동합니다(행렬 형식으로 포팅할 때). M34가 0이 아니면 기호도 대칭 이동합니다.

그러나 Direct3D는 오른손 좌표계를 지원할 수 있습니다. DirectXMath는 왼손 좌표계와 오른손 좌표계 모두에서 작동하는 다양한 함수를 제공합니다. 원래 메시 데이터 및 행렬 처리 중 일부를 보존하는 데 사용할 수 있습니다. 다음이 포함됩니다.

DirectXMath 행렬 함수 설명
XMMatrixLookAtLH 카메라 위치, 위쪽 방향 및 초점을 사용하여 왼손 좌표계에 대한 뷰 매트릭스를 작성합니다.
XMMatrixLookAtRH 카메라 위치, 위쪽 방향 및 초점을 사용하여 오른손 좌표계에 대한 뷰 매트릭스를 작성합니다.
XMMatrixLookToLH 카메라 위치, 위쪽 방향 및 카메라 방향을 사용하여 왼손 좌표계에 대한 뷰 매트릭스를 작성합니다.
XMMatrixLookToRH 카메라 위치, 위쪽 방향 및 카메라 방향을 사용하여 오른손 좌표계에 대한 뷰 매트릭스를 작성합니다.
XMMatrixOrthographicLH 왼손 좌표계에 대한 직교적 프로젝션 행렬을 작성합니다.
XMMatrixOrthographicOffCenterLH 왼손 좌표계에 대한 사용자 지정 직교적 프로젝션 행렬을 작성합니다.
XMMatrixOrthographicOffCenterRH 오른손 좌표계에 대한 사용자 지정 직교적 프로젝션 행렬을 작성합니다.
XMMatrixOrthographicRH 오른손 좌표계에 대한 직교적 프로젝션 행렬을 작성합니다.
XMMatrixPerspectiveFovLH 뷰 필드를 기반으로 왼손 원근 투영 행렬을 작성합니다.
XMMatrixPerspectiveFovRH 뷰 필드를 기반으로 오른손 원근 투영 행렬을 작성합니다.
XMMatrixPerspectiveLH 왼손 원근 투영 행렬을 작성합니다.
XMMatrixPerspectiveOffCenterLH 왼손 원근 투영 행렬의 사용자 지정 버전을 빌드합니다.
XMMatrixPerspectiveOffCenterRH 오른손 원근 투영 행렬의 사용자 지정 버전을 빌드합니다.
XMMatrixPerspectiveRH 오른손 원근 투영 행렬을 작성합니다.

 

OpenGL ES2.0-to-Direct3D 11 포팅 질문과 대답

  • 질문: "일반적으로 OpenGL 코드에서 특정 문자열이나 패턴을 검색하여 Direct3D와 상응하는 것으로 대체할 수 있나요?"
  • 대답: 아니요. OpenGL ES 2.0 및 Direct3D 11은 다양한 세대의 그래픽 파이프라인 모델링에서 제공됩니다. 렌더링 컨텍스트 및 셰이더 인스턴스화와 같은 개념과 API 간에는 몇 가지 표면 유사성이 있지만 1 대 1 매핑을 시도하는 대신 파이프라인을 다시 만들 때 최상의 선택을 할 수 있도록 이 지침과 Direct3D 11 참조를 검토해야 합니다. 그러나 GLSL에서 HLSL로 포팅하는 경우 GLSL 변수, 내장 함수 및 일반 함수에 대한 일반적인 별칭 세트를 만들면 포팅이 더 쉬워질 뿐만 아니라 셰이더 코드 파일 세트 하나만으로도 유지 관리할 수 있습니다.