DXライブラリでのMMDモデルの描画

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

DXライブラリでのMMDモデルの描画

#1

投稿記事 by みけCAT » 14年前

Dev-C++4.9.9.2、gcc3.4.2、公式gcc用DXライブラリVer3.05です。
DXライブラリでMMDのモデルを描画しようとしてみましたが、うまく描画されていないようです。
公式のリファレンスを参考にしました。
どこがおかしいか、どう直せばいいか教えていただければ幸いです。
よろしくお願いします。

コード:

#include "DxLib.h"

char Key[256];

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
	SetDrawScreen( DX_SCREEN_BACK );        //裏画面に設定

	int ModelHandle, AttachIndex, PlayAnim ;
	float TotalTime, PlayTime ;
	
	// 3Dモデルの読み込み
	ModelHandle = MV1LoadModel( "初音ミク.pmd" ) ;
	if(ModelHandle==-1)printfDx("モデルの読み込みに失敗");
	
	// 画面に映る位置に3Dモデルを移動
	if(MV1SetPosition( ModelHandle, VGet( 320.0f, -300.0f, 600.0f ) )==-1)
		printfDx("モデルの移動に失敗");

	// 3Dモデルの0番目のアニメーションをアタッチする
	AttachIndex = MV1AttachAnim( ModelHandle, 0, -1, FALSE ) ;
	if(AttachIndex==-1)printfDx("アニメーションのアタッチに失敗");

	// アタッチしたアニメーションの総再生時間を取得する
	TotalTime = MV1GetAttachAnimTotalTime( ModelHandle, AttachIndex ) ;

	// 再生時間の初期化
	PlayTime = 0.0f ;
	
	unsigned int prevtime,nowtime;
	prevtime=nowtime=GetTickCount();

	while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
		//↑メッセージ処理         ↑画面をクリア          ↑キーボード入力状態取得       ↑ESCが押されていない

		//ココに処理を書いていく
		
		// 再生時間を進める
		nowtime=GetTickCount();
		PlayTime+=(float)(nowtime-prevtime)/1000.0f*60.0f;
		prevtime=nowtime;
		if( PlayTime >= TotalTime )PlayTime=0.0f;
		
		// 再生時間をセットする
		if(MV1SetAttachAnimTime( ModelHandle, AttachIndex, PlayTime )==-1)
			DrawString(50,400,"再生時間のセットに失敗",GetColor(255,255,255));

		// 3Dモデルの描画
		if(MV1DrawModel( ModelHandle )==-1)
			DrawString(50,440,"モデルの描画に失敗",GetColor(255,255,255));

		ScreenFlip();//裏画面を表画面に反映
	}

	DxLib_End();
	return 0;
}
画面写真とプログラム、こうしたいというイメージ図を添付します。
modeltest.exeと同じフォルダに、
http://www.geocities.jp/higuchuu4/でダウンロードできる
「MikuMikuDance (Multi-Model Edition)」のUserFile>Modelフォルダから「初音ミク.pmd」をコピーしてください。
イメージ図はMMDの画面をコピペしてちょっと編集しただけなので汚いですが気にしないでください。

画面写真
mmdmodelerror.jpg
画面写真です。
mmdmodelerror.jpg (16.7 KiB) 閲覧数: 9448 回
イメージ図
mmdmodelrisou.jpg
イメージ図です。
mmdmodelrisou.jpg (33.05 KiB) 閲覧数: 9448 回
添付ファイル
modeltest.zip
プログラムです。
(1.38 MiB) ダウンロード数: 190 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: DXライブラリでのMMDモデルの描画

#2

投稿記事 by softya(ソフト屋) » 14年前

とりあえずカメラの範囲外なのとスケールが小さかったので拡大しました。
これで「Dev-C++4.9.9.2、gcc3.4.2、公式gcc用DXライブラリVer3.05です。」でも表示されると思いますので試してみてください。

コード:

#include "DxLib.h"
 
