Implementation of Directx 11 Rendering Engine in Nebula
Total Page:16
File Type:pdf, Size:1020Kb
DEGREE PROJECT Implementation of DirectX 11 Rendering Engine in Nebula Gustav Sterbrant Bachelor of Science in Engineering Technology Computer Game Programming Luleå University of Technology Department of Comuter Science, Electrical and Space Engineering Implementation of DirectX 11 rendering engine in the Nebula game engine Gustav Sterbrant gsCEPT Lule_aUniversity of Technology, Campus Skellefte_a May 19, 2012 1 Sammanfattning Denna uppsats beskriver hur man portar en renderingsmotor fr_anDirectX 9 till DirectX 10/11, och som samtidigt beskriver f¨ordelarnamed att uppgradera. Denna uppsats kommer g_aigenom den omfattande f¨or¨andringenmellan DirectX 9.0c till version 10, vilka f¨or¨andringarsom gjordes, och hur man anpassar sin ap- plikation s_aatt den utnyttjar alla nya funktioner. Senare kommer vi unders¨oka de nya funktionerna i DirectX 11 och hur de fungerar. I slut¨andankommer vi se hur en faktiskt spelmotor, mer exakt Nebula, kan designas om f¨oratt anv¨anda den nya DirectX standarden. Vi kommer ocks_abeskriva de nya Application Programming Interfaces, eller API:er, som kommit med DirectX 11. F¨orstkommer vi beskriva DirectX Graph- ics Infrastructure, f¨orkortat DXGI, som anv¨andsf¨orhantera adaptrar och ut- matningsenheter s_asomen datorsk¨arm. Vi kommer beskriva DirectWrite, och hur det kan anv¨andasi sammarbete med Direct2D f¨oratt rendera text. Vi kommer ¨aven beskriva shader model 5.0, vad som ¨arnytt fr_anshader model 3.0, samt hur man skriver en shader med den nya standarden. 2 Abstract This paper seeks to explain how to port an application rendering using Di- rectX 9, to DirectX 10/11 whilst at the same time explaining why this upgrade is preferable. This paper will discuss the extensive redesign of DirectX from version 9.0c to version 10, what changes were made, and how one has to re- design your own application to fully take advantage of the new features. Also, we will explore the new features in DirectX 11 and how they work. Later, we will see how an actual game engine, more precisely the Nebula game engine, is redesigned to fit the new DirectX standard. We will describe the new Application Programming Interfaces, or APIs, in- troduced with DirectX 11. We will introduce you to the DirectX Graphics Infrastructure, or DXGI, and explain how adapters are used in newer versions of DirectX to better handle variating hardware. We will investigate how Di- rectWrite is used together with Direct2D to render text. Also, we will go in depth to explain the new features in shader model 5.0, and how these can be used to improve the visual quality of your game. 1 Contents 1 Sammanfattning 1 2 Abstract 1 3 Introduction 4 4 Previous work 4 5 The DirectX 10 redesign 4 5.1 The DirectX Graphics Infrastructure . 4 5.2 Graphics data . 5 5.3 Shaders . 6 5.4 The assembly line . 6 6 The new features in DirectX 11 7 6.1 Hull shader . 7 6.2 Domain shader . 7 6.3 Compute shader . 8 6.4 Shader model 5.0 . 8 6.5 Multi-core CPU rendering . 9 7 Porting from DirectX 9 9 7.1 Device handling . 10 7.2 Buffers . 10 7.3 Textures . 10 7.4 Vertex declaration . 11 7.5 Shaders . 12 7.6 Text rendering . 14 8 Results 14 2 9 Discussion 14 10 Conclusion 16 References 20 3 3 Introduction With the development of games, also comes the need to develop the look of the game. The look of a game can be one of the major sales points, and thus, it comes natural that one might want to expand on what the game engine can manage. A new API doesn't automatically give the game better graphics, but the usage of new features enables the developers and the graphics artists to make games that look better. This paper will explain all the new features in DirectX 11, what has changed from DirectX 9 to 10, and how to port an actual game engine. 4 Previous work The Nebula game engine, developed by Radon Labs GmbH, uses the DirectX 9 rendering API. Also, they've constructed a sophisticated rendering engine to take advantage of the features found in DirectX 9, including a sophisticated and modular render path system. The DirectX 9 rendering code is also completely modular, and therefore easily replaceable with a newer one. Not only that have they implemented a shader system, where shader vari- ables are shared between effects. This shader system supports features such as deferred rendering and character skinning, to name a few. The shader system works in tight correlation with the render path to support writing render passes and setting up render pass variables using XML. 5 The DirectX 10 redesign When DirectX version 10 was developed, the developers decided to make a com- plete remake of the infrastructure of the DirectX rendering API. Even though this forced rendering engines to be rewritten to support DirectX 10, it also opened up for new features, and also produced a much more clean and manage- able rendering code. 5.1 The DirectX Graphics Infrastructure One major difference between DirectX 9 and 10, is the way that the devices and render contexts are separated. Before, you would have a DirectX 9 object, which could handle your adapters and check for supported DirectX features. This object does not exist in DirectX 10, as it is replaced by the DirectX Graphics Infrastructure, or DXGI [1]. Instead, you have a DXGIAdapter to check for 4 support, seeing as the adapter itself has noting do with the actual DirectX context. The DXGIAdapter can then be queried for display modes, which allows you to find out whether or not your graphics card can support the suggested format. Also, instead of having all of the information in the actual DXGI object, one has to create a descriptor, and then request to get the information. A descriptor is basically a struct, containing bundled data. For example, the DXGI MODE DESC contains the data relevant to describe a display mode, such as refresh rate, width, height, scaling and format. When the appropriate object is queried with the GetDesc-function, in this case it's the DXGIOut- puts GetDisplayModeList, the DXGI MODE DESC is filled out with the data containing a single display mode. Device information is no longer accessed via DirectX in version 10. In version 9, one could query the DirectX display device to get information about the device name, and driver information. In DirectX 10, this data is no longer accessible, neither using DXGI nor ID3D10. Instead, one has to rely on the fact that checking for supporting features will suffice. Also, DirectX 10 allows for backwards compatibility for using cards that doesn't support DirectX 10. This ensures that the features requested will be supported by the hardware. 5.2 Graphics data The way graphics data is saved has been generalized into a much more intuitive system. There is no longer any difference between an index buffer, a vertex buffer, or a shader variable buffer, they are all treated as DirectX 10 data buffers [2]. The API knows what kind of buffer you want your current data buffer to be used for by using a flag when binding the buffer. This pattern is very much like the OpenGL way of creating data buffers. Textures however, have been more specifically divided into Texture1D, Tex- ture2D, and Texture3D. Instead of having for example a cube texture from DirectX 9, one handles it like an array of 6 Texture2D textures, giving you spe- cific control over each and every surface of the texture cube. This also allows you to target specific images as render targets, seeing as you get to handle every single layer of the texture as an individual texture. Every texture consists of sub resources, and this is also new for DirectX 10 [3]. A Texture2D can consist of a single sub resource, and thus, you have a texture without any mip-levels. If a 2D texture consists of several sub resources, then you have that many levels of mip for your texture. A sub resource can be tampered with, switched, and even removed, giving the user complete control over a texture and its mip-maps. To allow a texture to be used as a render target, one has to assign a render target view to a specific texture. This render target view can then be set as the back buffer, or as an instance in a multiple render target pass. To then set 5 what to display, the user has to specify what texture, or render target view, that should be used as the back buffer using the DXGI Swap Chain object. 5.3 Shaders The DirectX effects library is not longer a part of the standard library. This library is now available for as one of the DirectX SDK samples, so to access the features in the DirectX 11 effects library, one has to compile it separately. With DirectX 10 came shader model 4.0. With shader model 4.0 came a handful of changes. For example, the previous VPOS shader semantic, that would give you the vertex position in screen space, is now renamed to SV POSITION, and is now representing the center of a pixel, rather than a corner of it [4]. Also, DirectX 10 gave us the geometry shader pipeline stage, which is a fully programmable new stage of the pipeline, allowing the programmer to alter the mesh by emitting or removing vertices. There were also some changes to the effects library. To set render states for a technique or render pass, one needs to define three different state objects, a BlendState, a RasterizerState and a DepthStencilState.