The most streamlined Direct3d11 demo skeleton of the whole strategy

Source: Internet
Author: User
Tags constructor win32 win32 window

This series of articles is written by zhmxy555 (Mao), please specify the source.

http://blog.csdn.net/zhmxy555/article/details/7707628

Author: Mao Nebula e-mail: happylifemxy@qq.com


This article will explain how to create a blank Windows demo based on Direct3d11 with the knowledge of DirectX 11 that we have mastered in previous articles, and this demo, which we completed in this section, will be used as a template in a later article , used to demonstrate the functionality of the various novelty DirectX11.


First of all, for the sake of reusability of code, we will write a directx11demobase, and draw on the code in the Win32 style blank Win32 window demo in note 26, and then, by way of derivation, and overloading some necessary virtual functions for integration , to create our demo.




A discussion on writing style of code


First, we ask a question, using the self-answer form to discuss:


In this demo design process, we are using the C-language global variables and global functions of the partner mode to complete, or the C + + type of object-oriented style class to write it.

The answer is the latter, which is done using object-oriented thinking. As for the explanation of this question, the answer is benevolent see.

Light ink before read a C + + world Masterpiece "C + + meditation", the author of the article at the beginning of an example, and then through the comparison of the effect of the example, reflects the C and C + + an impartial evaluation, is such a paragraph:


"C + + encourages classes to represent things like output streams, and classes provide an ideal place to hold state information." The C language prefers not to store state information unless it has been planned beforehand. So C programmers tend to assume that there is an "environment": there is a set of locations where they can find the current state of the system. If there is only one environment and one system, it is no problem to think about it, but the system often needs to introduce something unique and create more of these things in a growing process. ”


The explanation of this passage, light ink or in his own words to describe it:

Usually we use the general variable as the container to pass the data, but as the complexity of the program leads to a larger amount of data, too much data needs to be passed, and the data is basically passed to almost every function, so we create a lot of global variables as "containers", So the process of our design will only become more and more bloated, more and more chaotic. Don't be afraid, there's a trick-we can create a class or struct to host these objects, making them look less cluttered and orderly.


Around such a big circle, word, is the use of global variables is not very good programming habits, we should use less or not, instead of using "class" to accomplish these tasks.



Second, the design of Dx11demobase class


For the time being, we require the demo in this section to do the following:

▲ Initialize D3D

▲ Release the Direct3D object created during the startup process

▲ Store member variables for our D3D objects

▲ provide a way to load the specific contents of the demo

▲ provide a way to uninstall the demo's specific content

▲ be able to display the specific contents of the update of the demo per frame

▲demo specific code for rendering content

From our list above, it is necessary to create a common initialization and unload function, a virtual function for loading and unloading content functions, and a base class for rendering and updating virtual functions of the game loop step. By setting these functions to virtual functions, the demo class derived from the base class can implement their own custom logic and behavior.

Based on these descriptions, we can write the following code for Dx11demobase:

Code Snippet One header file for the Dx11demobases class

[CPP] View Plain copy print? #ifndef  _demo_base_h_    #define  _demo_base_h_    #include <d3d11.h>     #include <d3dx11.h>    #include <DxErr.h>    class dx11demobase    {   public:      dx11demobase ();      virtual  ~dx11demobase ();      bool initialize ( HINSTANCE hInstance,  hwnd hwnd );      void shutdown ( );       Virtual bool loadcontent ( );      virtual void unloadcontent (  );      virtual void update ( float dt )  = 0;       virtual void render ( )  = 0;       protected:      HINSTANCE hInstance_;      hwnd hwnd_;      D3D_DRIVER_TYPE driverType_;       D3D_FEATURE_LEVEL featureLevel_;      ID3D11Device* d3dDevice_;       ID3D11DeviceContext* d3dContext_;       idxgiswapchain* swapchain_;      ID3D11RenderTargetView* backBufferTarget_;   };   #endif   