char Key[256];
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
    SetDrawScreen( DX_SCREEN_BACK );        //裏画面に設定
 
    int ModelHandle, AttachIndex, PlayAnim ;
    float TotalTime, PlayTime ;
    
    // 3Dモデルの読み込み
    ModelHandle = MV1LoadModel( "Model\\初音ミク.pmd" ) ;
    if(ModelHandle==-1)printfDx("モデルの読み込みに失敗");
    
    // 画面に映る位置に3Dモデルを移動
    if(MV1SetPosition( ModelHandle, VGet( 0.0f, -50.0f, 0.0f ) )==-1)
        printfDx("モデルの移動に失敗");
 
 	// モデルスケールを変更
 	if(MV1SetScale( ModelHandle, VGet( 4.0f, 4.0f, 4.0f ) ) ==-1)
        printfDx("モデルのスケール変更に失敗");
        
 	//	カメラ設定
 	VECTOR CameraPos;
 	// カメラの座標を初期化
	CameraPos.x = 0.0f ;
	CameraPos.y = 00.0f ;
	CameraPos.z = -100.0f ;

	// カメラの位置と注視点をセット、注視点は原点
	SetCameraPositionAndTarget_UpVecY( CameraPos, VGet( 0.0f, 0.0f, 0.0f ) ) ;
 
    // 3Dモデルの0番目のアニメーションをアタッチする
    AttachIndex = MV1AttachAnim( ModelHandle, 0, -1, FALSE ) ;
    if(AttachIndex==-1)printfDx("アニメーションのアタッチに失敗");
 
    // アタッチしたアニメーションの総再生時間を取得する
    TotalTime = MV1GetAttachAnimTotalTime( ModelHandle, AttachIndex ) ;
 
    // 再生時間の初期化
    PlayTime = 0.0f ;
    
    unsigned int prevtime,nowtime;
    prevtime=nowtime=GetTickCount();
 
    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
        //↑メッセージ処理         ↑画面をクリア          ↑キーボード入力状態取得       ↑ESCが押されていない
 
        //ココに処理を書いていく
        
        // 再生時間を進める
        nowtime=GetTickCount();
        PlayTime+=(float)(nowtime-prevtime)/1000.0f*60.0f;
        prevtime=nowtime;
        if( PlayTime >= TotalTime )PlayTime=0.0f;
        
        // 再生時間をセットする
        if(MV1SetAttachAnimTime( ModelHandle, AttachIndex, PlayTime )==-1)
            DrawString(50,400,"再生時間のセットに失敗",GetColor(255,255,255));
 
        // 3Dモデルの描画
        if(MV1DrawModel( ModelHandle )==-1)
            DrawString(50,440,"モデルの描画に失敗",GetColor(255,255,255));
 
        ScreenFlip();//裏画面を表画面に反映
    }
 
    DxLib_End();
    return 0;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: DXライブラリでのMMDモデルの描画

#3

投稿記事 by みけCAT » 14年前

一応表示されました。
かなり汚いですが、仕様でしょうか?

こんな感じです。
mmdmodeldraw.jpg
画面写真です。
mmdmodeldraw.jpg (31.85 KiB) 閲覧数: 9433 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: DXライブラリでのMMDモデルの描画

#4

投稿記事 by softya(ソフト屋) » 14年前

設定やテクスチャなどの問題で表示されないことがあります。
これは本家などの過去ログを参考にしてください。

一部PMDモデルの読み込み不具合について
http://hpcgi2.nifty.com/natupaji/bbs/pa ... ew&no=2296
こちらに出てくるモデルビュアーだと正常に表示されますので、たぶんトゥーン処理あたりの設定が違うんだと思います。
[補足]3.05f付属のモデルビューアでも正常に表示されました。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: DXライブラリでのMMDモデルの描画

#5

投稿記事 by softya(ソフト屋) » 14年前

ふと思いつきでカメラクリップを設定したら表示されました。
カメラクリップとかスケールアップも問題?

コード:

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	int ModelHandle ;
	ChangeWindowMode(TRUE);

	// DXライブラリの初期化
	if( DxLib_Init() < 0 )
	{
		// エラーが発生したら直ちに終了
		return -1 ;
	}

	// 3Dモデルの読み込み
    ModelHandle = MV1LoadModel( "Model\\初音ミク.pmd" ) ;

 	//	カメラ設定
 	VECTOR CameraPos;
 	// カメラの座標を初期化
	CameraPos.x = 0.0f ;
	CameraPos.y = 20.0f ;
	CameraPos.z = -20.0f ;

	//	カメラの 手前クリップ距離と 奥クリップ距離を設定する
	SetCameraNearFar( 1.0f, 150.0f ) ;
	// カメラの位置と注視点をセット、注視点は原点
	SetCameraPositionAndTarget_UpVecY( CameraPos, VGet( 0.0f, 10.0f, 0.0f ) ) ;
	
	// 3Dモデルの描画
	MV1DrawModel( ModelHandle ) ;

	// キーの入力待ち
	WaitKey() ;

	// DXライブラリの後始末
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: DXライブラリでのMMDモデルの描画

#6

投稿記事 by みけCAT » 14年前

Ver3.05fにして、softyaさんのコードを入れたら正常に表示されました。
白目をむいていて怖いですが、アニメーションの問題でしょうか?
一応解決とさせていただきます。

コード:

