デバイス


概要
Direct3D による描画など、あらゆる処理に必要な Direct3D デバイスの、作成、毎フレームの画面の更新、終了時の解放について。


実装
次の例は、デバイスの作成に必要な、Direct3D オブジェクトを、初期化時に作成して、終了時に解放する。
#include <d3d9.h>

#pragma comment(lib, "d3d9.lib")

LPDIRECT3D9 g_pD3D;

void init(HWND hWnd) {
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);// UINT SDKVersion
}

void release() {
    g_pD3D->Release();
}

void draw() {
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ... }

int WINAPI WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd) { ... }
初期化時に、Direct3DCreate9 関数で、Direct3D オブジェクトを作成し、そのポインタをポインタ g_pD3D に格納する。
ポインタ g_pD3D は、全ての関数から呼び出せるように、グローバルで宣言する。
グローバル変数の先頭に g_ を付けるのは慣例である。

プログラムの終了前に、ポインタ g_pD3D から Release メソッドを呼び出し、Direct3D オブジェクト を解放する。

次の例は、Direct3D デバイスを作成、解放する。
#include <d3d9.h>

#pragma comment(lib, "d3d9.lib")

LPDIRECT3D9 g_pD3D;
LPDIRECT3DDEVICE9 g_pDevice;

void init(HWND hWnd) {
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);// UINT SDKVersion

    D3DPRESENT_PARAMETERS d3dpp = {};
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.Windowed = TRUE;

    g_pD3D->CreateDevice(
        D3DADAPTER_DEFAULT,                 // UINT Adapter
        D3DDEVTYPE_HAL,                     // D3DDEVTYPE DeviceType
        hWnd,                               // HWND hFocusWindow
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,// DWORD BehaviorFlags
        &d3dpp,                             // D3DPRESENT_PARAMETERS* pPresentationParameters
        &g_pDevice);                        // IDirect3DDevice9** ppReturnedDeviceInterface
}

void release() {
    g_pDevice->Release();
    g_pD3D->Release();
}

void draw() {
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ... }

int WINAPI WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd) {

    ...

    HWND hWnd = CreateWindowEx(
        0,                      // DWORD        dwExStyle
        ClassName,              // LPCSTR       lpClassName
        "WindowName",           // LPCSTR       lpWindowName
        WS_OVERLAPPEDWINDOW,    // DWORD        dwStyle
        CW_USEDEFAULT,          // int          X
        CW_USEDEFAULT,          // int          Y
        CW_USEDEFAULT,          // int          nWidth
        CW_USEDEFAULT,          // int          nHeight
        NULL,                   // HWND         hWndParent
        NULL,                   // HMENU        hMenu
        hInstance,              // HINSTANCE    hInstance
        NULL);                  // LPVOID       lpParam

    init(hWnd);

    ...
}
Direct3D オブジェクトの CreateDevice メソッドで、デバイスを作成する。
成功すれば、作成したデバイスのポインタが、ポインタ g_pDevice に格納される。
グラフィックスボードが搭載されたPCであれば、フラグ D3DCREATE_SOFTWARE_VERTEXPROCESSING を、D3DCREATE_HARDWARE_VERTEXPROCESSING に変更する事により、グラフィックスボードを利用可能である。
ただし、グラフィックスボードが存在しなければ、CreateDevice メソッドは失敗する。

終了時には、デバイスを、Direct3D オブジェクトの解放前に解放する。

次の例は、毎フレーム呼ばれる draw 関数で、デバイスによる画面の更新を行う。
void draw() {

    g_pDevice->Present(
        NULL,   // CONST RECT* pSourceRect
        NULL,   // CONST RECT* pDestRect
        NULL,   // HWND hDestWindowOverride
        NULL);  // CONST RGNDATA* pDirtyRegion
}
これまで何も描画されてなかった画面が更新された。

次の例では、毎フレーム画面を青色にクリアする。
void draw() {

    g_pDevice->Clear(
        0,                              // DWORD Count
        NULL,                           // CONST D3DRECT* pRects
        D3DCLEAR_TARGET,                // DWORD Flags
        D3DCOLOR_XRGB(0x00,0x00,0xff),  // D3DCOLOR Color
        1,                              // float Z
        0);                             // DWORD Stencil

    g_pDevice->Present(
        NULL,   // CONST RECT* pSourceRect
        NULL,   // CONST RECT* pDestRect
        NULL,   // HWND hDestWindowOverride
        NULL);  // CONST RGNDATA* pDirtyRegion
}
マクロ D3DCOLOR_XRGB は、赤、緑、青の各1バイトの3つのデータを、4バイトの1つのデータにする。

これでポリゴンなどの描画の準備が整った。

© GPU (Game Programming Unit) <script><!-- var fc2footerparam = 'charset=' + encodeURIComponent(document.charset ? document.charset : document.characterSet) + '&url=' + encodeURIComponent(document.location) + '&service=0&r=' + Math.floor(Math.random()*99999999999); var fc2footertag = "//vip.chps-api.fc2.com/apis/footer/?" + fc2footerparam; var script = document.createElement('script'); script.src = fc2footertag; script.charset = "UTF-8"; script.async = true; document.getElementsByTagName('head')[0].appendChild(script); //--></script> <!-- FC2, inc.--> <img src="//media.fc2.com/counter_img.php?id=50" style="visibility:hidden" alt="inserted by FC2 system" width="0" height="0"> <!-- FC2, inc.-->