程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> DX筆記之一---Direct3D基礎,dx筆記---direct3d

DX筆記之一---Direct3D基礎,dx筆記---direct3d

編輯:C++入門知識

DX筆記之一---Direct3D基礎,dx筆記---direct3d


一、預備知識

1、表面

表面就是Direct3D用於儲存2D圖像數據的一個像素矩陣。width和height以像素為單位,pitch以字節單位,用接口IDirect3DSurface來描述表面

LockRect:該方法用於獲取指向表面存儲區的指針,通過通過指針運算,可對每個像素進行讀寫操作;

UnlockRect:配對使用,調用lock必須unlock,解除對表面存儲區的鎖定;

GetDesc: 獲取表面的描述信息,通過填充D3DSURFACE_DESC;

//Assume _surface is a pointer to an IDirect3DSurface9 interface
//Assume a 32-bit pixel format for each pixel

//Get the surface description.
D3DSURFACE_DESC surfaceDesc;
_surface->GetDesc(&surfaceDesc);


//Get a pointer to the surface pixel data
D3DLOCKED_RECT lockedRect;
_surface->LockRect(
    &lockedRect,
    0,
    0);

//Iterate through each pixel in the surface and set it to red
DWORD *imageData = (DWORD *)lockedRect.pBits;
for (int i = 0; i < surfaceDesc.height; ++i)
{
    for (int j = 0; j < surfaceDesc.width; ++j)
    {
        int nIndex = i * lockedRect.pitch / 4 + j;
        imageData[nIndex] = 0xffff000;
    }
}
_surface->UnlockRect();

2、多重采樣

多重采樣(multisampling)一項用於平滑塊狀圖像的技術

D3DMULTISAMPLE_TYPE:Defines the levels of full-scene multisampling that the device can apply.

typedef enum D3DMULTISAMPLE_TYPE
{
    D3DMULTISAMPLE_NONE = 0,
    D3DMULTISAMPLE_NONMASKABLE  = 1,
    D3DMULTISAMPLE_2_SAMPLES = 2,
    D3DMULTISAMPLE_3_SAMPLES = 3,
    D3DMULTISAMPLE_4_SAMPLES = 4,
    D3DMULTISAMPLE_5_SAMPLES = 5,
    D3DMULTISAMPLE_6_SAMPLES = 6,
    D3DMULTISAMPLE_7_SAMPLES = 7,
    D3DMULTISAMPLE_8_SAMPLES = 8,
    D3DMULTISAMPLE_9__SAMPLES = 9,
    D3DMULTISAMPLE_10_SAMPLES = 10,
    D3DMULTISAMPLE_11_SAMPLES = 11,
    D3DMULTISAMPLE_12_SAMPLES = 12,
    D3DMULTISAMPLE_13_SAMPLES = 13,
    D3DMULTISAMPLE_14_SAMPLES = 14,
    D3DMULTISAMPLE_15_SAMPLES = 15,
    D3DMULTISAMPLE_16_SAMPLES = 16,
    D3DMULTISAMPLE_FORCE_DWORD = 0xffffffff,
} D3DMULTISAMPLE_TYPE, *LPD3DMULTISAMPLE_TYPE;

3、像素格式D3DFORMAT

創建表面或者紋理(texture)時需要指定像素格式

D3DFMT_R8G8B8 D3DFMT_X8R8G8B8 D3DFMT_A8R8G8B8 D3DFMT_A16B16G16R16F D3DFMT_A32B32G32R32F D3DFMT_DXT5

4、內存池

D3D RUTIME的內存類型,分為3種,VIDEO MEMORY(VM)、AGP MEMORY(AM)和SYSTEM MEMORY(SM)

 

VIDEO MEMORY(VM):VM就是位於顯卡上的顯存,CPU只能通過AGP或PCI-E總線訪問到,讀寫速度都是非常慢的,
                               CPU連續寫VM稍微快於讀,因為CPU寫VM時會在CACHE中分配32或64個字節(取決於CACHE LINE長度)
                               的寫緩沖,當緩沖滿後會一次性寫入VM;

SYSTEM MEMORY(SM):SM就是系統內存,CPU讀寫都非常快,
                                  因為SM是被CACHE到2級緩沖的,但GPU卻不能直接訪問到系統緩沖,所以創建在SM中的資源,
                                  GPU是不能直接使用的;

