Cubism SDK‎ > ‎プラットフォーム‎ > ‎DirectX‎ > ‎

プロジェクトの作成

Last update: 2014/06/04

ここでは、Visual Studioでのプロジェクト作成から、DirectXでLive2D モデルを描画するまでの手順を説明します。
推奨環境などはSDK付属のReadMeをご覧ください。



用意するもの
  • Visual Studio (ここではVisual Studio 2012を使用します)
            DirectXのダウンロードを済ませておく。
  • Live2D ライブラリ (ダウンロードしたLive2D SDK の「lib」フォルダ。ここでは1.0.02のバージョンを使用します
            
  • Live2D のリソース
本来は、Live2Dのリソースは作成するモデルに応じてそれぞれ用意します。
ここではサンプルプロジェクトの「ハル」のリソースを使って説明をしていきます。

simple/res/haru/
  • haru.moc
  • haru.1024/texture_00.png
  • haru.1024/texture_01.png
  • haru.1024/texture_02.png



◆プロジェクトの設定と下準備
新規プロジェクトを作成して、必要なファイルをインポートしていきます。

Visual Studioのメニューバーの「ファイル(F)」 > 「新規作成(N)」 > 「プロジェクト(P)...」をクリックします。


テンプレートから「Visual C++」 > 「Win32 プロジェクト」を選択し、名前や保存場所を設定して「OK」をクリックします。


「Win32 アプリケーション ウィザード」が表示されるので、「次へ」をクリックします。


次の画面で「空のプロジェクト(E)」のチェックを入れて「完了」をクリックします。



次に、プロジェクトの設定を行います。

プロジェクトを右クリックして「プロパティ(R)」をクリックします。


「構成プロパティ」 > 「全般」を選択して、「文字セット」の項目を「マルチバイト文字セットを使用する」に設定します。


次に、「構成プロパティ」 > 「C/C++」 > 「全般」を選択し、「追加のインクルードディレクトリ」の項目の、
右端にある下向きの三角をクリック > 「<編集...>」をクリックします。


ダイアログが出てくるので、ダイアログ上部の白い枠内に
"include" 、 "$(DXSDK_DIR)\Include" の2つを入力し、OKをクリックします。



同様に、「構成プロパティ」 > 「C/C++」 > 「プリプロセッサ」を選択し、「プリプロセッサの定義」の項目に
"L2D_TARGET_D3D" を追加してOKをクリックします。




「構成プロパティ」> 「リンカー」 > 「全般」 を選択し、「追加のライブラリディレクトリ」の項目に、
"lib" 、 "$(DXSDK_DIR)\Lib\x86" の二つを追加します。




最後に、「構成プロパティ」> 「リンカー」 > 「入力」を選択し、「追加の依存ファイル」の項目に、
"d3d9.lib" 、 "d3dx9.lib" 、 "live2d_directX_mdd.lib" の3つを追加してOKをクリックします。



これでプロジェクトの設定は終了です。
次はプロジェクトに必要なファイルを追加していきます。


プロジェクトを右クリックして「エクスプローラーでフォルダーを開く(X)」をクリックして、フォルダを開きます。


開いたプロジェクトフォルダの中に、SDKフォルダルートにある「include」と「lib」をドラッグアンドドロップ(またはコピー・ペースト)します。


SDKの \sample\Simple にある「res」フォルダも同様に追加します。


プロジェクトに.cppファイルを追加します。ここでは「main.cpp」とします




以上でプロジェクトへの追加は完了です。
これからモデルの読み込み、表示を行います。







main.cppを開き、以下のように記述してウィンドウの作成を行います。
  1. #include <windows.h>
  2.  
  3.  
  4. LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  5.  
  6. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine,int nShow)
  7. {
  8.         MSG msg;
  9.        
  10.         // ウィンドウ作成
  11.         WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
  12.                          WndProc, 00, hInstance, NULLNULL(HBRUSH)(COLOR_WINDOW+1),
  13.                          NULL"DX9_TUTORIAL1_CLASS"NULL};
  14.  
  15.         RegisterClassEx(&wc);
  16.        
  17.         HWND hMainWnd = CreateWindow("DX9_TUTORIAL1_CLASS",
  18.                                      "Live2D Sample",
  19.                                      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800800,
  20.                                      NULLNULL, hInstance, NULL);
  21.        
  22.         // ウィンドウの表示
  23.         ShowWindow(hMainWnd, nShow);
  24.         UpdateWindow(hMainWnd);
  25.        
  26.         while(GetMessage(&msg, NULL00))
  27.         {
  28.                 TranslateMessage(&msg);
  29.                 DispatchMessage(&msg);
  30.         }
  31.        
  32.         return(0);
  33. }
  34.  
  35.  
  36. LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  37. {
  38.         switch(msg)
  39.         {
  40.         case WM_DESTROY:
  41.                 PostQuitMessage(0);
  42.                 return(0);
  43.         }
  44.        
  45.         return(DefWindowProc(hwnd, msg, wParam, lParam));
  46. }


ここまでで実行すると空のウィンドウが表示されます。
次に、DirectXの設定を行います。

以下のようにインクルードとグローバルな関数を追加します。
  1. #include <d3d9.h>
  2.  
  3. // globals
  4. LPDIRECT3D9 g_pDirect3D = NULL;
  5. LPDIRECT3DDEVICE9 g_pDirect3D_Device = NULL;
  6. D3DPRESENT_PARAMETERS g_D3DPP;


WinMain() 関数内のCreateWindow()関数の直下で、以下のようにDirectXの初期化を行います。
  1. // DirectXの初期化
  2. g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
  3. D3DPRESENT_PARAMETERS PresentParams;
  4. memset(&PresentParams, 0sizeof(D3DPRESENT_PARAMETERS));
  5.        
  6. PresentParams.Windowed = TRUE;
  7. PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
  8.        
  9. g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hMainWnd,
  10.                           D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams,
  11.                           &g_pDirect3D_Device);
  12.  
  13. //  ビューポートの設定
  14. D3DVIEWPORT9 vp;
  15. vp.X            = 0;
  16. vp.Y            = 0;
  17. vp.Width        = 800;
  18. vp.Height       = 800;
  19. vp.MinZ         = 0.0f;
  20. vp.MaxZ         = 1.0f;
  21. g_pDirect3D_Device->SetViewport(&vp);



WinMain() 関数の return 直前に、以下のように追加します。
  1.         g_pDirect3D_Device->Release();
  2.         g_pDirect3D->Release();
  3.         return(0);
  4. }



WndProc() 関数内のswitch文に、以下を追加します。
  1. case WM_PAINT:
  2.     g_pDirect3D_Device->Clear(0NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255255255)1.0f0);
  3.     g_pDirect3D_Device->BeginScene();
  4.       
  5.     g_pDirect3D_Device->Present(NULLNULLNULLNULL);
  6.     ValidateRect(hwnd, NULL);
  7.     return(0);



それでは、これからLive2Dの初期化、描画まで行います。

まずモデルの変数を用意します。
  1. live2d::Live2DModelD3D* live2DModel ;


Live2Dモデルの初期化を、WinMain()関数のWindouUpdate()の下に、以下のように設定します。
  1. // Live2Dの初期化
  2. live2d::Live2D::init();
  3.        
  4. const LPCWSTR TEXTURES[] = {
  5.     L"res\\haru\\haru.1024\\texture_00.png" ,
  6.     L"res\\haru\\haru.1024\\texture_01.png" ,
  7.     L"res\\haru\\haru.1024\\texture_02.png" ,
  8.     NULL ,
  9. };
  10.  
  11. // モデルのロード
  12. live2DModel = live2d::Live2DModelD3D::loadModel("res\\haru\\haru.moc");
  13.  
  14. // テクスチャのロード
  15. for( int i = 0 ; i < 1000 ; i++ ){
  16.     if( ! TEXTURES[i] ) break;
  17.  
  18.     LPDIRECT3DTEXTURE9 tex;
  19.                
  20.     // テクスチャ画像をDirextXでの表示用に変換
  21.     if( FAILED( D3DXCreateTextureFromFileExW( g_pDirect3D_Device
  22.         , TEXTURES[i]
  23.         , 0     //width
  24.         , 0     //height
  25.         , 0     // mipmap( 0なら完全なミップマップチェーン)
  26.         , 0     //Usage
  27.         , D3DFMT_A8R8G8B8                
  28.         , D3DPOOL_MANAGED
  29.         , D3DX_FILTER_LINEAR
  30.         , D3DX_FILTER_BOX
  31.         , 0                      
  32.         , NULL
  33.         , NULL
  34.         , &tex ) ) )
  35.     {
  36.         live2d::UtDebug::print("Could not create texture");
  37.         return FALSE;
  38.     }
  39.     else
  40.     {
  41.         live2DModel->setTexture( i , tex );
  42.     }
  43. }


WndProc()関数のcase WM_PAINT: の中で、モデルの行列を設定します。
BrginScene()とPresent()の間に記述してください。
  1. // 行列の設定
  2. D3DXMATRIXA16 matWorld;
  3. D3DXMatrixIdentity( &matWorld );
  4.  
  5. D3DXMATRIX Ortho2D;    
  6. D3DXMATRIX Identity;
  7.                
  8. D3DXMatrixOrthoLH(&Ortho2D, 3000.0f3000.0f-1.0f1.0f);
  9. D3DXMatrixIdentity(&Identity);
  10.                
  11. g_pDirect3D_Device->SetTransform(D3DTS_PROJECTION, &Ortho2D);
  12. g_pDirect3D_Device->SetTransform(D3DTS_WORLD, &Identity);
  13. g_pDirect3D_Device->SetTransform(D3DTS_VIEW , &Identity);


