• Direct3D初始化


    Direct3D初始化步骤(核心代码):

     1 // 描述交换链
     2     DXGI_SWAP_CHAIN_DESC sd;
     3     sd.BufferDesc.Width = mClientWidth;
     4     sd.BufferDesc.Height = mClientHeigth;
     5     sd.BufferDesc.RefreshRate.Numerator = 60;
     6     sd.BufferDesc.RefreshRate.Denominator = 1;
     7     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
     8     sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
     9     sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    10     sd.SampleDesc.Count = 1;    // 多重采样数量和质量级别
    11     sd.SampleDesc.Quality = 0;
    12     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;    // 将它用作渲染目标
    13     sd.BufferCount = 1;
    14     sd.OutputWindow = mhMainWnd;
    15     sd.Windowed = true;
    16     sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    17     sd.Flags = 0;
    18 
    19     UINT createDeviceFlags = 0;
    20     // 创建设备和交换链
    21     D3D10CreateDeviceAndSwapChain(0, md3dDriverType, 0, createDeviceFlags,
    22         D3D10_SDK_VERSION, &sd, &mSwapChain, &md3dDevice);
    23 
    24     // 创建渲染目标视图
    25     ID3D10Texture2D* backBuffer;
    26     mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer));
    27     md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
    28     backBuffer->Release();//每调用一次IDXGISwapChain::GetBuffer,后台缓冲区的COM引用计数向上递增一次,所以释放
    29 
    30     // 创建深度/模板缓冲区及其视图
    31     D3D10_TEXTURE2D_DESC depthStencilDesc;
    32     depthStencilDesc.Width = mClientWidth;
    33     depthStencilDesc.Height = mClientHeigth;
    34     depthStencilDesc.MipLevels = 1;
    35     depthStencilDesc.ArraySize = 1;
    36     depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    37     depthStencilDesc.SampleDesc.Count = 1;
    38     depthStencilDesc.SampleDesc.Quality = 0;
    39     depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
    40     depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
    41     depthStencilDesc.CPUAccessFlags = 0;
    42     depthStencilDesc.MiscFlags = 0;
    43     md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer);
    44     md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView);
    45 
    46     // 将视图绑定到输出合并器阶段
    47     md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
    48 
    49     // 设置视口
    50     // 通过修改视口,可以把3D场景渲染到后台缓冲区的一个子矩形区域中
    51     D3D10_VIEWPORT vp;
    52     vp.TopLeftX = 0;
    53     vp.TopLeftY = 0;
    54     vp.Width = mClientWidth;
    55     vp.Height = mClientHeigth;
    56     vp.MinDepth = 0.0f;
    57     vp.MaxDepth = 1.0f;
    58     md3dDevice->RSSetViewports(1, &vp);

    本程序中,使用md3dDevice::ClearRenderTargetView清除渲染目标视图的颜色缓冲区,设为特定的颜色,然后调用mSwapChain->Present(0, 0)函数在屏幕上显示渲染缓冲区的内容(即设定的背景颜色)。

    完整程序(使用类):

      1 /*
      2 2015.4
      3 DirectX10 Init
      4 
      5 对 Direct3D 进行初始化
      6 1. 填充一个DXGI_SWAP_CHAIN_DESC结构体,该结构体描述了所要创建的交换链的特性。
      7 2. 使用D3D10CreateDeviceAndSwapChain 函数创建ID3D10Device接口和IDXGISwapChain接口。
      8 3. 为交换链的后台缓冲区创建一个渲染目标视图。
      9 4. 创建深度/模板缓冲区以及相关的深度/模板视图。
     10 5. 将渲染目标视图和深度/模板视图绑定到渲染管线的输出合并阶段,使它们可以被Direct3D使用。
     11 6. 设置视口。
     12 */
     13 
     14 #include <iostream>
     15 #include <string>
     16 #include <d3d10.h>
     17 #include <d3dx10.h>
     18 
     19 #pragma comment(lib, "d3d10.lib")
     20 #pragma comment(lib, "d3dx10.lib")
     21 
     22 LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
     23 
     24 class D3DApp
     25 {
     26 public:
     27     D3DApp(HINSTANCE hInstance);
     28     ~D3DApp();
     29 
     30     HINSTANCE getAppInstance();
     31     HWND getMainWnd();
     32     int run();
     33 
     34     void initApp();
     35     void onResize();
     36     void updateScene();
     37     void drawScene();
     38     LRESULT msgProc(UINT msg, WPARAM wParam, LPARAM lParam);
     39 
     40 protected:
     41     void initMainWindow();
     42     void initDirect3D();
     43 
     44     HINSTANCE mhAppInstance;
     45     HWND mhMainWnd;
     46     bool mAppPaused;
     47     bool mMinimized;
     48     bool mMaximized;
     49     bool mResizing;
     50 
     51     std::wstring mFrameStatus;
     52     std::wstring mMainWndCaption;
     53 
     54     ID3D10Device* md3dDevice;
     55     IDXGISwapChain* mSwapChain;
     56     D3D10_DRIVER_TYPE md3dDriverType;
     57     D3DXCOLOR mClearColor;
     58     ID3D10Texture2D* mDepthStencilBuffer;
     59     ID3D10RenderTargetView* mRenderTargetView; 
     60     ID3D10DepthStencilView* mDepthStencilView;
     61     ID3DX10Font* mFont;
     62 
     63     int mClientWidth;
     64     int mClientHeigth;
     65 };
     66 
     67 D3DApp::D3DApp(HINSTANCE hInstance)
     68 {
     69     mhAppInstance = hInstance;
     70     mhMainWnd = 0;
     71     mAppPaused = false;
     72     mMinimized = false;
     73     mMaximized = false;
     74     mResizing = false;
     75 
     76     mFrameStatus = L"";
     77     mMainWndCaption = L"D3D10 Application";
     78 
     79     md3dDevice = 0;
     80     mSwapChain = 0;
     81     md3dDriverType = D3D10_DRIVER_TYPE_HARDWARE;
     82     mClearColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
     83     mFont = 0;
     84     mClientWidth = 800;
     85     mClientHeigth = 600;
     86 }
     87 
     88 D3DApp::~D3DApp()
     89 {
     90     mSwapChain->Release();
     91     mFont->Release();
     92     md3dDevice->Release();
     93 }
     94 
     95 HINSTANCE D3DApp::getAppInstance()
     96 {
     97     return mhAppInstance;
     98 }
     99 
    100 HWND D3DApp::getMainWnd()
    101 {
    102     return mhMainWnd;
    103 }
    104 
    105 int D3DApp::run()
    106 {
    107     MSG msg = { 0 };
    108 
    109     while (msg.message != WM_QUIT)
    110     {
    111         if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
    112         {
    113             TranslateMessage(&msg);
    114             DispatchMessage(&msg);
    115         }
    116         else
    117         {
    118             drawScene();
    119         }
    120     }
    121     return (int)msg.wParam;
    122 }
    123 
    124 void D3DApp::initApp()
    125 {
    126     initMainWindow();
    127     initDirect3D();
    128 
    129     D3DX10_FONT_DESC fontDesc;
    130     fontDesc.Height = 24;
    131     fontDesc.Width = 0;
    132     fontDesc.Weight = 0;
    133     fontDesc.MipLevels = 1;
    134     fontDesc.Italic = false;    //非斜体
    135     fontDesc.CharSet = DEFAULT_CHARSET;
    136     fontDesc.OutputPrecision = OUT_DEFAULT_PRECIS;
    137     fontDesc.Quality = DEFAULT_QUALITY;
    138     fontDesc.PitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
    139     wcscpy_s(fontDesc.FaceName, L"Times New Roman");
    140 
    141     D3DX10CreateFontIndirect(md3dDevice, &fontDesc, &mFont);
    142 }
    143 
    144 void D3DApp::onResize()
    145 {
    146     // Release the old views, as they hold references to the buffers we
    147     // will be destroying.  Also release the old depth/stencil buffer.
    148     mRenderTargetView->Release();
    149     mDepthStencilBuffer->Release();
    150     mDepthStencilView->Release();
    151 
    152     // Resize the swap chain and recreate the render target view.
    153     mSwapChain->ResizeBuffers(1, mClientWidth, mClientHeigth, DXGI_FORMAT_R8G8B8A8_UNORM, 0); //[0, 1]区间
    154     
    155     // 创建渲染目标视图
    156     ID3D10Texture2D* backBuffer;
    157     mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer));
    158     md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
    159     backBuffer->Release();
    160 
    161     // 创建深度/模板缓冲区及其视图
    162     D3D10_TEXTURE2D_DESC depthStencilDesc;
    163     depthStencilDesc.Width = mClientWidth;
    164     depthStencilDesc.Height = mClientHeigth;
    165     depthStencilDesc.MipLevels = 1;
    166     depthStencilDesc.ArraySize = 1;
    167     depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    168     depthStencilDesc.SampleDesc.Count = 1;
    169     depthStencilDesc.SampleDesc.Quality = 0;
    170     depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
    171     depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
    172     depthStencilDesc.CPUAccessFlags = 0;
    173     depthStencilDesc.MiscFlags = 0;
    174     md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer);
    175     md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView);
    176 
    177     // 将视图绑定到输出合并器阶段,使它们可以被Direct3D使用
    178     md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
    179 
    180     // 设置视口
    181     D3D10_VIEWPORT vp;
    182     vp.TopLeftX = 0;
    183     vp.TopLeftY = 0;
    184     vp.Width = mClientWidth;
    185     vp.Height = mClientHeigth;
    186     vp.MinDepth = 0.0f;
    187     vp.MaxDepth = 1.0f;
    188     md3dDevice->RSSetViewports(1, &vp);
    189 }
    190 
    191 void D3DApp::updateScene()
    192 {
    193 
    194 }
    195 
    196 void D3DApp::drawScene()
    197 {
    198     mClearColor = D3DXCOLOR(0.0f, 0.5f, 0.0f, 1.0f);
    199 
    200     // 清除渲染目标视图的颜色缓冲区,设为特定的颜色
    201     md3dDevice->ClearRenderTargetView(mRenderTargetView, mClearColor);
    202 
    203     // 调用交换链的Present函数在屏幕上显示渲染缓冲区的内容
    204     mSwapChain->Present(0, 0);
    205 }
    206 
    207 LRESULT D3DApp::msgProc(UINT msg, WPARAM wParam, LPARAM lParam)
    208 {
    209     switch (msg)
    210     {
    211     case WM_DESTROY:
    212         PostQuitMessage(0);
    213         return 0;
    214     }
    215     return DefWindowProc(mhMainWnd, msg, wParam, lParam);
    216 }
    217 
    218 void D3DApp::initMainWindow()
    219 {
    220     WNDCLASS wc;
    221     wc.style = CS_HREDRAW | CS_VREDRAW;
    222     wc.lpfnWndProc = MainWndProc;
    223     wc.cbClsExtra = 0;
    224     wc.cbWndExtra = 0;
    225     wc.hInstance = mhAppInstance;
    226     wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    227     wc.hCursor = LoadCursor(0, IDC_ARROW);
    228     wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
    229     wc.lpszMenuName = 0;
    230     wc.lpszClassName = L"D3DWndClassName";
    231 
    232     if (!RegisterClass(&wc))
    233     {
    234         MessageBox(0, L"RegisterClass FAILED", 0, 0);
    235         PostQuitMessage(0);
    236     }
    237     RECT R = { 0, 0, mClientWidth, mClientHeigth };
    238     AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
    239     int width = R.right - R.left;
    240     int height = R.bottom - R.top;
    241 
    242     mhMainWnd = CreateWindow(L"D3DWndClassName", mMainWndCaption.c_str(),
    243         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, mhAppInstance, this);
    244     if (!mhMainWnd)
    245     {
    246         MessageBox(0, L"CreateWindow FAILED", 0, 0);
    247         PostQuitMessage(0);
    248     }
    249 
    250     ShowWindow(mhMainWnd, SW_SHOW);
    251     UpdateWindow(mhMainWnd);
    252 }
    253 
    254 void D3DApp::initDirect3D()
    255 {
    256     // 描述交换链
    257     DXGI_SWAP_CHAIN_DESC sd;
    258     sd.BufferDesc.Width = mClientWidth;
    259     sd.BufferDesc.Height = mClientHeigth;
    260     sd.BufferDesc.RefreshRate.Numerator = 60;
    261     sd.BufferDesc.RefreshRate.Denominator = 1;
    262     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    263     sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    264     sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    265     sd.SampleDesc.Count = 1;    // 多重采样数量和质量级别
    266     sd.SampleDesc.Quality = 0;
    267     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;    // 将它用作渲染目标
    268     sd.BufferCount = 1;
    269     sd.OutputWindow = mhMainWnd;
    270     sd.Windowed = true;
    271     sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    272     sd.Flags = 0;
    273 
    274     UINT createDeviceFlags = 0;
    275     // 创建设备和交换链
    276     D3D10CreateDeviceAndSwapChain(0, md3dDriverType, 0, createDeviceFlags,
    277         D3D10_SDK_VERSION, &sd, &mSwapChain, &md3dDevice);
    278 
    279     //onResize();    //在该程序中可以使用此句代替下面语句
    280 
    281     // 创建渲染目标视图
    282     ID3D10Texture2D* backBuffer;
    283     mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer));
    284     md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
    285     backBuffer->Release();//每调用一次IDXGISwapChain::GetBuffer,后台缓冲区的COM引用计数向上递增一次,所以释放
    286 
    287     // 创建深度/模板缓冲区及其视图
    288     D3D10_TEXTURE2D_DESC depthStencilDesc;
    289     depthStencilDesc.Width = mClientWidth;
    290     depthStencilDesc.Height = mClientHeigth;
    291     depthStencilDesc.MipLevels = 1;
    292     depthStencilDesc.ArraySize = 1;
    293     depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    294     depthStencilDesc.SampleDesc.Count = 1;
    295     depthStencilDesc.SampleDesc.Quality = 0;
    296     depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
    297     depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
    298     depthStencilDesc.CPUAccessFlags = 0;
    299     depthStencilDesc.MiscFlags = 0;
    300     md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer);
    301     md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView);
    302 
    303     // 将视图绑定到输出合并器阶段
    304     md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
    305 
    306     // 设置视口
    307     // 通过修改视口,可以把3D场景渲染到后台缓冲区的一个子矩形区域中
    308     D3D10_VIEWPORT vp;
    309     vp.TopLeftX = 0;
    310     vp.TopLeftY = 0;
    311     vp.Width = mClientWidth;
    312     vp.Height = mClientHeigth;
    313     vp.MinDepth = 0.0f;
    314     vp.MaxDepth = 1.0f;
    315     md3dDevice->RSSetViewports(1, &vp);
    316 
    317 }
    318 
    319 LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    320 {
    321     static D3DApp* app = 0;
    322     switch (msg)
    323     {
    324     case WM_CREATE:
    325     {
    326                       // CREATESTRUCT结构定义了应用程序中窗口过程的初始化参数
    327                       CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
    328                       app = (D3DApp*)cs->lpCreateParams;
    329                       return 0;
    330     }
    331     }
    332 
    333     if (app)
    334         return app->msgProc(msg, wParam, lParam);
    335     else
    336         return DefWindowProc(hwnd, msg, wParam, lParam);
    337 }
    338 
    339 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
    340 {
    341     D3DApp theApp(hInstance);
    342 
    343     theApp.initApp();
    344     theApp.run();
    345 
    346     return 0;
    347 }
  • 相关阅读:
    1025. 除数博弈
    剑指 Offer 12. 矩阵中的路径
    64. 最小路径和
    剑指 Offer 07. 重建二叉树-7月22日
    为人工智能、机器学习和深度学习做好准备的数据中心实践
    在云应用程序中加强隐私保护的9种方法
    迎接物联网时代 区块链大有可为
    Science 好文:强化学习之后,机器人学习瓶颈如何突破?
    学会这5招,让Linux排障更简单
    云游戏:5G时代的王牌应用
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4453392.html
Copyright © 2020-2023  润新知