• Directx11 HelloWorld之与Directx9的比较


      这些天终于受不了诱惑,决定入手Directx11,看了下一个最basic 的demo,总结下自己的理解。

      先看看整体框架:所有函数的声明。可以看到和D3d9c差不多,都是初始化窗口,创建设备,清理设备,消息循环和渲染。下面我们将看到发生变化的主要是创建设备的InitDevice()函数,其他都是些MFC框架。

      HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ); 

      HRESULT InitDevice();

      void CleanupDevice();

      LRESULT CALLBACK    WndProc( HWND, UINT, WPARAM, LPARAM );

      void Render();

      主函数入口,可以看到和Directx9一样,正如前面说的,后面会看到最大的不一样就是在InitDevice()里面初始化不一样的设备而已。

    int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )

    {

    //    UNREFERENCED_PARAMETER( hPrevInstance );

     //   UNREFERENCED_PARAMETER( lpCmdLine );

        if( FAILED( InitWindow( hInstance, nCmdShow ) ) )

            return 0;

        if( FAILED( InitDevice() ) )

        {

            CleanupDevice();

            return 0;

        }

        // Main message loop

        MSG msg = {0};

        while( WM_QUIT != msg.message )

        {

            if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )

            {

                TranslateMessage( &msg );

                DispatchMessage( &msg );

            }

            else

            {

                Render();

            }

        }

        CleanupDevice();

        return ( int )msg.wParam;

    }

      接下来我们集中讨论下InitDevice()。先看下程序一开始定义的全局变量,并讨论InitDevice()中如何初始化下面一些设备接口。

    //--------------------------------------------------------------------------------------

    // Global Variables

    //--------------------------------------------------------------------------------------

    HINSTANCE               g_hInst = NULL;

    HWND                    g_hWnd = NULL;

    D3D_DRIVER_TYPE         g_driverType = D3D_DRIVER_TYPE_NULL;

    D3D_FEATURE_LEVEL       g_featureLevel = D3D_FEATURE_LEVEL_11_0;

    ID3D11Device*           g_pd3dDevice = NULL;

    ID3D11DeviceContext*    g_pImmediateContext = NULL;

    IDXGISwapChain*         g_pSwapChain = NULL;

    ID3D11RenderTargetView* g_pRenderTargetView = NULL;

      Directx9里面只有一个设备接口:IDirect3DDevice9,而在Directx11中则有三个:device,immediate contexa swap chain。在d3d9里面,渲染以及创建设备的工作都是有device来负责。但是d3d11里面则分开了,device负责创建resouces,immediate contex负责渲染。而swap chain则是交换链,最典型作用负责交换前后台缓存,front buffer和back buffer。(ps下:swap chain在d3d9里面也有了,不过这个接口在D3d9里面用的很少,因为这个接口都是Direct3D负责管理的,不知道在D3d11里面是不是会用的比较多,有待探索)。 front buffer是现在电脑屏幕上正在展现的内容,back buffer是正在后台被渲染的缓存。当back buffer被绘制好了,则将back buffer和front buffer交换。

      为了创建上面说的device,immediate device和swap chain,可以通过调用D3D11CreateDeviceAndSwapChain函数,其原型如下:

      HRESULT D3D11CreateDeviceAndSwapChain( __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,

      __in const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,

      __out IDXGISwapChain **ppSwapChain,

      __out ID3D11Device **ppDevice,

      __out D3D_FEATURE_LEVEL *pFeatureLevel,

      __out ID3D11DeviceContext **ppImmediateContext );

      调用实例:

      hr = D3D11CreateDeviceAndSwapChain( NULL,

      g_driverType,

      NULL,

      createDeviceFlags,

      featureLevels,

      numFeatureLevels,

      D3D11_SDK_VERSION,

      &sd,

      &g_pSwapChain,

      &g_pd3dDevice,

      &g_featureLevel,

      &g_pImmediateContext );

      再看看d3d9中类似的创建设备函数IDirect3D9::CreateDevice():

      HRESULT CreateDevicee( [in] UINT Adapter,

      [in] D3DDEVTYPE DeviceType,

      [in] HWND hFocusWindow,

      [in] DWORD BehaviorFlags,

      [in, out] D3DPRESENT_PARAMETERS *pPresentationParameters,

      [out, retval] IDirect3DDevice9 **ppReturnedDeviceInterface );

      调用实例:

       IDirect3D9* g_pD3D;

       g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,

                                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,

                                          &d3dpp, &g_pd3dDevice ) ;

      下面我们通过函数CreateRenderTargetView()创建一个render target view(类似于c中用空指针void*创建的一片内存区),并将swap chain的back buffer绑定给它,这样D3d11才能渲染back buffer。我对这个概念也不是很理解,个人感觉像是你想要渲染的东西,必须绑定到一个指定的空显存区,然后d3d11渲染管道的输出会写到这块显存中,即完成渲染。

      if( FAILED( g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&pBackBuffer ) ) )

        return FALSE;

      hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );

      pBackBuffer->Release(); if( FAILED( hr ) ) return FALSE;

       接下来我们通过调用immediate context的OMSetRenderTargets()将刚创建的render target view绑定到渲染管道,这样渲染管道的输出会自动写到back buffer中。

      g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );

      InitDevice()的最后就是创建一个视口viewport,和d3d9差不多,但是d3d11中视口是必须要创建的。

      D3D11_VIEWPORT vp;

      vp.Width = (FLOAT)width;

      vp.Height = (FLOAT)height;

      vp.MinDepth = 0.0f;

      vp.MaxDepth = 1.0f;

      vp.TopLeftX = 0;

      vp.TopLeftY = 0;

      g_pImmediateContext->RSSetViewports( 1, &vp );

      最后看看Render().相对d3d9明显简洁了许多,没有了IDirect3DDevice9::begin()和IDirect3DDevice9::end()(连XNA都未能幸免begin和end),直接draw()。

    void Render()

    {

        // Just clear the backbuffer

        float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alpha

        g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );

        g_pSwapChain->Present( 0, 0 );

    }

      剩下几个函数都是和D3d9c差不多了。因为都是一些MFC的框架。

  • 相关阅读:
    冯小刚贺岁片十大经典台词
    网络”X客”大集合:博客、维客、奇客、播客、闪客、摩客、威克…
    [ASP.NET]动态页面调用JS错误。保存为HTML文件就不报错了。
    xp sp2 pro 安装IIS时候出现 安装程序无法复制文件staxmem.dl_
    上传功能出现 asp 0104 不允许操作解决方法
    插入数据库记录时候“输入字符串的格式不正确。 ”
    猪的FLASH-星晴
    Tab Bar Controller 与 Navigation Controller 共存
    iPhone控件之UILabel
    使用MPMoviePlayerViewController播放视频
  • 原文地址:https://www.cnblogs.com/bester/p/3255829.html
Copyright © 2020-2023  润新知