トップページ > 記事閲覧
Live2DとDxlibの併用
名前:Mel 日時: 2014/11/15 00:05

管理人様初めましてMelと申します。 Dxlibでゲーム開発を進めている途中、Live2Dの話を聞きまして非営利ユーザーならSDKを契約料免除でくれるそうなのです。 免除申請して、SDKを頂きLive2Dのリファレンスなどを見て簡単なプログラムを組んでみたものの、 Dxlib側で描画したものは描画されるのですが、Live2D側は全く描画されませんでした。 ただ、Dxlibの2D描画は内部で3Dレンダリングを行ってると聞いているので、 同じ3Dならうまくいくのではと思っていたのですが、つまずくばかりです。 Dxlibのメリットから離れてしまうのですが、GetUseDirect3DDevice9関数でデバイス取得してデバイスを Live2D側に渡してやってみてもダメで新たにLPDIRECT3DDEVICE9を作って描画すると、描画はされるもののProcessMessage関数内部でPresentしてるはずなので画面がDxlib側とLive2D側で点滅してしまいます。 割りきってゲームの1シーンのみでしかLive2Dは使わないのでそのシーンのみDirectXを直で書いて別シーンはDxlib側で 書こうと思ってSetHookWinProc関数などでプロシージャごと書いてみて試行錯誤してみたものの終了できないなどの バグに追われてしまい、管理人様にお助けを求めにきました...。 質問が単刀直入ですが、管理人様の方で何かいい方法がありませんか? 理想はDxlibとLive2Dを同じデバイスで共存できることです。 よろしくお願いします。 Dxlib Ver.3.13 Win7Pro Live2D version 2.0.00 for DirectX プロジェクト設定がすごくややこしいです。 プロジェクト設定チュートリアルのサイトも公式であるので 参考にしてください。 http://sites.cybernoids.jp/cubism/sdk_tutorial/platform-setting/directx/createproject //以下サンプルソース // ここにサンプルプログラムをペーストしてください // 初期状態では LoadGraphScreen のサンプルプログラムが入力されています。 #include <D3D9.h> //今回のゲームで使うライブラリ宣言 #include <Live2D.h> using namespace live2d; #include "DxLib.h" //Live2D フレームワーク #include <Live2DModelD3D.h> #include <util/UtSystem.h> //Live2d Live2DModelD3D* live2DModel; LPCWSTR TEXTURES[3]; LPDIRECT3DDEVICE9 g_Device9; void Render2D(); bool Create(); LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp); LPDIRECT3D9 g_pDirect3D = NULL; D3DPRESENT_PARAMETERS g_D3DPP; // D3DDeviceの設定 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { // タイトルを test に変更 SetMainWindowText( "Test_exe" ) ; // ウインドウモードに変更 ChangeWindowMode( TRUE ) ; //描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ); if( DxLib_Init() == -1 ) // DXライブラリ初期化処理 { return -1; // エラーが起きたら直ちに終了 } // 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, GetMainWindowHandle(), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams, &g_Device9); Live2D::init(); // g_Device9 = (LPDIRECT3DDEVICE9)GetUseDirect3DDevice9(); // ビューポートの設定 D3DVIEWPORT9 vp; vp.X = 0; vp.Y = 0; vp.Width = 800; vp.Height = 800; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; g_Device9->SetViewport(&vp); SetHookWinProc(WndProc); SetFontSize(20); if(!Create()) { return -1; } while( ProcessMessage()==0 ) { ClearDrawScreen(); DrawString(50,50,"Live2D",GetColor(255,255,255)); Render2D(); // バック画面をディスプレイに転送します ScreenFlip(); } DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 } void Render2D() { // for(;;) { // モデルが初期化されていなければ何もしない if(live2DModel == NULL) return; //SetDrawScreen(DX_SCREEN_FRONT); g_Device9->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0); g_Device9->BeginScene(); 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); // D3DXMatrixPerspectiveFovLH( &Ortho2D, D3DXToRadian( 45.0f ), h/w, 0.0f, 100.0f ); D3DXMatrixIdentity(&Identity); g_Device9->SetTransform(D3DTS_PROJECTION, &Ortho2D); g_Device9->SetTransform(D3DTS_WORLD, &Identity); // D3DXMATRIX view; // D3DXMatrixLookAtLH( &view, &D3DXVECTOR3( 0.0f, 0.0f, -10.0f ), &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) ); // g_Device9->SetTransform(D3DTS_VIEW , &view); g_Device9->SetTransform(D3DTS_VIEW , &Identity); D3DXMATRIXA16 world, scale, trans ; g_Device9->GetTransform(D3DTS_WORLD, &world); D3DXMatrixTranslation(&trans , -modelWidth/2, -modelHeight/2, 0) ; world = trans *world; g_Device9->SetTransform(D3DTS_WORLD, &world); //float matrix[16]; //matrix[0] = 2/live2DModel->getCanvasWidth();//x軸の拡大率 //matrix[5] = 2/live2DModel->getCanvasWidth();//y軸の拡大率 //matrix[12] = 0;//x軸の移動 //matrix[13] = 0;//y軸の移動 //live2DModel->setMatrix( matrix ); // --- モデルのパラメータを直接設定するサンプル double t = (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_Device9) ; live2DModel->update() ; live2DModel->draw() ; g_Device9->EndScene(); g_Device9->Present(NULL, NULL, NULL, NULL); //SetDrawScreen( DX_SCREEN_BACK ); //DrawString(0,0,"Live2D",GetColor(255,255,255)); } } bool Create() { TEXTURES[0] = L"L2res/haru/haru.1024/texture_00.png" ; TEXTURES[1] = L"L2res/haru/haru.1024/texture_01.png" ; TEXTURES[2] = L"L2res/haru/haru.1024/texture_02.png" ; live2DModel = Live2DModelD3D::loadModel("L2res/haru/haru.moc"); // テクスチャのロード for( int i = 0 ; i < 3 ; i++ ){ LPDIRECT3DTEXTURE9 tex ; // テクスチャ画像をDirextXでの表示用に変換 if( FAILED( D3DXCreateTextureFromFileExW( g_Device9 , TEXTURES[i] , 0 //width , 0 //height , 0 //mipmap //( 0なら完全なミップマップチェーン) , 0 //Usage , D3DFMT_A8R8G8B8 , D3DPOOL_DEFAULT , D3DX_FILTER_LINEAR , D3DX_FILTER_BOX , 0 , NULL , NULL , &tex ) ) ) { live2d::UtDebug::print( "Could not create texture" ); return false ; } else { // 変換が成功したらセット live2DModel->setTexture( i , tex ) ; } } return true; } LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { SetUseHookWinProcReturnValue(TRUE); switch(msg) { case WM_LBUTTONUP: MessageBox(hwnd , TEXT("終わるにゃん") , TEXT("Kitty") , MB_ICONINFORMATION); //exit(0); break; case WM_DESTROY: case WM_QUIT: PostQuitMessage(0); break; case WM_PAINT: Render2D(); } return DefWindowProc(hwnd , msg , wp , lp); }
メンテ