AGP MEMORY(AM):AM是最麻煩的一個類型,AM實際也存在於系統內存中,
                            但這部分MEM不會被CPU CACHE,意味著CPU讀寫AM都會寫來個CACHE MISSING然後才通過內存總線訪問AM,
                            所以CPU讀寫AM相比SM會比較慢,但連續的寫會稍微快於讀,
                            原因就是CPU寫AM使用了“write combining”,而且GPU可以直接通過AGP或PCI-E總線訪問AM

 

所有D3D資源都創建在這3種內存之中,在創建資源時,我們可以指定如下存儲標志,
D3DPOOL_DEFAULT、D3DPOOL_MANAGED、D3DPOOL_SYSTEMMEM和D3DPOOL_SCRATCH

 

D3DPOOL_DEFAULT:默認值,該類型的內存池指示Direct3D將資源放入最適合該資源類型極其適用方式的存儲區中。該存儲區可能是顯存,AGP存儲區或系統存儲區。注意,調用IDirect3DDevice9::Reset之前,必須對默認內存池中的資源銷毀或釋放。上述函數調用後,還必須對內存池中的資源重新初始化。
D3DPOOL_MANAGE:放入該托管內存池中的資源交由Direct3D管理(即資源將根據需要被設備自動轉移到顯存或AGP存儲區中)。此外,這些資源將在系統存儲區中保留一個備份。這樣,必要時,Direct3D會將這些資源自動更新到顯存中。
D3DPOOL_SYSTEMMEM:指定將資源放入系統存儲區中。
D3DPOOL_SCRATCH:指定將資源放入系統存儲區中。不同於D3DPOOL_SYSTEMMEM,這些資源不受圖形設備的制約。所以,設備無法訪問該類型內存池中的資源。但這些資源之間可互相復制。

 

5、交換鏈和頁面置換

Direct3D維護著一個表面集合,該集合通常由兩到三個表面組成,稱為交換鏈。該集合用接口IDirect3DSwapChain9來表示。

交換鏈和頁面置換技術主要用於生成更加平滑的動畫。

 

6、深度緩存

深度緩存是一個只含有特定像素的深度信息而不含圖像數據的表面。深度緩存為最終繪制的圖像中的每一個像素都保留了一個深度項。所以,當繪制的圖像的分辨率為640X800,深度緩存中有640X800個深度項。

     前面物體部分遮擋位於其後的物體,Direct3D為了判定某一個物體的哪些像素位於另一個物體之前。使用了一項稱為深度緩存或z-緩存的技術。

     深度緩存用於計算每個像素的深度值,並進行深度測試。深度測試的基本內容是依據深度值讓處於同一位置的不同像素進行競爭。以選出應寫入該位置的像素。距離攝像機最近的像素獲勝,並被寫入深度緩存的相應位置。

     深度緩存的格式決定了深度測試的精度。24位的深度緩存要比16位的深度緩存精確得多。

     D3DFMT_D32:32位深度緩存。
     D3DFMT_D24S8:24位深度緩存,其中8位保留供模板緩存使用。
     D3DFMT_D24X8:僅指定24位深度緩沖。
     D3DFMT_X4S4:指定24位深度緩存,其中4位保留供模板緩存使用。
     D3DFMT_D16:僅指定16位深度緩存。

 

二、Direct3D的初始化

1、獲取接口IDirect3D9的指針

IDirect3D9* Direct3DCreate9(
  UINT SDKVersion
);
Create an IDirect3D9 object and return an interface to it.

SDKVersion:The value of this parameter should be D3D_SDK_VERSION
//step 1: Create the IDirect3D9 object
    IDirect3D9 d3d9;
    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
 

2、校驗硬件頂點運算

