"D3d11 Game Programming" Learning Note five: D3D11 initialization

Source: Internet
Author: User
Tags win32

(Note: "D3d11 game Programming" study Note series by CSDN author Bonchoix wrote, reproduced please indicate the source: Http://blog.csdn.net/BonChoix, thank you ~)

The first time you use D3D11, start with its initialization. Before using D3D, however, there are several important concepts to understand:

1. Hardware capability: Hardware capacity

Familiar with the d3d9 will be very clear, at the beginning of the initialization of d3d9 need to do is to detect the ability of the hardware to understand the user's machine support which D3D features, which are not supported, in the runtime reasonable call API. Unless you use the software rendering engine that comes with D3D, attempting to use a feature that is not supported by hardware is an error. In D3d11, however, it is no longer necessary to detect hardware capabilities. This saves a bit of effort for the programmer, but the additional requirement is that the hardware must support all the features of the D3D11. As a result, the D3D11 application is more demanding in terms of hardware.

2. Data Format

D3D applications, whether they are texture images or buffers created, have specific data formats. D3D11 supports a limited data format that exists as an enumeration variable in the following ways:

Dxgi_format_r32g32b32_float:3 32-bit single-precision character points, for example, to represent three-dimensional space coordinates, as well as 24-bit color;

Dxgi_format_r16g16b16a16_unorm:4 a 16-digit number, each member is located between [0,1.0f], UNORM means: unsigned normalized, namely unsigned, and normalized;

Dxgi_format_r32g32_uint:2 a 32-digit number, each of which is an unsigned integer (unsigned int);

Dxgi_format_r8g8b8a8_unorm:4 a 8-digit number consisting of [0,1.f] each member;

Dxgi_format_r8g8b8a8_snorm:4 a 8-digit number, each member is [ -1.0f, 1.0f] between, snorm means: signed normalized;

Dxgi_format_r8g8b8a8_sint:4 a 8-digit number, each member is a signed integral type;

In addition there are many other types of data formats, familiar with the meaning of the various parts of any type can be quickly learned from the name of its meaning, it is also easy to write the specified meaning of the data format corresponding to the enumeration variable. Data formats are used fairly frequently in programs, so it is necessary to familiarize yourself with the characteristics of the enumerated type variable in advance.

3. DXGI

The DXGI, or DirectX Graphics Infrastructure, comes from the beginning of d3d10, encapsulating some d3d underlying, underlying mechanisms, including data format definitions, swap chains (Swapchain), Enumerates device types, detects device information, and so on. Because these mechanisms are suitable for any generation of D3D interfaces and are not related to a particular D3D feature, the update is far less frequent than other D3D features, so Microsoft separates these from the Direct3D alone. This part of the corresponding enumeration variables and functions, such as the beginning of Dxgi.

4. Swap chain: Swapchain

swap chain is not a unique property of D3d11, but one of the most basic mechanisms of any 2D and 3D computer animation. To achieve a smooth animation, at least two buffers are required, a front buffer is used to display, one post buffer is used for the next frame of drawing, each time a frame is drawn, a new frame is displayed by swapping the corresponding pointer of the front and back buffers, and the next frame continues to be drawn on the previous buffer (the current back buffer). Swap chains can have 3 or more buffers, but in most cases 2 are enough. The interface for the swap chain in D3d11 is Idxgiswapchain.

5. Depth/stencil buffers: depth/stencil buffer

A depth buffer is an area of memory that is exactly the same size as the swap chain buffer, where each pixel corresponds to the corresponding position in the depth buffer. In the final blending phase of the render pipeline (Output merger stage), each fragment (Fragment) has a depth value Z, compared to the depth at the corresponding position in the depth buffer, if the fragment z is smaller, the fragment is drawn and the current attempt value is overwritten, otherwise the fragment is discarded. This buffer is primarily used to achieve the same occlusion between objects projected on the screen at the same location and near and far. In addition, there are many kinds of advanced effects that can be achieved with the flexible configuration of the try buffer.

The template buffer shares the same block area as the depth buffer, with one template value for each depth value, and the template value is primarily used to implement some advanced effects such as planar reflections, shadows, and so on. Various effects using different configuration of depth and template buffers are described in detail later.

6. Views (view)

views are one of the most important concepts in D3D11. In the case of textures, a texture can be bound to different stages of a 3D rendering pipeline for different purposes. For example, common texture images (called Shader Resource in D3d11) can also be used to render objects (render target), acting as buffers in swap chains for drawing scenes. The same texture can be bound to multiple pipeline stages at the same time (Dynamic Cube mapping is an example, which is described later), but when creating the texture resource you need to specify the type of binding (bind Flags), such as the above example, the binding type is specified as: d3d11_ Bind_render_target | D3d11_shader_resource.

In fact, in D3d11, it is not the texture resource itself that binds to a stage of the pipeline, but the corresponding "view". For each method that uses the texture, we create the corresponding view separately and then bind the view to the pipeline-specific stage. The corresponding interfaces for each view in D3d11 are: Id3d11shaderresourceview and Id3d11rendertargetview, Id3d11depthstencilview. Using the details of the view will slowly be realized in the following process.

7. Multi-Sample anti-aliasing: multisampling atialiasing

There are many methods for the anti-aliasing of rasterized displays, which are used in the D3D of multiple sampling methods. That is, within each pixel, set multiple sample points, draw the polygon edge, for each sample point to determine whether the polygon is covered, the final color value from the sample point to take the mean, to the edge of the polygon to "blur", thereby reducing the aliasing effect. As shown in the following figure, this is an example of a 4 resampling, where the final color value is 3/4 of the color value of the polygon itself:

The hardware that supports D3D11 all supports 4 resampling, so we will generally use 4 sample points in later programs. Multi-sampling is set in D3D11 by the structure DXGI_SAMPLE_DESC, which is defined as follows:

typedef struct DXGI_SAMPLE_DESC {
  UINT Count;
  UINT quality;
} Dxgi_sample_desc, *lpdxgi_sample_desc;

Count sets the number of samples we set, quality the different levels supported by the machine, and we will detect the quality during initialization.

Note multisampling differs from the key point of the super sampling: whether the different sample points calculate the color value (super sampling) or share the same color value (multisampling) separately. There are a lot of reference books in detail.

8. Feature class: Feature level

The feature level defines a series of corresponding levels that support different D3D functions, meaning that if a user's hardware does not support a particular feature level, the program can choose a lower level to ensure proper operation. The following levels are defined in D3D11 to represent the different D3D versions:

typedef enum D3D_FEATURE_LEVEL {
  d3d_feature_level_9_1    = 0x9100,
  d3d_feature_level_9_2    = 0x9200,
  d3d_feature_level_9_3    = 0x9300,
  d3d_feature_level_10_0   = 0xa000,
  d3d_feature_level_10_1   = 0xa100,
  D3d_feature_level_11_0   = 0xb000 
} d3d_feature_level;

During the initialization process, we can provide a different set of feature levels, and the program will detect each one from the first, and run into the first appropriate one to create the device. So we provide the initialization program in the array from high to low placement feature level.

OK, the important concept is these, now start initializing d3d~

The initialization of D3D11 is mainly in the following steps:

1. Create device Id3d11device and device context Id3d11devicecontext;

2. Detection of multi-sampling support levels: Checkmultisamplequalitylevels

3. Create a swap chain

4. Create Rendertargetview

5. Create Depthstencilview

6. Bind the two views above to the corresponding stage of the render pipeline

7. Set Viewport

The following starts with the first step:

1. Create the device and context:

The function prototypes are as follows:

HRESULT  d3d11createdevice (
  __in   idxgiadapter *padapter,
  __in   d3d_driver_type Drivertype,
  __in   hmodule software,
  __in   UINT Flags,
  __in   const d3d_feature_level *pfeaturelevels,
  __in   UINT Featurelevels,
  __in   uint sdkversion,
  __out  id3d11device **ppdevice,
  __out  d3d_ Feature_level *pfeaturelevel,
  __out  id3d11devicecontext **ppimmediatecontext
);

Padapter to select the appropriate graphics adapter, set to NULL to select the default adapter;

Drivertype Setting the driver type, there is no doubt that hardware acceleration is chosen, that is, D3d_driver_type_hardware, at which point the next parameter is null;

Flags are optional parameters, generally null, can be set to D3d11_create_device_debug, d3d11_create_device_singlethreaded, or both, the former lets you collect information for debugging purposes. The latter is set to it when it is determined that the program is only run on a single thread, which can improve performance;

Pfeaturelevels gives us an array of feature levels for the program, and the next parameter is the number of elements in the array;

Sdkversion constant for D3d11_sdk_version;

Ppdevice is the address of the device pointer, noting that the device is a pointer type, where the address of the pointer is passed (a two-dimensional pointer, and all the interfaces in the D3D program are declared as pointer types. );

Pfeaturelevel is the selected feature level for the last program, we define the corresponding variable and pass its address in.

Ppimmediatecontext is the address of the device context pointer, which requires the same device pointer.

Create the device code as follows:

Id3d11device		*d3ddevice (NULL);
Id3d11devicecontext	*devicecontext (NULL);
D3d_feature_level Featurelevels[6] = {
	d3d_feature_level_11_0,
	d3d_feature_level_10_1,
	D3D_FEATURE_ Level_10_0,
	d3d_feature_level_9_3,
	d3d_feature_level_9_2,
	d3d_feature_level_9_1};
D3d_feature_level	Curlevel;
D3d11createdevice (
	0,  				//default adapter
	D3d_device_type_hardware,	//Hardware acceleration Device type
	0, 
	0, 
	Featurelevels, 6,
	d3d11_sdk_version,
	&d3ddevice,
	&curlevel,
	&devicecontext);

You can detect multiple samples (we only use 4 resampling) at the end of the creation level:

M_d3ddevice->checkmultisamplequalitylevels (dxgi_format_r8g8b8a8_unorm,4,&x4msaaquality);

2. Create a swap chain

The nature of the swap chain is specified by the following structure:

typedef struct DXGI_SWAP_CHAIN_DESC {
  dxgi_mode_desc   bufferdesc;
  Dxgi_sample_desc Sampledesc;
  Dxgi_usage       bufferusage;
  UINT             BufferCount;
  HWND             OutputWindow;
  BOOL             windowed;
  Dxgi_swap_effect SwapEffect;
  UINT             Flags;
} Dxgi_swap_chain_desc;

BUFFERDESC Specifies the post-buffer-related characteristics;

SAMPLEDESC specifies multiple sampling, as previously said;

Bufferusage, for the swap chain, for dxgi_usage_render_target_output;

BufferCount: We only create one post buffer (double buffering), so it is 1;

OutputWindow: Specifies the window handle, the WIN32 program initializes the created main window;

Windowed: whether full screen;

Dxgi_swap_effect: usually Dxgi_swap_effect_discard;

Flags: Optional, we set to 0;

The DXGI_MODE_DESC structure is defined as follows:

typedef struct DXGI_MODE_DESC {
  UINT                     Width;
  UINT                     Height;
  Dxgi_rational            refreshrate;
  Dxgi_format              FORMAT;
  Dxgi_mode_scanline_order scanlineordering;
  Dxgi_mode_scaling        SCALING;
} Dxgi_mode_desc, *lpdxgi_mode_desc;

Width, height is the buffer size, usually set as the main window size;

FORMAT is a buffer type, generally as the render object buffer type is dxgi_format_r8g8b8a8_unorm;

The other parameters are generally fixed, see Code.

In addition, creating the swap chain requires getting the interface idxgifactory, the process is fixed, creating the swap chain code as follows:

	Dxgi_swap_chain_desc Scdesc = {0};		Fill structure, set swap chain equivalent properties ScDesc.BufferDesc.Format = Dxgi_format_r8g8b8a8_unorm;			Buffer data Format scDesc.BufferDesc.Width = 640;
	Buffer size scDesc.BufferDesc.Height = 480;			ScDesc.BufferDesc.RefreshRate.Numerator = 60;
	Refresh rate, generally this setting can be scDesc.BufferDesc.RefreshRate.Denominator = 1;			scDesc.BufferDesc.Scaling = dxgi_mode_scaling_unspecified;	Fixed parameter scDesc.BufferDesc.ScanlineOrdering = dxgi_mode_scanline_order_unspecified;					Fixed parameter scdesc.buffercount = 1;		Number of buffers scdesc.bufferusage = Dxgi_usage_render_target_output;
	Usage is render Target Output scdesc.flags = 0;			Scdesc.outputwindow = m_hwnd;			main Window Handle scDesc.SampleDesc.Count = 4;	4 Sample points scDesc.SampleDesc.Quality = x4msaaquality-1;	4 resampling support Level scdesc.swapeffect = Dxgi_swap_effect_discard;				Common parameter scdesc.windowed = true;
	Window mode//through the following three steps to obtain the interface idxgifactory, to create a swap chain Idxgidevice *pdxgidevice (NULL);
M_d3ddevice->queryinterface (__uuidof (Idxgidevice),reinterpret_cast<void**> (&pDxgiDevice));	Idxgiadapter *pdxgiadapter (NULL);
	Pdxgidevice->getparent (__uuidof (idxgiadapter),reinterpret_cast<void**> (&pDxgiAdapter));
	Idxgifactory *pdxgifactory (NULL);
	Pdxgiadapter->getparent (__uuidof (idxgifactory),reinterpret_cast<void**> (&pDxgiFactory));
	
	Pdxgifactory->createswapchain (D3ddevice,&scdesc,&swapchain);
	Release interface Saferelease (pdxgifactory);
	Saferelease (Pdxgiadapter); Saferelease (Pdxgidevice);

3. Create Rendertargetview

Creating a view in D3d11 requires a corresponding resource, where you first get the post-buffer address and create the corresponding view as a parameter:

	Id3d11texture2d *backbuffer (NULL);
	Gets the post-buffer address
	Swapchain->getbuffer (0,__uuidof (id3d11texture2d),reinterpret_cast<void**> (& BackBuffer));
	Create View
	D3ddevice->createrendertargetview (Backbuffer,0,&m_rendertargetview);
	After releasing the buffer reference
	backbuffer->release ();

The Createrendertargetview function is prototyped as follows:

	HRESULT Createrendertargetview (
  	 id3d11resource *presource,				//view corresponding resource
  	 const D3D11_RENDER_TARGET_VIEW_ DESC *pdesc,//		View description
  	 Id3d11rendertargetview **pprtview			//view to be created (the address of the pointer)
);

A description of the view (the second parameter) is required to create the view in D3d11, but if the view corresponds to a resource type that is known, it is generally no longer required and is set to null. Here the buffer is given at the time of Creation (Dxgi_format_r8g8b8a8_unorm), so the view description is not required here. When a resource is created, it can also be specified as untyped (typeless) and interpreted at different stages in different types, when a view is created that requires a view description to clearly describe the type.
4. Create depth, template buffers, and corresponding views

Create a buffer to create a 2-dimensional texture, id3d11texture2d, creating it requires a description of D3d11_texture2d_desc first. Defined as follows:

typedef struct D3D11_TEXTURE2D_DESC {
  UINT             Width;
  UINT             Height;
  UINT             miplevels;		There is no need for mipmap, set to 1
  UINT             ArraySize;		Texture array is used, here is 1
  dxgi_format      FORMAT;		Data format, generally dxgi_format_d24_unorm_s8_uint,24 bit for depth, 8 bits for template
  dxgi_sample_desc Sampledesc;		Multiple samples, such as before, must be consistent before and after.
  D3d11_usage      Usage;		Usage, for only let GPU read, write, should be D3d11_usage_default
  UINT             bindflags;		The binding type is D3d11_bind_depth_stencil
  UINT             cpuaccessflags;	CPU unreachable, set to 0
  UINT             miscflags;		Set to 0
} D3d11_texture2d_desc;

To create the view type Depthstencilview, the code is as follows:

	D3d11_texture2d_desc Dsdesc;
	Dsdesc.format = Dxgi_format_d24_unorm_s8_uint;
	Dsdesc.width = 640;
	Dsdesc.height = 480;
	Dsdesc.bindflags = D3d11_bind_depth_stencil;
	Dsdesc.miplevels = 1;
	Dsdesc.arraysize = 1;
	dsdesc.cpuaccessflags = 0;
	DsDesc.SampleDesc.Count = 4;
	dsDesc.SampleDesc.Quality = x4msaaquality-1;
	dsdesc.miscflags = 0;
	Dsdesc.usage = D3d11_usage_default;
	D3ddevice->createtexture2d (&dsdesc,0,&depthstencilbuffer);
	D3ddevice->createdepthstencilview (Depthstencilbuffer,0,&depthstencilview);

Once you've created two views, you're bound to the rendering pipeline:

	Devicecontext->omsetrendertargets (1,&rendertargetview,depthstencilview);

The function is prototyped as follows:

void Omsetrendertargets (
  [in]  UINT numviews,							//rendertarget number, we generally use only one
  [in]  Id3d10rendertargetview *const *pprendertargetviews,		//rendertarget Array, only one, so direct its address can be
  [in]  Id3d10depthstencilview *pdepthstencilview			//depthstencil view
);

Finally set viewport, very simple, d3d11_viewport defined as follows:

typedef struct D3D11_VIEWPORT {
  FLOAT topleftx;		The upper left corner of the viewport on the screen x-coordinate, generally depending on the share population full screen, so for 0
  FLOAT toplefty;		Y-coordinate, same as
  FLOAT Width;			Viewport width, generally consistent with the back buffer to maintain the image does not deform
  FLOAT Height;			Height, ditto
  FLOAT mindepth;		Minimum depth value: 0.0f
  FLOAT MaxDepth;		Maximum depth value: 1.0f
} d3d11_viewport;

To set the viewport code:

	D3d11_viewport VIEWPORT;
	Viewport.width = static_cast<float> (clientwidth);
	Viewport.height = static_cast<float> (clientheight);
	viewport.maxdepth = 1.f;
	viewport.mindepth = 0.F;
	VIEWPORT.TOPLEFTX = 0.F;
	Viewport.toplefty = 0.F;
	Devicecontext->rssetviewports (1,&viewport);

Voila, the initialization process is complete.

The following can be entered into the main loop rendering function to draw the scene, this time we do not draw anything, but simply to empty the screen to a randomly specified color:

	XMVECTORF32 color = {0.f, 1.f, 0.F, 1.6f};
	G_devicecontext->clearrendertargetview (g_rendertargetview,reinterpret_cast<float*> (&color));
	G_devicecontext->cleardepthstencilview (g_depthstencilview,d3d11_clear_depth| d3d11_clear_stencil,1.f,0);

	G_swapchain->present (0,0);

When each frame starts rendering, the Rendertargetview and depth buffers are emptied first, and then the content is rendered in full screen. After drawing the entire scene, the last call lets the swap chain present to swap the front and back buffers to display a new frame. Emptying the rendertarget is simple, pass the corresponding view in, and given any background color (4 float array, this is suitable for XMVECTORF32). For the empty depth, the template buffer, the first parameter at a glance, the second is used to specify the empty content parameters, generally we want to clear the depth and template at the same time, so with two enumeration variables, the last two parameters specify the empty depth and the default value of the template, The depth is emptied to 1.0f (max), and the template is generally emptied to 0, and so on.

The whole process is over, with the last Win32 program, is now a complete, working D3D program, showing a blank window of the specified color. The initialization program is like this, one of the simplest D3D applications. Slowly began to render more dazzling scenes ~

This complete initialization program source code is as follows:

D3D11 Full initialization code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.