#ifndef _demo_base_h_
#define _demo_base_h_
#include <d3d11.h>
#include <d3dx11.h>
# Include<dxerr.h>
class Dx11demobase
{public
:
   dx11demobase ();
   Virtual ~dx11demobase ();
   BOOL Initialize (HINSTANCE HINSTANCE, HWND hwnd);
   void Shutdown ();
   virtual bool Loadcontent ();
   virtual void unloadcontent ();
   virtual void Update (float dt) = 0;
   virtual void Render () = 0;
   Protected:
   hinstance Hinstance_;
   HWND Hwnd_;
   D3d_driver_type Drivertype_;
   D3d_feature_level Featurelevel_;
   id3d11device* D3ddevice_;
   id3d11devicecontext* D3dcontext_;
   idxgiswapchain* Swapchain_;
   id3d11rendertargetview* backbuffertarget_;
};
#endif




In the above code we can see the most streamlined D3d object, which exists in the class as a protected class member. Initializing variables outside of the class is a good programming habit and is much more efficient than calling the copy constructor starters and then calling the default constructor.

Dx11demobase class constructors, destructors, load contents, unload content, shutdown functions are defined as follows:



Code Snippet Two some dx11demobase composition code


[CPP] View Plain copy print? #include "Dx11DemoBase.h"       dx11demobase::D x11demobase ( )  : drivertype_ (  d3d_driver_type_null),   Featurelevel_ ( D3D_FEATURE_LEVEL_11_0 ),  d3ddevice_ (  0 ), D3dcontext_ ( 0 ),   swapchain_ ( 0 ),  backbuffertarget_ (  0 )    {     }      void dx11demobase::unloadcontent (  )    {  //Can be overloaded here, add code to implement related functions             void  dx11demobase::shutdown ( )    {      unloadcontent ( );       if ( backBufferTarget_ )  backbuffertarget_->release ( );       if ( swapChain_ )  swapchain_->release ( );       if ( d3dContext_ )  d3dcontext_->release ( );      if ( d3dDevice_ )  d3ddevice_->release ( );       d3ddevice_ = 0;      d3dContext_ = 0;       swapChain_ = 0;      backBufferTarget_ = 0;  }   

#include "Dx11DemoBase.h"

dx11demobase::D x11demobase (): Drivertype_ (d3d_driver_type_null),
featurelevel_ (D3D_FEATURE_LEVEL_11_0), D3ddevice_ (0), D3dcontext_ (0),
swapchain_ (0), backbuffertarget_ (0)
{

}

void Dx11demobase::unloadcontent ()
{
//can be overloaded here, add code to implement related functions



void Dx11demobase::shutdown ()
{
   unloadcontent ();
   if (backbuffertarget_) backbuffertarget_->release ();
   if (swapchain_) swapchain_->release ();
   if (d3dcontext_) d3dcontext_->release ();
   if (D3ddevice_) d3ddevice_->release ();
   D3ddevice_ = 0;
   D3dcontext_ = 0;
   Swapchain_ = 0;
   backbuffertarget_ = 0;
}



The last function in the Dx11demobase class is the Initialize function. The Initialize function performs the D3D initialization that we talked about in this chapter. This function begins to declare the driver type of our hardware, warp or software, and our d3d11.0,10.1 or 10.0 feature level. The code is set to attempt to create a hardware device in D3D 11. If the creation fails, we will try other drive types and feature levels until we find a suitable type. This also means that if we use D3D10 hardware we can also run this demo in hardware because we can choose a feature level of 10.1 or 10.0.

The next step is to create a description of the swap chain and use that information to try to find the supported device types and feature levels. If we succeed in searching for the information we need. The next step is to create a render target, create viewports, and invoke the Loadcontent method to load specific content. It is important to note that the Loadcontent method is best left with the last call to avoid unnecessary errors.

Here is the whole process of DirectX11 initialization:



Code Snippet three initialization function for the Dx11demobase class

 

[CPP] View Plain copy print? Bool dx11demobase::initialize ( HINSTANCE hInstance, HWND hwnd )    {        hInstance_ =hInstance;       hwnd_  = hwnd;           RECT dimensions;        getclientrect ( hwnd,&dimensions );            unsigned int width =dimensions.right - dimensions.left;        unsigned int height =dimensions.bottom - dimensions.top;            D3D_DRIVER_TYPEdriverTypes[] =        {          d3d_driver_type_hardware, d3d_driver_ type_warp,          d3d_driver_type_reference, d3d_driver_type_software       };            unsigned inttotaldrivertypes = arraysize ( driverTypes );            D3D_FEATURE_LEVELfeatureLevels[] =        {          D3D_FEATURE_LEVEL_11_0,           D3D_FEATURE_LEVEL_10_1,          d3d _feature_level_10_0       };            unsigned inttotalfeaturelevels = arraysize ( featureLevels );            DXGI_SWAP_CHAIN_DESCswapChainDesc;        ZeroMemory (&swapchaindesc, sizeof ( swapChainDesc )  );       Swapchaindesc.buffercount = 1;      swapChainDesc.BufferDesc.Width = width;      swapChainDesc.BufferDesc.Height = height;       swapchaindesc.bufferdesc.format = dxgi_format_r8g8b8a8_unorm;       swapchaindesc.bufferdesc.refreshrate.numerator = 60;       swapchaindesc.bufferdesc.refreshrate.denominator = 1;       swapchaindesc.bufferusage = dxgi_usage_render_target_output;       swapchaindesc.outputwindow = hwnd;       swapChainDesc.Windowed=  true;      swapChainDesc.SampleDesc.Count = 1;        swapChainDesc.SampleDesc.Quality= 0;           unsigned  intcreationFlags = 0;       #ifdef  _debug        creationFlags |=D3D11_CREATE_DEVICE_DEBUG;    #endif            HRESULT result;        unsigned int driver =0;           for (  driver = 0;driver < totalDriverTypes; ++driver )         {           result = D3d11createdeviceandswapchain ( 0, driverTypes[driver], 0, creationFlags,                                                     featureLevels, totalFeatureLevels,    &NBSP;&NBSP;&NBSP;&NBSP;&NBsp;                                            d3d11_sdk_version, &swapchaindesc, &swapchain_,                                                     &d3dDevice_, & featurelevel_, &d3dcontext_ );                if ( succeeded (result )  )             {               drivertype_ = Drivertypes[driver]; &nbsP             break;            }       }            if ( failed ( result )  )        {            dxtrace_msg ("Create  Direct3D  device failed!")  );           return false;        }           ID3D11Texture2D*backBufferTexture;            result =swapchain_->getbuffer ( 0, __uuidof (  ID3D11Texture2D ),  ( lpvoid*) &backBufferTexture );           if ( failed ( result )  )        {    &NBSP;&NBSP;&NBSP;&NBsp;    dxtrace_msg ("Get Swap chain background cache failed.") " );           return false;        }           result =d3dDevice_-> Createrendertargetview ( backBufferTexture, 0,&backBufferTarget_ );            if ( backbuffertexture)            backbuffertexture->release ( );           if (  FAILED ( result )  )        {            dxtrace_msg ("Create render target View failed!")  );           return false;        }          d3dcontext_->omsetrendertargets ( 1,  &backbuffertarget_, 0 );           D3D11_VIEWPORTviewport;        viewport. Width =static_cast<float> (width);       viewport. height =static_cast<float> (height);       viewport. mindepth =0.0f;       viewport. maxdepth =1.0f;       viewport. topleftx =0.0f;       viewport. toplefty =0.0f;          d3dcontext_->rssetviewports ( 1,  &viewport );           return loadcontent (  );  }          

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.