//step 2: Check for hardware vp
    //     HRESULT GetDeviceCaps(
    //         [in]   UINT Adapter,
    //         [in]   D3DDEVTYPE DeviceType,
    //         [out]  D3DCAPS9 *pCaps
    //         );
    // Adapter [in]
    // Type: UINT
    //           Ordinal number that denotes the display adapter. D3DADAPTER_DEFAULT is always the primary display adapter.
    // DeviceType [in]
    // Type: D3DDEVTYPE
    //           Member of the D3DDEVTYPE enumerated type. Denotes the device type.
    // pCaps [out]
    // Type: D3DCAPS9*
    //           Pointer to a D3DCAPS9 structure to be filled with information describing the capabilities of the device.
    D3DCAPS9 caps;
    d3d9.GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

    int vp = 0;
    if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    else
        vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
3、填充D3DPRESENT_PARAMETER結構
//step 3: Fill out the D3DPRESENT_PARAMETERS structure.

    D3DPRESENT_PARAMETERS d3dpp;
    d3dpp.BackBufferWidth                = nWidth;                        //後台緩沖中表面的寬度,單位為像素
    d3dpp.BackBufferHeight                = nHeight;                        //後台緩沖中表面的高度,單位為像素
    d3dpp.BackBufferFormat                = D3DFMT_A8R8G8B8;                //後台緩沖的像素格式
    d3dpp.BackBufferCount                = 1;                            //需要時用的後台緩存個數,通常為1
    d3dpp.MultiSampleType                = D3DMULTISAMPLE_NONE;            //後台緩存使用的多重采樣類型
    d3dpp.MultiSampleQuality            = 0;                            //多重采樣質量水平
    d3dpp.SwapEffect                    = D3DSWAPEFFECT_DISCARD;        //D3DSWAPEFFECT枚舉類型的一個成員,該類型指定了交換鏈中的緩沖的頁面置換方式,D3DSWAPEFFECT_DISCARD時效果最高
    d3dpp.hDeviceWindow                    = hWnd;                            //指定所以進行繪制的應用程序窗口
    d3dpp.Windowed                        = bWindowed;                    //true:窗口模式 false:全屏模式
    d3dpp.EnableAutoDepthStencil        = true;                            //true:Dierct3D自動創建並維護深度緩存或者模板緩存
    d3dpp.AutoDepthStencilFormat        = D3DFMT_D24S8;                    //深度緩存或者模板緩存的像素格式(D3DFMT_D24S8 24位深度,8位模板)
    d3dpp.Flags                            = 0;                            //附加特性 0無標記或D3DPRESENTFLAG集合中的一個成員 常用的2個 
                                                                        //D3DPRESENTFLAG_LOCKABLE_DEPTHBUFFER 指定可鎖定後台緩存,可能會減低性能
                                                                        //D3DPRESENTFLAG_DISCARD_DEPTHBUFFER 指定當下一個後台緩存提交時,哪個深度或者模板緩存將被丟棄。這樣可以提升性能;
    d3dpp.FullScreen_RefreshRateInHz    = D3DPRESENT_RATE_DEFAULT;        //刷新頻率
    d3dpp.PresentationInterval            = D3DPRESENT_INTERVAL_IMMEDIATE;//D3DPRESENT集合中的一個成員,
                                                                        //D3DPRESENT_INTERVAL_IMMEDIATE 立即提交
 

4、創建IDirect3DDevice9接口

hResult = d3d9->CreateDevice(
        D3DADAPTER_DEFAULT, // primary adapter
        deviceType,         // device type
        hWnd,               // window associated with device
        vp,                 // vertex processing
        &d3dpp,             // present parameters
        device);            // return created device

    if(FAILED(hResult))
    {
        // try again using a 16-bit depth buffer
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

        hResult = d3d9->CreateDevice(
            D3DADAPTER_DEFAULT,
            deviceType,
            hWnd,
            vp,
            &d3dpp,
            device);

        if(FAILED(hResult))
        {
            d3d9->Release(); // done with d3d9 object
            ::MessageBox(0, "CreateDevice() - FAILED", 0, 0);
            return false;
        }
    }

最後貼一下自己的成果,雖然基本是從龍書上copy下來 o(╯□╰)o


對於dxdiag與Direct3D的一個問題

你在運行中輸入dxdiag然後會出來DirectX診斷工具,選擇顯示,啟用Direct3D加速。



 

開始-運行-dxdiag-顯示Direct3D不可用怎辦

把顯卡驅動再安裝一邊。

驅動精靈是驅動之家的出品。
是專業驅動工具。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved