Plan your port from OpenGL ES 2.0 to Direct3D
If you are porting a game from the iOS or Android platforms, you have probably made a significant investment in OpenGL ES 2.0. When preparing to move your graphics pipeline codebase to Direct3D 11 and the Windows Runtime, there are a few things you should consider before you start.
Most porting efforts usually involving initially walking the codebase and mapping common APIs and patterns between the two models. You'll find this process a bit easier if you take some time to read and review this topic.
Here are some things to be aware of when porting graphics from OpenGL ES 2.0 to Direct3D 11.
The porting topics in this section reference the Windows implementation of the OpenGL ES 2.0 specification created by the Khronos Group. All OpenGL ES 2.0 code samples were developed using Visual Studio 2012 and basic Windows C syntax. If you are coming from an Objective-C (iOS) or Java (Android) codebase, be aware that the provided OpenGL ES 2.0 code samples may not use similar API calling syntax or parameters. This guidance tries to stay as platform agnostic as possible.
This documentation only uses the 2.0 specification APIs for the OpenGL ES code and reference. If you are porting from OpenGL ES 1.1 or 3.0, this content can still prove useful, although some of the OpenGL ES 2.0 code examples and context may be unfamiliar.
The Direct3D 11 samples in these topics use Microsoft Windows C++ with Component Extensions (CX). For more info on this version of the C++ syntax, read Visual C++, Component Extensions for Runtime Platforms, and Quick Reference (C++\CX).
The set of graphics processing features supported by OpenGL ES 2.0 roughly maps to the features provided in Direct3D 9.1. If you want to take advantage of the more advanced features provided in Direct3D 11, review the Direct3D 11 documentation when planning your port, or review the Port from DirectX 9 to Windows Store topics when you're done with the initial effort.
To make your initial porting effort simple, start with a Visual Studio Direct3D template. It provides a basic renderer already configured for you, and supports Windows Store app features like recreating resources on window changes and Direct3D feature levels.
Direct3D 11 provides support for hardware "feature levels" from 9_1 (Direct3D 9.1) for 11_1. These feature levels indicate the availability of certain graphics features and resources. Typically, most OpenGL ES 2.0 platforms support a Direct3D 9.1 (feature level 9_1) set of features.
Also, because Windows RT devices are not required to support feature levels higher than 9_1, Direct3D apps that target the Windows RT architecture must target feature level 9_1. To reach the largest audience, target the 9_1 feature set for your games and apps as a baseline for all CPU architectures. If you intend to take advantage of higher level features in your port, target 11_1.
For more information on Direct3D feature levels, read Developing for different Direct3D feature levels.
|DXGI||The DirectX Graphics Infrastructure (DXGI) provides an interface between the graphics hardware and Direct3D. It sets the device adapter and hardware configuration using the IDXGIAdapter and IDXGIDevice1 COM interfaces. Use it to create and configure your buffers and other window resources. Notably, the IDXGIFactory2 factory pattern iis used to acquire the graphics resources, including the swap chain (a set of frame buffers). Since DXGI owns the swap chain, the IDXGISwapChain1 interface is used to present frames to the screen.|
|Direct3D||Direct3D is the set of APIs that provide a virtual representation of the graphics interface and allow you to draw graphics using it. The current version is 11, which shipped with Windows 8. It is roughly comparable, feature-wise, to OpenGL 4.3. (OpenGL ES 2.0, on the other hand, is similar to DirectX9, feature-wise, and OpenGL 2.0, but with OpenGL 3.0's unified shader pipeline.) Most of the heavy lifting is done with the ID3D11Device1 and ID3D11DeviceContext1 interfaces which provide access to individual resources and subresources, and the rendering context, respectively.|
|Direct2D||Direct2D provides a set of APIs for GPU-accelerated 2D rendering. It can be considered similar in purpose to OpenVG.|
|DirectWrite||DirectWrite provides a set of APIs for GPU-accelerated, high-quality font rendering.|
|DirectXMath||DirectXMath provides a set of APIs and macros for handling common linear algebra and trigonometric types, values, and functions. These types and functions are designed to work well with Direct3D and its shader operations.|
|DirectX HLSL||The current HLSL syntax used by Direct3D shaders. It implements Direct3D Shader Model 5.0.|
The Windows Runtime APIs provide the overall infrastructure for Windows Store apps. Review them here.
Key Windows Runtime APIs used in porting your graphics pipeline include:
Additionally, the Windows Runtime C++ Template Library (WRL) is a template library that provides a low-level way to author and use Windows Runtime components. The Direct3D 11 APIs for Windows Store apps are best used in conjunctions with the interfaces and types in this library, such as smart pointers (ComPtr). For more info on the WRL, read Windows Runtime C++ Template Library (WRL).
One difference that sometimes confuses early port efforts is the change from OpenGL's traditional right-handed coordinate system to Direct3D's default left-handed coordinate system. This change in coordinate modeling affects many parts of your game, from the setup and configuration of your vertex buffers to many of your matrix math functions. The two most important changes to make are:
- Flip the order of triangle vertices so that Direct3D traverses them clockwise from the front. For example, if your vertices are indexed as 0, 1, and 2 in your OpenGL pipeline, pass them to Direct3D as 0, 2, 1 instead.
- Use the view matrix to scale world space by -1.0f in the z direction, effectively reversing the z-axis coordinates. To do this, flip the sign of the values at positions M31, M32, and M33 in your view matrix (when porting it to the Matrix type). If M34 is not 0, flip its sign as well.
However, Direct3D can support a right-handed coordinate system. DirectXMath provides a number of functions that operate on and across both left-handed and right-handed coordinate systems. They can be used to preserve some of your original mesh data and matrix processing. They include:
|DirectXMath matrix function||Description|
|XMMatrixLookAtLH||Builds a view matrix for a left-handed coordinate system using a camera position, an up direction, and a focal point.|
|XMMatrixLookAtRH||Builds a view matrix for a right-handed coordinate system using a camera position, an up direction, and a focal point.|
|XMMatrixLookToLH||Builds a view matrix for a left-handed coordinate system using a camera position, an up direction, and a camera direction.|
|XMMatrixLookToRH||Builds a view matrix for a right-handed coordinate system using a camera position, an up direction, and a camera direction.|
|XMMatrixOrthographicLH||Builds an orthogonal projection matrix for a left-handed coordinate system.|
|XMMatrixOrthographicOffCenterLH||Builds a custom orthogonal projection matrix for a left-handed coordinate system.|
|XMMatrixOrthographicOffCenterRH||Builds a custom orthogonal projection matrix for a right-handed coordinate system.|
|XMMatrixOrthographicRH||Builds an orthogonal projection matrix for a right-handed coordinate system.|
|XMMatrixPerspectiveFovLH||Builds a left-handed perspective projection matrix based on a field of view.|
|XMMatrixPerspectiveFovRH||Builds a right-handed perspective projection matrix based on a field of view.|
|XMMatrixPerspectiveLH||Builds a left-handed perspective projection matrix.|
|XMMatrixPerspectiveOffCenterLH||Builds a custom version of a left-handed perspective projection matrix.|
|XMMatrixPerspectiveOffCenterRH||Builds a custom version of a right-handed perspective projection matrix.|
|XMMatrixPerspectiveRH||Builds a right-handed perspective projection matrix.|
- Question: "In general, can I search for certain strings or patterns in my OpenGL code and replace them with the Direct3D equivalents?"
- Answer: No. OpenGL ES 2.0 and Direct3D 11 come from different generations of graphics pipeline modeling. While there are some surface similarities between concepts and APIs, such as the rendering context and the instancing of shaders, you should review this guidance as well as the Direct3D 11 reference so you can make the best choices when recreating your pipeline instead of attempting a 1-to-1 mapping. However, if you are porting from GLSL to HLSL, creating a set of common aliases for GLSL variables, intrinsincs, and functions can not only make porting easier, it allows you to maintain only one set of shader code files.