Page: 1 |

Re: Live2DとDxlibの併用 ( No.1 )
名前:管理人 日時:2014/11/15 18:49

Live2D は条件次第では無償で使用できるようになったのですね Melさんのプログラムを少し変更させていただいて正常に表示されるようにしてみましたので、よろしければご覧ください #include <D3D9.h> //今回のゲームで使うライブラリ宣言 #include <Live2D.h> using namespace live2d; #include "DxLib.h" //Live2D フレームワーク #include <Live2DModelD3D.h> #include <util/UtSystem.h> // 画面サイズ #define SCREEN_SIZE_X 800 #define SCREEN_SIZE_Y 750 //Live2d Live2DModelD3D* live2DModel; LPDIRECT3DDEVICE9 g_Device9; void Render2D(); bool Create(); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int x, add ; // タイトルを test に変更 SetMainWindowText( "Test_exe" ) ; // ウインドウモードに変更 ChangeWindowMode( TRUE ) ; //描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ); // Direct3D9Ex ではなく Direct3D9 を使う SetUseDirect3D9Ex( FALSE ) ; // 画面解像度の設定 SetGraphMode( SCREEN_SIZE_X, SCREEN_SIZE_Y, 32 ) ; // DXライブラリ初期化 if( DxLib_Init() == -1 ) { return -1; } // Live2D 初期化 Live2D::init(); // DXライブラリが使用している Direct3DDevice9 を取得 g_Device9 = (LPDIRECT3DDEVICE9)GetUseDirect3DDevice9(); // フォントサイズの変更 SetFontSize(20); // Live2D データの読み込み if(!Create()) { return -1; } // 左右に動く文字列の変数を初期化 x = 0 ; add = 8 ; // 背景色を青に設定 SetBackgroundColor( 0, 0, 255 ) ; // 描画先を裏画面に変更 SetDrawScreen(DX_SCREEN_BACK); // メインループ while( ProcessMessage()==0 ) { // 画面をクリア ClearDrawScreen(); // 左右に動く文字列を動かす x += add ; if( x < 0 || x > SCREEN_SIZE_X ) { add = -add ; } // Live2D で描くキャラクターの奥に"Live2D"と描画 DrawString(x,64,"Live2D",GetColor(255,255,255)); // Live2D の描画 Render2D(); // Live2D で描くキャラクターの手前にも"Live2D"と描画 DrawString(SCREEN_SIZE_X - x, SCREEN_SIZE_Y - 100,"Live2D",GetColor(255,255,255)); // 裏画面を表画面に転送 ScreenFlip(); } // DXライブラリ使用の終了処理 DxLib_End() ; // ソフトの終了 return 0 ; } void Render2D() { // モデルが初期化されていなければ何もしない if(live2DModel == NULL) return; // DXライブラリの描画処理を完了させる RenderVertex() ; // Live2D の描画 { // 射影行列の設定 D3DXMATRIX Ortho2D; float modelWidth = live2DModel->getModelImpl()->getCanvasWidth() ; float modelHeight = live2DModel->getModelImpl()->getCanvasHeight() ; D3DXMatrixOrthoLH(&Ortho2D, modelHeight ,-modelHeight *SCREEN_SIZE_Y/SCREEN_SIZE_X, -1.0f, 1.0f); g_Device9->SetTransform(D3DTS_PROJECTION, &Ortho2D); // ビュー行列の設定 D3DXMATRIX Identity; D3DXMatrixIdentity(&Identity); g_Device9->SetTransform(D3DTS_VIEW , &Identity); // ワールド行列の設定 D3DXMATRIXA16 world ; D3DXMatrixTranslation(&world , -modelWidth/2, -modelHeight/2, 0) ; g_Device9->SetTransform(D3DTS_WORLD, &world); // --- モデルのパラメータを直接設定するサンプル double t = (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->update() ; live2DModel->draw() ; } // DXライブラリの Direct3D9 の設定を復帰させる RefreshDxLibDirect3DSetting() ; } bool Create() { LPCWSTR TEXTURES[3] = { L"L2res/haru/haru.1024/texture_00.png", L"L2res/haru/haru.1024/texture_01.png", L"L2res/haru/haru.1024/texture_02.png" }; live2DModel = Live2DModelD3D::loadModel("L2res/haru/haru.moc"); live2DModel->setDevice(g_Device9) ; // テクスチャのロード for( int i = 0 ; i < 3 ; i++ ){ LPDIRECT3DTEXTURE9 tex ; // テクスチャ画像をDirextXでの表示用に変換 if( FAILED( D3DXCreateTextureFromFileExW( g_Device9 , TEXTURES[i] , 0 //width , 0 //height , 0 //mipmap //( 0なら完全なミップマップチェーン) , 0 //Usage , D3DFMT_A8R8G8B8 , D3DPOOL_DEFAULT , D3DX_FILTER_LINEAR , D3DX_FILTER_BOX , 0 , NULL , NULL , &tex ) ) ) { live2d::UtDebug::print( "Could not create texture" ); return false ; } else { // 変換が成功したらセット live2DModel->setTexture( i , tex ) ; } } return true; } DXライブラリと Live2D を併用する場合の要点は以下の3つです ・DxLib_Init の前に SetUseDirect3D9Ex( FALSE ) ; を記述して Direct3D9 を使用するようにする  ( DXライブラリはデフォルトでは Direct3D9Ex を使用するのですが、Direct3D9Ex を使用した場合は   何も表示されませんでした ) ・Live2D の処理を行う前に RenderVertex() ; を実行してDXライブラリの描画を完了しておく ・Live2D の処理が終わり、DXライブラリの処理を行う前に RefreshDxLibDirect3DSetting() ; を実行して  DXライブラリ用の Direct3D9 の設定を復活させる
メンテ
Re: Live2DとDxlibの併用 ( No.2 )
名前:Mel 日時:2014/11/15 23:24

対応有難うございます。 こちらでも両方描画されるようになりました。 これで制作が捗れます。 また何かあったとき質問すると思いますがその時もよろしくお願いします。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存