ホーム < ゲームつくろー! < DirectX10技術編

その3 板ポリをワールドへ : サンプルプログラム



 DirectX10技術編その3「板ポリをワールドへ」で説明した内容を踏まえたサンプルプログラムです。実行すると、回転する正三角形が1枚画面に表示されます。


サンプルスクリーンショット

 以下のプログラムは新規プロジェクトにコピペすると動きます。上からデバッグしていくと、何をしているか良くわかるように1つのソースで完結させています。シェーダファイル等の関連ファイルはこちらからダウンロードできます

(もしうまく動かない、プログラムへの組み込み方がわからない等ございましたら掲示板にてご連絡下さい)

// DirectX10シンプルビルボードサンプルプログラム

#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "d3d10.lib")
#if _DEBUG
 #pragma comment(lib, "d3dx10d.lib")
#else
 #pragma comment(lib, "d3dx10.lib")
#endif
#pragma comment(lib, "dxerr.lib")

#include <windows.h>
#include <tchar.h>
#include <dxerr.h>
#include <d3d10.h>
#include <d3dx10.h>

_TCHAR gName[] = _T("DirectX10シンプルビルボードサンプルプログラム");

// 頂点構造体
struct MyVertex {
        D3DXVECTOR3 Pos;
        D3DXVECTOR3 Color;
};

// ウィンドウプロシージャ
LRESULT CALLBACK WndProc( HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam ) {
   if( mes == WM_DESTROY || mes == WM_CLOSE ) { PostQuitMessage( 0 ); return 0; }
   return DefWindowProc( hWnd, mes, wParam, lParam );
}

