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 资源应根据所使用的模型而有所不同。
这里使用样例中「haru」的资源来说明。


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 项目」,设置项目名和保存路径,点击「确定」。


在「Win32 应用程序向导」窗口点击「下一步」。


勾选「空项目(E)」,点击「完成」。



然后对项目进行设置。


右击项目,选择「属性(R)」。


选择「配置属性」 > 「常规」,把「字符集」设置为「使用多字节字符集」。



然后在「配置属性」 > 「C/C++」 > 「常规」中,点击「附加包含目录」最右端的下拉菜单,选择 「<编辑...>」。


在弹出窗口的文本框内,输入 "include" 和 "$(DXSDK_DIR)\Include" ,点击确定。



以同样的方法,选择「配置属性」 > 「C/C++」 > 「预处理器」,在「预处理器」中添加 "L2D_TARGET_D3D" ,
点击确定。





选择「配置属性」> 「链接器」 > 「常规」 ,在「附加库目录」中,
添加 "lib"  和 "$(DXSDK_DIR)\Lib\x86" 。




最后,选择「配置属性」> 「链接器」 > 「输入」、在「附加依赖项」中,
添加 "d3d9.lib" 、 "d3dx9.lib"  、 "live2d_directX_mdd.lib" ,点击确定。




至此,项目的设置就完成了。
接下来向项目中添加所需的文件。


右击项目,选择「在文件资源管理器中打开文件夹(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 的设置。

添加 include 命令,声明全局变量。
  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. //  设置viewport
  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 ;


在WinMain() 的 WindouUpdate() 函数之后添加如下代码,进行 Live2D 模型的初始化。
  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时,会创建完整的mipmap链)
  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);//  打开Alpha渲染
  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. // 由于此时模型坐标为(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.     //  设置viewport
  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时,会创建完整的mipmap链)
  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);//  打开Alpha渲染
  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.         // 由于此时模型坐标为(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. }










コメント