最後に、上のモデルの行列と、Present()の間で、Live2Dの描画を設定して実行すれば完了です!
  1. // --- Live2D 用の描画設定 ---
  2. g_pDirect3D_Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  3. g_pDirect3D_Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  4. g_pDirect3D_Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  5.                
  6. g_pDirect3D_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);//  アルファ・ブレンディングを行う
  7. g_pDirect3D_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);//  透過処理を行う
  8. g_pDirect3D_Device->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_SRCALPHA);//  半透明処理を行う
  9.  
  10. g_pDirect3D_Device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  11. g_pDirect3D_Device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  12. g_pDirect3D_Device->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
  13.                
  14. // --- 座標変換
  15. // 現在のLive2Dモデルは、画像のように下向きに(0,0,w,h)に配置されるため
  16. // センタリングと上下逆転を行う
  17. float modelWidth = live2DModel->getModelImpl()->getCanvasWidth();
  18. float modelHeight = live2DModel->getModelImpl()->getCanvasHeight();
  19.  
  20. D3DXMATRIXA16 world, scale, trans;
  21. g_pDirect3D_Device->GetTransform(D3DTS_WORLD, &world);
  22. D3DXMatrixScaling(&scale,  1-11); // 上下逆転
  23. D3DXMatrixTranslation(&trans , -modelWidth/2-modelHeight/20);
  24. world = trans * scale * world;
  25.  
  26. g_pDirect3D_Device->SetTransform(D3DTS_WORLD, &world);

  27. // --- 描画
  28. live2DModel->setDevice(g_pDirect3D_Device);
  29. live2DModel->update();
  30. live2DModel->draw();
  31.                
  32. g_pDirect3D_Device->EndScene();