int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
   MSG msg; HWND hWnd;
   WNDCLASSEX wcex = { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, NULL, NULL,
                                    (HBRUSH)(COLOR_WINDOW+1), NULL, (_TCHAR*)gName, NULL };
   if( !RegisterClassEx( &wcex ) )
      return 0;

   if( !( hWnd = CreateWindow( gName, gName, WS_OVERLAPPEDWINDOW & ~( WS_MAXIMIZEBOX | WS_SIZEBOX ),
                                 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, 0) ) )
       return 0;

   DXGI_SWAP_CHAIN_DESC SwapChainDesc =
   {  { 800, 600, {60, 1}, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, DXGI_MODE_SCALING_CENTERED},
      {1, 0}, DXGI_USAGE_RENDER_TARGET_OUTPUT, 1, hWnd, true, DXGI_SWAP_EFFECT_DISCARD, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
   };

   ID3D10Device* pDev;
   IDXGISwapChain* pSwapChain;
   if( FAILED( D3D10CreateDeviceAndSwapChain( 0, D3D10_DRIVER_TYPE_HARDWARE, 0, 0, D3D10_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDev ) ) )
           return 0;

   ID3D10Texture2D *pBackBuffer;
   ID3D10RenderTargetView *pRenderTargetView;
   pSwapChain->GetBuffer( 0, __uuidof(ID3D10Texture2D), (void**)&pBackBuffer );
   if ( FAILED ( pDev->CreateRenderTargetView( pBackBuffer, 0, &pRenderTargetView ) ) ) {
           pSwapChain->Release(); pDev->Release();
           return 0;
   };
   pDev->OMSetRenderTargets( 1, &pRenderTargetView, 0 );
   pBackBuffer->Release();

   D3D10_VIEWPORT vp = { 0, 0, 800, 600, 0.0f, 1.0f };
   pDev->RSSetViewports( 1, &vp );

   // 頂点作成
   MyVertex vtx[] = {
           D3DXVECTOR3( cos(D3DXToRadian(-30.0f)), sin(D3DXToRadian(-30.0f)), 0.5f ), D3DXVECTOR3( 1.0f, 1.0f, 1.0f ),
           D3DXVECTOR3( cos(D3DXToRadian(-150.0f)), sin(D3DXToRadian(-150.0f)), 0.5f ), D3DXVECTOR3( 1.0f, 1.0f, 1.0f ),
           D3DXVECTOR3( cos(D3DXToRadian(90.0f)), sin(D3DXToRadian(90.0f)), 0.5f ), D3DXVECTOR3( 1.0f, 1.0f, 1.0f )
   };

   // 頂点情報
   D3D10_INPUT_ELEMENT_DESC MyVertexDesc[] = {
           { "POSITION_IN", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
           { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(D3DXVECTOR3), D3D10_INPUT_PER_VERTEX_DATA, 0 },
   };

   // 頂点バッファを作成
   D3D10_BUFFER_DESC BufferDesc = {
           3 * sizeof( MyVertex ), D3D10_USAGE_DEFAULT, D3D10_BIND_VERTEX_BUFFER, 0, 0
   };
   D3D10_SUBRESOURCE_DATA SubResourceData;
   SubResourceData.pSysMem = vtx;
   ID3D10Buffer *pBuffer;
   if ( FAILED ( pDev->CreateBuffer( &BufferDesc, &SubResourceData, &pBuffer ) ) ) {
      pRenderTargetView->Release();
      pDev->Release();
      pSwapChain->Release();
          return 0;
   }
   UINT stride = sizeof( MyVertex );
   UINT offset = 0;
   pDev->IASetVertexBuffers( 0, 1, &pBuffer, &stride, &offset );

   // プリミティブ定義
   pDev->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

   // 頂点レイアウト作成
   D3D10_PASS_DESC PassDesc;
   ID3D10InputLayout *pVertexLayout;
   ID3D10EffectTechnique *pTechnique;
   ID3D10Effect *pEffect;
   ID3D10Blob *pBlob;
   if ( FAILED ( D3DX10CreateEffectFromFile(
           L"MyShader.fx", 0, 0, "fx_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, pDev, 0, 0, &pEffect, &pBlob, 0 ) ) )
   {
      const char* err = (const char*)pBlob->GetBufferPointer();
      pBuffer->Release();
      pRenderTargetView->Release(); pDev->Release(); pSwapChain->Release();
          return 0;
   }
   pTechnique = pEffect->GetTechniqueByName( "SimpleRender" );
   pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
   if ( FAILED ( pDev->CreateInputLayout(
           MyVertexDesc, sizeof(MyVertexDesc)/sizeof(D3D10_INPUT_ELEMENT_DESC),
           PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &pVertexLayout ) ) )
   {
      pEffect->Release(); pBuffer->Release();
      pRenderTargetView->Release(); pDev->Release(); pSwapChain->Release();
          return 0;
   }
   pDev->IASetInputLayout( pVertexLayout );

   // 行列を設定する変数インターフェイスを取得
   D3DXMATRIX World, Rot_X, Rot_Z, View, Proj;
   D3DXMatrixLookAtLH( &View, &D3DXVECTOR3(0,0,-2.0f), &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,1,0) );
   D3DXMatrixPerspectiveFovLH( &Proj, D3DXToRadian(45.0f), 640.0f/480.0f, 0.1f, 100.0f );

   ID3D10EffectMatrixVariable *pWorldMatVar = pEffect->GetVariableByName("g_World")->AsMatrix();
   ID3D10EffectMatrixVariable *pViewMatVar = pEffect->GetVariableByName("g_View")->AsMatrix();
   ID3D10EffectMatrixVariable *pProjMatVar = pEffect->GetVariableByName("g_Proj")->AsMatrix();

   pViewMatVar->SetMatrix( (float*)&View );
   pProjMatVar->SetMatrix( (float*)&Proj );

   ShowWindow( hWnd, SW_SHOW );

   D3D10_TECHNIQUE_DESC techDesc;
   float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA
   float angle = 0.0f;
   do{
      if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){ DispatchMessage( &msg ); }
          else {
                  // DirectX10の処理 //
                  // 回転
                  D3DXMatrixRotationZ( &World, (float)D3DXToRadian(angle+=0.04f) );
                  pWorldMatVar->SetMatrix( (float*)&World );

                  pDev->ClearRenderTargetView( pRenderTargetView, ClearColor );
                  pTechnique->GetDesc( &techDesc );
                  for ( UINT p = 0; p < techDesc.Passes; ++p ) {
                          pTechnique->GetPassByIndex( p )->Apply( 0 );
                          pDev->Draw( 3, 0 );
                  }
          pSwapChain->Present( 0, 0 );
          }
   }while( msg.message != WM_QUIT );

   pRenderTargetView->Release();
   pDev->Release();
   pSwapChain->Release();

   return 0;
}