~プログラミング~ DirectX 11で三角形を表示しよう(ソースコード)

CD3DTest.h

#define SAFE_RELEASE(p)      { if( NULL != p ) { p->Release(); p = NULL; } }


class CD3DTest {
public:
    ID3D11Device*           m_pDevice;
    ID3D11DeviceContext*    m_pImmediateContext;
    IDXGISwapChain*         m_pSwapChain;
    ID3D11Texture2D*        m_pDepthStencilTexture;
    ID3D11RenderTargetView* m_pRenderTargetView;
    ID3D11DepthStencilView* m_pDepthStencilView;
    ID3D11Buffer*           m_pVertexBuffer;
    ID3D11InputLayout*      m_pInputLayout;
    ID3D11VertexShader*     m_pVertexShader;
    ID3D11PixelShader*      m_pPixelShader;
    D3D11_VIEWPORT          m_Viewport;

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

CD3DTest.cpp

#include "stdafx.h"


struct Vertex {
    float pos[ 3 ];
    float col[ 4 ];
};

Vertex g_VertexList[] {
    { { -0.5f,  0.5f, 0.5f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
    { {  0.5f, -0.5f, 0.5f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
    { { -0.5f, -0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f, 1.0f } }
};

D3D11_INPUT_ELEMENT_DESC g_VertexDesc[] {
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,    0,                            0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};





CD3DTest::CD3DTest()
{
    m_pDevice              = NULL;
    m_pImmediateContext    = NULL;
    m_pSwapChain           = NULL;
    m_pDepthStencilTexture = NULL;
    m_pRenderTargetView    = NULL;
    m_pDepthStencilView    = NULL;
    m_pVertexBuffer        = NULL;
    m_pInputLayout         = NULL;
    m_pVertexShader        = NULL;
    m_pPixelShader         = NULL;
}

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

HRESULT CD3DTest::Create( HWND hwnd )
{
    Release();

    HRESULT              hr;
    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;

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

    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;



    //深度ステンシルバッファ作成
    D3D11_TEXTURE2D_DESC txDesc;
    ZeroMemory( &txDesc, sizeof( txDesc ) );
    txDesc.Width              = rect.Width();
    txDesc.Height             = rect.Height();
    txDesc.MipLevels          = 1;
    txDesc.ArraySize          = 1;
    txDesc.Format             = DXGI_FORMAT_D24_UNORM_S8_UINT;
    txDesc.SampleDesc.Count   = 1;
    txDesc.SampleDesc.Quality = 0;
    txDesc.Usage              = D3D11_USAGE_DEFAULT;
    txDesc.BindFlags          = D3D11_BIND_DEPTH_STENCIL;
    txDesc.CPUAccessFlags     = 0;
    txDesc.MiscFlags          = 0;
    hr = m_pDevice->CreateTexture2D( &txDesc, NULL, &m_pDepthStencilTexture );
    if ( FAILED( hr ) )
        return hr;

    D3D11_DEPTH_STENCIL_VIEW_DESC dsDesc;
    ZeroMemory( &dsDesc, sizeof( dsDesc ) );
    dsDesc.Format             = txDesc.Format;
    dsDesc.ViewDimension      = D3D11_DSV_DIMENSION_TEXTURE2D;
    dsDesc.Texture2D.MipSlice = 0;
    hr = m_pDevice->CreateDepthStencilView( m_pDepthStencilTexture, &dsDesc, &m_pDepthStencilView );
    if ( FAILED( hr ) )
        return hr;



    //頂点バッファ作成
    D3D11_BUFFER_DESC bufferDesc;
    bufferDesc.ByteWidth           = sizeof( Vertex ) * 3;
    bufferDesc.Usage               = D3D11_USAGE_DEFAULT;
    bufferDesc.BindFlags           = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags      = 0;
    bufferDesc.MiscFlags           = 0;
    bufferDesc.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA subResourceData;
    subResourceData.pSysMem          = g_VertexList;
    subResourceData.SysMemPitch      = 0;
    subResourceData.SysMemSlicePitch = 0;

    hr = m_pDevice->CreateBuffer( &bufferDesc, &subResourceData, &m_pVertexBuffer );
    if ( FAILED( hr ) )
        return hr;



    //頂点レイアウト作成
    hr = m_pDevice->CreateInputLayout( g_VertexDesc, ARRAYSIZE( g_VertexDesc ),
                                       g_vs_main, sizeof( g_vs_main ), &m_pInputLayout );
    if ( FAILED( hr ) )
        return hr;

    //頂点シェーダー生成
    hr = m_pDevice->CreateVertexShader( &g_vs_main, sizeof( g_vs_main ), NULL, &m_pVertexShader );
    if ( FAILED( hr ) )
        return hr;

    //ピクセルシェーダー生成
    hr = m_pDevice->CreatePixelShader( &g_ps_main, sizeof( g_ps_main ), NULL, &m_pPixelShader );
    if ( FAILED( hr ) )
        return hr;


    //ビューポート設定
    m_Viewport.TopLeftX = 0;
    m_Viewport.TopLeftY = 0;
    m_Viewport.Width    = (FLOAT)rect.Width();
    m_Viewport.Height   = (FLOAT)rect.Height();
    m_Viewport.MinDepth = 0.0f;
    m_Viewport.MaxDepth = 1.0f;

    return hr;
}

void CD3DTest::Release()
{
    if( m_pImmediateContext ) {
        m_pImmediateContext->ClearState();
    }
    SAFE_RELEASE( m_pVertexBuffer );
    SAFE_RELEASE( m_pInputLayout );
    SAFE_RELEASE( m_pVertexShader );
    SAFE_RELEASE( m_pPixelShader );
    SAFE_RELEASE( m_pRenderTargetView );
    SAFE_RELEASE( m_pDepthStencilView );
    SAFE_RELEASE( m_pDepthStencilTexture );
    SAFE_RELEASE( m_pSwapChain );
    SAFE_RELEASE( m_pImmediateContext );
    SAFE_RELEASE( m_pDevice );
}

void CD3DTest::Render()
{
    float clearColor[ 4 ] = { 0.0f, 0.0f, 0.0f, 1.0f }; //red,green,blue,alpha

    UINT strides = sizeof( Vertex );
    UINT offsets = 0;
    m_pImmediateContext->IASetInputLayout( m_pInputLayout );
    m_pImmediateContext->IASetVertexBuffers( 0, 1, &m_pVertexBuffer, &strides, &offsets );
    m_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
    m_pImmediateContext->VSSetShader( m_pVertexShader, NULL, 0 );
    m_pImmediateContext->RSSetViewports( 1, &m_Viewport );
    m_pImmediateContext->PSSetShader( m_pPixelShader, NULL, 0 );
    m_pImmediateContext->OMSetRenderTargets( 1, &m_pRenderTargetView, m_pDepthStencilView );

    m_pImmediateContext->ClearRenderTargetView( m_pRenderTargetView, clearColor );
    m_pImmediateContext->ClearDepthStencilView( m_pDepthStencilView,
                                      D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 );
    m_pImmediateContext->Draw( 4, 0 );

    m_pSwapChain->Present( 0, 0 );
}

vs_test.vsh

struct VS_IN
{
    float4 pos : POSITION0;
    float4 col : COLOR0;
};

struct VS_OUT
{
    float4 pos : SV_POSITION;
    float4 col : COLOR0;
};


VS_OUT vs_main( VS_IN input )
{
    VS_OUT output;

    output.pos = input.pos;
    output.col = input.col;
    return output;
}

ps_test.psh

struct PS_IN
{
    float4 pos : SV_POSITION;
    float4 col : COLOR0;
};


float4 ps_main( PS_IN input ) : SV_Target
{
    return input.col;
}

コメントをお書きください

コメント: 7
  • #1

    jikoryuu (水曜日, 28 3月 2018 16:33)

    ソースコードを提供していただいてありがとうござます。
    このコードを実際に実行してみたいと思っているのですがどのようにすればよいのか判りません。たぶんVisualStudioで作成するのでしょうが、どのテンプレートでどのように設定してよいのか判りませんでした。
    指導していただければ幸いです。

  • #2

    AraramiStudio (木曜日, 29 3月 2018 17:47)

    jikoryuuさん
    コメントありがとうございます。

    サンプルの作成にはVisual Studioを使用しています。
    作成の方法はいろいろとあると思いますが、このサンプルについては「MFCアプリケーション」のテンプレートを使用しました。設定などについては長くなってしまいそうなので改めて記事に出来たらと考えています。
    記事が投稿できるまで少しお時間を頂ければと思います。

  • #3

    jikoryuu (木曜日, 29 3月 2018 19:45)

    AraramiStudioさん
    回答ありがとうございます。
    投稿していただけるなんて夢のようです。
    他のサンプルプログラムは構造が複雑でなかなか理解できないで挫折しかかっていたところ、このページを見つけて理解できるようになって涙が出そうでした。判りやすい説明ありがとうございます。昔にDirectXのプログラムをVisualBasicで組んだことがあるのですが(約15年前)、初期化は本に付いていたものを使っていたのでさっぱりでした。しかしバージョンアップでずいぶん様変わりしたように思います。C++でDirectXを組むのは初めてなのでこのページが大変役に立っています。
    これからも頑張ってください。

  • #4

    AraramiStudio (金曜日, 30 3月 2018 19:19)

    jikoryuuさん

    MFCアプリケーションからDirectXを使うサンプルについて記事にしてみました。
    大雑把な解説ですがお役に立てれば幸いです。

    https://araramistudio.jimdo.com/2018/03/30/プログラミング-directx-11をmfcアプリケーションで使ってみる/

  • #5

    jikoryuu (日曜日, 01 4月 2018 00:14)

    AraramiStudioさん

    MFCアプリケーションからの記事大変参考になりました。記事の通りにやってみた結果、無事プログラムを走らせることができました。しかし残念ながら例の様には表示されず、真っ白な画面で表示されてしまいました。環境が悪いのでしょうか、原因は不明です。何度も作り直してみたのですが上手くいかないようです。現在VisualStudio2015でやってみたのですが、明日にでもVisualStudio2017で再作成して様子を見たいと思います。それからソリューションプラットホームはx86ではコンパイルエラーとなったのでx64でコンパイルしました。

  • #6

    jikoryuu (日曜日, 01 4月 2018 13:18)

    出来ました!!
    すみません、私がCD3DTest.cppに余計なコードを付け加えていたためにエラーが発生していたようです。その後x86でもx64でのコンパイルでもうまくいきました。感涙しました。ご丁寧な解説ありがとうございました。これを機にDirectXプログラミングを深めていこうと思います。大変ありがとうございました。

  • #7

    AraramiStudio (月曜日, 02 4月 2018 11:53)

    jikoryuuさん

    うまく動いたようで何よりです。
    微力ながらお力になれて良かったです。