~プログラミング~ DirectX 11の初期化をしよう その2

C++言語でDirectX 11を使ったアプリケーションを開発してみよう。

まずはDirectXを初期化するところから。

 

とりあえず、初期化して背景を青にするところまでをコーディングしてみます。

サンプルコード

sample.h

class CD3D11 {
public:
    ID3D11Device*           m_pDevice;
    ID3D11DeviceContext*    m_pImmediateContext;
    IDXGISwapChain*         m_pSwapChain;
    ID3D11RenderTargetView* m_pRenderTargetView;

public:
            CD3D11();
    virtual ~CD3D11();
    virtual HRESULT Create( HWND hwnd );
    virtual void    Release();
    virtual void    Render();
};

sample.cpp

CD3D11::CD3D11()
{
    m_pDevice           = NULL;
    m_pImmediateContext = NULL;
    m_pSwapChain        = NULL;
    m_pRenderTargetView = NULL;
}

CD3D11::~CD3D11()
{
    Release();
}

HRESULT CD3D11::Create( HWND hwnd )
{
    HRESULT  hr;


    UINT flags = 0;
#ifdef _DEBUG
    flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
    D3D_FEATURE_LEVEL pLevels[] = { D3D_FEATURE_LEVEL_11_0 };
    D3D_FEATURE_LEVEL level;

    CRect                rect;
    DXGI_SWAP_CHAIN_DESC scDesc;
        
    ::GetClientRect( hwnd, &rect );
    ::ZeroMemory( &scDesc, sizeof( scDesc ) );
    scDesc.BufferCount        = 1;
    scDesc.BufferDesc.Width   = rect.Width();
    scDesc.BufferDesc.Height  = rect.Height();
    scDesc.BufferDesc.Format  = DXGI_FORMAT_R8G8B8A8_UNORM;
    scDesc.BufferUsage        = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    scDesc.OutputWindow       = hwnd;
    scDesc.SampleDesc.Count   = 1;
    scDesc.SampleDesc.Quality = 0;
    scDesc.Windowed           = TRUE;

    hr = D3D11CreateDeviceAndSwapChain( NULL,
                                D3D_DRIVER_TYPE_HARDWARE,
                                NULL,
                                flags,
                                pLevels,
                                1,
                                D3D11_SDK_VERSION,
                                &scDesc,
                                &m_pSwapChain,
                                &m_pDevice,
                                &level,
                                &m_pImmediateContext );
    if ( FAILED( hr ) )
        return hr;


    ID3D11Texture2D* pBackBuffer;

    hr = m_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&pBackBuffer );
    if ( FAILED( hr ) )
        return hr;

    hr = m_pDevice->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderTargetView );
    pBackBuffer->Release();
    if ( FAILED( hr ) )
        return hr;
    return hr;
}

void CD3D11::Release()
{
    if( m_pImmediateContext ) {
        m_pImmediateContext->ClearState();
    }

    if ( NULL != m_pRenderTargetView ) {
        m_pRenderTargetView->Release();
        m_pRenderTargetView = NULL;
    }
    if ( NULL != m_pSwapChain ) {
        m_pSwapChain->Release();
        m_pSwapChain = NULL;
    }
    if ( NULL != m_pImmediateContext ) {
        m_pImmediateContext->Release();
        m_pImmediateContext = NULL;
    }
    if ( NULL != m_pDevice ) {
        m_pDevice->Release();
        m_pDevice = NULL;
    }
}

void CD3D11::Render()
{
    if ( NULL == m_pDevice ) return;
    if ( NULL == m_pImmediateContext ) return;
    if ( NULL == m_pRenderTargetView ) return;
    if ( NULL == m_pSwapChain ) return;

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

    m_pImmediateContext->OMSetRenderTargets( 1, &m_pRenderTargetView, NULL );
    m_pImmediateContext->ClearRenderTargetView( m_pRenderTargetView, clearColor );
    m_pSwapChain->Present( 0, 0 );
}

CD3D11::Createメソッド

初期化時に呼び出すことを想定したメソッド。

 

D3D11CreateDeviceAndSwapChainで初期化 (19~52行目)

HWNDからウインドウサイズを取得しつつ、機能レベル「11_0」で初期化をしています。

 

ID3D11RenderTargetViewオブジェクトを作成 (57~64行目)

スワップチェーンのバックバッファーからレンダーターゲットのビューを作成しています。

GetBufferメソッドでテクスチャリソースを取得し、そこからビューを生成します。

使い終わったテクスチャリソースは忘れずにReleaseしましょう。

CD3D11::Renderメソッド

描画の度に呼び出される事を想定したメソッド。

ビューをレンダーターゲットにセットして、背景色でクリアしているだけです。

 

描画が終わったらIDXGISwapChain::Presentでチェーンバッファを切り替えて画面に表示させています。