最終的なコードは以下のようになります。
  1. #include <windows.h>
  2. #include <d3d9.h>
  3. #include "Live2D.h"
  4. #include "Live2DModelD3D.h"
  5.  
  6. // globals
  7. LPDIRECT3D9 g_pDirect3D = NULL;
  8. LPDIRECT3DDEVICE9 g_pDirect3D_Device = NULL;
  9. D3DPRESENT_PARAMETERS g_D3DPP;
  10.  
  11. live2d::Live2DModelD3D* live2DModel ;
  12.  
  13.  
  14. LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  15.  
  16. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine,
  17.                    int nShow)
  18. {
  19.     MSG msg;
  20.        
  21.     // ウィンドウ作成
  22.     WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
  23.         WndProc, 00, hInstance, NULLNULL(HBRUSH)(COLOR_WINDOW+1),
  24.         NULL"DX9_TUTORIAL1_CLASS"NULL};
  25.  
  26.     RegisterClassEx(&wc);
  27.        
  28.     HWND hMainWnd = CreateWindow("DX9_TUTORIAL1_CLASS",
  29.         "Live2D Sample",
  30.         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800800,
  31.         NULLNULL, hInstance, NULL);
  32.        
  33.     // DirectXの初期化
  34.     g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
  35.     D3DPRESENT_PARAMETERS PresentParams;
  36.     memset(&PresentParams, 0sizeof(D3DPRESENT_PARAMETERS));
  37.        
  38.     PresentParams.Windowed = TRUE;
  39.     PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
  40.        
  41.     g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hMainWnd,
  42.         D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams,
  43.         &g_pDirect3D_Device);
  44.  
  45.     //  ビューポートの設定
  46.     D3DVIEWPORT9 vp;
  47.     vp.X            = 0;
  48.     vp.Y            = 0;
  49.     vp.Width        = 800;
  50.     vp.Height       = 800;
  51.     vp.MinZ         = 0.0f;
  52.     vp.MaxZ         = 1.0f;
  53.     g_pDirect3D_Device->SetViewport(&vp);
  54.  
  55.     // ウィンドウの表示
  56.     ShowWindow(hMainWnd, nShow);
  57.     UpdateWindow(hMainWnd);
  58.  
  59.  
  60.     // Live2Dの初期化
  61.     live2d::Live2D::init();
  62.        
  63.     const LPCWSTR TEXTURES[] = {
  64.         L"res\\haru\\haru.1024\\texture_00.png" ,
  65.         L"res\\haru\\haru.1024\\texture_01.png" ,
  66.         L"res\\haru\\haru.1024\\texture_02.png" ,
  67.         NULL ,
  68.     };
  69.  
  70.     // モデルのロード
  71.     live2DModel = live2d::Live2DModelD3D::loadModel("res\\haru\\haru.moc");
  72.  
  73.     // テクスチャのロード
  74.     for( int i = 0 ; i < 1000 ; i++ ){
  75.         if( ! TEXTURES[i] ) break;
  76.  
  77.         LPDIRECT3DTEXTURE9 tex;
  78.                
  79.         // テクスチャ画像をDirextXでの表示用に変換
  80.         if( FAILED( D3DXCreateTextureFromFileExW( g_pDirect3D_Device
  81.             , TEXTURES[i]
  82.             , 0     //width
  83.             , 0     //height
  84.             , 0     // mipmap( 0なら完全なミップマップチェーン)
  85.             , 0     //Usage
  86.             , D3DFMT_A8R8G8B8                
  87.             , D3DPOOL_MANAGED
  88.             , D3DX_FILTER_LINEAR
  89.             , D3DX_FILTER_BOX
  90.             , 0                      
  91.             , NULL
  92.             , NULL
  93.             , &tex ) ) )
  94.         {
  95.             live2d::UtDebug::print("Could not create texture");
  96.             return FALSE;
  97.         }
  98.         else
  99.         {
  100.             live2DModel->setTexture( i , tex );
  101.         }
  102.     }
  103.        
  104.     while(GetMessage(&msg, NULL00))
  105.     {
  106.         TranslateMessage(&msg);
  107.         DispatchMessage(&msg);
  108.     }
  109.        
  110.     g_pDirect3D_Device->Release();
  111.     g_pDirect3D->Release();
  112.     return(0);
  113. }
  114.  
  115.  
  116. LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  117. {
  118.     switch(msg)
  119.     {
  120.     case WM_DESTROY:
  121.         PostQuitMessage(0);
  122.         return(0);
  123.                
  124.     case WM_PAINT:
  125.         g_pDirect3D_Device->Clear(0NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255255255)1.0f0);
  126.         g_pDirect3D_Device->BeginScene();
  127.                
  128.         // 行列の設定
  129.         D3DXMATRIXA16 matWorld;
  130.         D3DXMatrixIdentity( &matWorld );
  131.  
  132.         D3DXMATRIX Ortho2D;    
  133.         D3DXMATRIX Identity;
  134.                
  135.         D3DXMatrixOrthoLH(&Ortho2D, 3000.0f3000.0f-1.0f1.0f);
  136.         D3DXMatrixIdentity(&Identity);
  137.                
  138.         g_pDirect3D_Device->SetTransform(D3DTS_PROJECTION, &Ortho2D);
  139.         g_pDirect3D_Device->SetTransform(D3DTS_WORLD, &Identity);
  140.         g_pDirect3D_Device->SetTransform(D3DTS_VIEW , &Identity);
  141.                
  142.         // --- Live2D 用の描画設定 ---
  143.         g_pDirect3D_Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  144.         g_pDirect3D_Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  145.         g_pDirect3D_Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  146.                
  147.         g_pDirect3D_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);//  アルファ・ブレンディングを行う
  148.         g_pDirect3D_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);//  透過処理を行う
  149.         g_pDirect3D_Device->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_SRCALPHA);//  半透明処理を行う
  150.  
  151.         g_pDirect3D_Device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  152.         g_pDirect3D_Device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  153.         g_pDirect3D_Device->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
  154.              
  155.         // --- 座標変換
  156.         // 現在のLive2Dモデルは、画像のように下向きに(0,0,w,h)に配置されるため
  157.         // センタリングと上下逆転を行う
  158.         float modelWidth = live2DModel->getModelImpl()->getCanvasWidth();
  159.         float modelHeight = live2DModel->getModelImpl()->getCanvasHeight();
  160.  
  161.         D3DXMATRIXA16 world, scale, trans;
  162.         g_pDirect3D_Device->GetTransform(D3DTS_WORLD, &world);
  163.         D3DXMatrixScaling(&scale,  1-11); // 上下逆転
  164.         D3DXMatrixTranslation(&trans , -modelWidth/2-modelHeight/20);
  165.         world = trans * scale * world;
  166.  
  167.         g_pDirect3D_Device->SetTransform(D3DTS_WORLD, &world);

  168.         // --- 描画
  169.         live2DModel->setDevice(g_pDirect3D_Device);
  170.         live2DModel->update();
  171.         live2DModel->draw();
  172.                
  173.                
  174.         g_pDirect3D_Device->EndScene();
  175.  
  176.         g_pDirect3D_Device->Present(NULLNULLNULLNULL);
  177.         ValidateRect(hwnd, NULL);
  178.         return(0);
  179.     }
  180.        
  181.     return(DefWindowProc(hwnd, msg, wParam, lParam));
  182. }










Comments