#include "DxLib.h"
 
char Key[256];
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
    SetDrawScreen( DX_SCREEN_BACK );        //裏画面に設定
 
    int ModelHandle, AttachIndex, PlayAnim ;
    float TotalTime, PlayTime ;
    
    // 3Dモデルの読み込み
    //ModelHandle = MV1LoadModel( "Model\\初音ミク.pmd" ) ;
    ModelHandle = MV1LoadModel( "初音ミク.pmd" ) ;
    if(ModelHandle==-1)printfDx("モデルの読み込みに失敗");
    
#if 0
    // 画面に映る位置に3Dモデルを移動
    if(MV1SetPosition( ModelHandle, VGet( 0.0f, -50.0f, 0.0f ) )==-1)
        printfDx("モデルの移動に失敗");
 
    // モデルスケールを変更
    if(MV1SetScale( ModelHandle, VGet( 4.0f, 4.0f, 4.0f ) ) ==-1)
        printfDx("モデルのスケール変更に失敗");
        
    //  カメラ設定
    VECTOR CameraPos;
    // カメラの座標を初期化
    CameraPos.x = 0.0f ;
    CameraPos.y = 00.0f ;
    CameraPos.z = -100.0f ;
 
    // カメラの位置と注視点をセット、注視点は原点
    SetCameraPositionAndTarget_UpVecY( CameraPos, VGet( 0.0f, 0.0f, 0.0f ) ) ;
#else
	 //  カメラ設定
    VECTOR CameraPos;
    // カメラの座標を初期化
    CameraPos.x = 0.0f ;
    CameraPos.y = 20.0f ;
    CameraPos.z = -20.0f ;
 
    //  カメラの 手前クリップ距離と 奥クリップ距離を設定する
    SetCameraNearFar( 1.0f, 150.0f ) ;
    // カメラの位置と注視点をセット、注視点は原点
    SetCameraPositionAndTarget_UpVecY( CameraPos, VGet( 0.0f, 10.0f, 0.0f ) ) ;
#endif
 
    // 3Dモデルの0番目のアニメーションをアタッチする
    AttachIndex = MV1AttachAnim( ModelHandle, 0, -1, FALSE ) ;
    if(AttachIndex==-1)printfDx("アニメーションのアタッチに失敗");
 
    // アタッチしたアニメーションの総再生時間を取得する
    TotalTime = MV1GetAttachAnimTotalTime( ModelHandle, AttachIndex ) ;
 
    // 再生時間の初期化
    PlayTime = 0.0f ;
    
    unsigned int prevtime,nowtime;
    prevtime=nowtime=GetTickCount();
 
    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
        //↑メッセージ処理         ↑画面をクリア          ↑キーボード入力状態取得       ↑ESCが押されていない
 
        //ココに処理を書いていく
        
        // 再生時間を進める
        nowtime=GetTickCount();
        PlayTime+=(float)(nowtime-prevtime)/1000.0f*60.0f;
        prevtime=nowtime;
        if( PlayTime >= TotalTime )PlayTime=0.0f;
        
        // 再生時間をセットする
        if(MV1SetAttachAnimTime( ModelHandle, AttachIndex, PlayTime )==-1)
            DrawString(50,400,"再生時間のセットに失敗",GetColor(255,255,255));
 
        // 3Dモデルの描画
        if(MV1DrawModel( ModelHandle )==-1)
            DrawString(50,440,"モデルの描画に失敗",GetColor(255,255,255));
 
        ScreenFlip();//裏画面を表画面に反映
    }
 
    DxLib_End();
    return 0;
}
添付ファイル
mmdmodeldraw2.jpg
画面写真です。
mmdmodeldraw2.jpg (32.15 KiB) 閲覧数: 9386 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: DXライブラリでのMMDモデルの描画

#7

投稿記事 by softya(ソフト屋) » 14年前

miki.png
今頃返事して遅いかも知れませんが、当方では目があります。
違いはMMDのMODELフォルダを全部持ってきていますので、目のテクスチャが読み込まれていないのでは?

eyeR2.bmp
eye2.bmp
eye3.bmp
eye3Ne.bmp
eye4.bmp
eyeKT.bmp
eyeM2.bmp
eyeMe2.bmp

このうちどれかでしょうね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: DXライブラリでのMMDモデルの描画

#8

投稿記事 by みけCAT » 14年前

できました。ありがとうございます。
モデルビューアで調べたところ、eye2.bmpとtoon01~03.bmpが使われているようです。
添付ファイル
mmdmodeldraw3.jpg
画面写真です。
mmdmodeldraw3.jpg (33.17 KiB) 閲覧数: 9336 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る