/** * Live2D SDK for DirectX * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ #define _CRTDBG_MAP_ALLOC// ※追加 #include #include #include "Live2D.h" #include "Live2DModelD3D.h" #include "util/UtSystem.h" #include // ※追加 #ifdef _DEBUG// ※追加 #define new new(_NORMAL_BLOCK,__FILE__,__LINE__)// ※追加 #endif /*********************************************************** 必要なライブラリをリンクする ************************************************************/ #pragma comment( lib, "d3d9.lib" ) #pragma comment( lib, "d3dx9d.lib" ) /*********************************************************** グローバル変数(アプリケーション関連) ************************************************************/ //#define USE_LIVE2D 1 LPDIRECT3D9 g_pDirect3D = NULL; LPDIRECT3DDEVICE9 g_pDirect3D_Device = NULL; D3DPRESENT_PARAMETERS g_D3DPP; // D3DDeviceの設定 #define FAILED(hr) (((HRESULT)(hr)) < 0) live2d::Live2DModelD3D* live2DModel = NULL;// 初期値をNULL ※変更 LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); VOID RenderLive2D(); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShow) { _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );// ※追加 MSG msg; WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC, WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1), NULL, "DX9_TUTORIAL1_CLASS", NULL}; RegisterClassEx(&wc); // ウィンドウ作成 HWND hMainWnd = CreateWindow("DX9_TUTORIAL1_CLASS", "Live2D SDK Simple", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 800, NULL, NULL, hInstance, NULL); // DirectXの初期化 g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION); D3DPRESENT_PARAMETERS PresentParams; memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS)); PresentParams.Windowed = TRUE; PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD; g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hMainWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams, &g_pDirect3D_Device); // ビューポートの設定 D3DVIEWPORT9 vp; vp.X = 0; vp.Y = 0; vp.Width = 800; vp.Height = 800; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; g_pDirect3D_Device->SetViewport(&vp); // ウィンドウの表示 ShowWindow(hMainWnd, nShow); UpdateWindow(hMainWnd); // live2d::UtDebug::addMemoryDebugFlags( live2d::UtDebug::MEMORY_DEBUG_MEMORY_INFO_COUNT ) ;// ※追加 live2d::UtDebug::addMemoryDebugFlags( live2d::UtDebug::MEMORY_DEBUG_MEMORY_INFO_ALL ) ;// ※追加 // Live2Dの初期化 live2d::Live2D::init(); const LPCWSTR TEXTURES[] = { L"res\\haru\\haru.1024\\texture_00.png" , L"res\\haru\\haru.1024\\texture_01.png" , L"res\\haru\\haru.1024\\texture_02.png" , NULL , } ; // モデルのロード live2DModel = live2d::Live2DModelD3D::loadModel("res\\haru\\haru.moc") ; #if 1// ※追加 if(live2DModel)// ※追加 {// ※追加 // テクスチャのロード for( int i = 0 ; i < 1000 ; i++ ){ if( ! TEXTURES[i] ) break ; LPDIRECT3DTEXTURE9 tex ; // テクスチャ画像をDirextXでの表示用に変換 if( FAILED( D3DXCreateTextureFromFileExW( g_pDirect3D_Device , TEXTURES[i] , 0 //width , 0 //height , 0 //mipmap //( 0なら完全なミップマップチェーン) , 0 //Usage , D3DFMT_A8R8G8B8 , D3DPOOL_MANAGED , D3DX_FILTER_LINEAR , D3DX_FILTER_BOX , 0 , NULL , NULL , &tex ) ) ) { live2d::UtDebug::print( "Could not create texture" ); return FALSE ; } else { // 変換が成功したらセット live2DModel->setTexture( i , tex ) ; } } }// ※追加 #endif// ※追加 // メッセージ・ループ do { if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { // アイドル処理 RenderLive2D(); } } while (msg.message != WM_QUIT); live2DModel->deleteTextures();// ※追加 if(live2DModel) delete live2DModel;// ※追加 live2d::Live2D::dispose();// ※追加 g_pDirect3D_Device->Release(); g_pDirect3D->Release(); return(0); } LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); return(0); // ※未使用のためコメント // case WM_PAINT: // RenderLive2D(); // return(0); } return(DefWindowProc(hwnd, msg, wParam, lParam)); } // モデルの描画 VOID RenderLive2D() { // モデルが初期化されていなければ何もしない if(live2DModel == NULL) return; g_pDirect3D_Device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0); g_pDirect3D_Device->BeginScene(); // Set up world matrix D3DXMATRIXA16 matWorld; D3DXMatrixIdentity( &matWorld ); D3DXMATRIX Ortho2D; D3DXMATRIX Identity; int w , h ; w = 800 ; h = 800 ; float modelWidth = live2DModel->getModelImpl()->getCanvasWidth() ; float modelHeight = live2DModel->getModelImpl()->getCanvasHeight() ; D3DXMatrixOrthoLH(&Ortho2D, modelHeight ,- modelHeight *h/w, -1.0f, 1.0f); D3DXMatrixIdentity(&Identity); g_pDirect3D_Device->SetTransform(D3DTS_PROJECTION, &Ortho2D); g_pDirect3D_Device->SetTransform(D3DTS_WORLD, &Identity); g_pDirect3D_Device->SetTransform(D3DTS_VIEW , &Identity); // --- 座標変換 // 現在のLive2Dモデルは、画像のように下向きに(0,0,w,h)に配置される // センタリングと上下逆転が必要 D3DXMATRIXA16 world, scale, trans ; g_pDirect3D_Device->GetTransform(D3DTS_WORLD, &world); D3DXMatrixTranslation(&trans , -modelWidth/2, -modelHeight/2, 0) ; world = trans *world; g_pDirect3D_Device->SetTransform(D3DTS_WORLD, &world); // --- モデルのパラメータを直接設定するサンプル double t = (live2d::UtSystem::getUserTimeMSec()/1000.0) * 2 * 3.14 ;// 1秒ごとに2π(1周期)増える double cycle=3.0;// パラメータが一周する時間(秒) double value=sin( t/cycle );// -1から1の間を周期ごとに変化する live2DModel->setParamFloat( "PARAM_ANGLE_X" , (float) (30 * value) ) ;// PARAM_ANGLE_Xのパラメータが[cycle]秒ごとに-30から30まで変化する // --- 描画 live2DModel->setDevice(g_pDirect3D_Device) ; live2DModel->update() ; // live2DModel->draw() ; // ※検証用にコメント g_pDirect3D_Device->EndScene(); g_pDirect3D_Device->Present(NULL, NULL, NULL, NULL); return; }