トップページ > 過去ログ > 記事閲覧
モデル名からテクスチャ名を取得する方法
名前:ジュンヤ 日時: 2013/02/12 20:15

いつもお世話になってます。 今回はMV1LoadModelFromMemを使って自作のアーカイブからモデルハンドルを作成したいと思ってます。 そこで3Dモデルのファイル名からテクスチャ名とテクスチャの総数を取得する方法はないでしょうか? ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=2845 ↑のサンプルプログラムでほとんど希望する機能は実装されているのですが、 テクスチャ名を直接プログラムに書いてるので、この部分を3Dモデルのファイル名から取得したいです。

Page: 1 |

Re: モデル名からテクスチャ名を取得する方法 ( No.1 )
名前:いっち 日時:2013/02/12 22:35

ちょっと、なにをなさりたいのか良く分からないのですが、 MV1LoadModelFromMem の第3引数に設定するコールバック関数(FileReadFunc)の第1引数に テクスチャのパスが渡されるはずですが、これでは問題があるのでしょうか?
Re: モデル名からテクスチャ名を取得する方法 ( No.2 )
名前:ジュンヤ 日時:2013/02/13 19:00

いっちさんご回答ありがとうございます。 とりあえずFindFirstFileを使ってアーカイブを作成することでなんとか実現できました。 しかしまた問題があって、SetUseASyncChangeWindowModeFunctionでフルスクリーンモードへ切り替えると、 モデルハンドルが失われてしまうようです。 #pragma warning(disable:4996) #include "DxLib.h" //#include "DxStatic.h" #include <stdio.h> #include <string.h> #include <malloc.h> // メモリに読み込んだファイル情報の最大数 #define FIMEMEMINFO_MAX_NUM (256) // メモリに読み込んだファイル情報を保存するための構造体 struct FILEMEMINFO { // ファイル名 char FileName[ 64 ] ; // 読み込んだファイルが格納されているメモリの先頭アドレス void *FileAddr ; // ファイルサイズ int FileSize ; } ; // メモリに読み込んだファイル情報配列 FILEMEMINFO FileMemInfo[ FIMEMEMINFO_MAX_NUM ] ; // メモリに読み込んだファイル情報の数 int FileMemInfoNum ; // ファイル情報を追加 int AddFileMemInfo( const TCHAR *FilePath, const TCHAR *FileName ) { FILE *fp ; // ファイル情報が一杯の場合はエラー if( FileMemInfoNum == FIMEMEMINFO_MAX_NUM ) return -1 ; // ファイルを開く fp = fopen( FilePath, "rb" ) ; // 失敗したら -1 を返す if( fp == NULL ) return -1 ; // ファイルのサイズを取得 fseek( fp, 0L, SEEK_END ) ; FileMemInfo[ FileMemInfoNum ].FileSize = ftell( fp ) ; fseek( fp, 0L, SEEK_SET ) ; // メモリの確保 FileMemInfo[ FileMemInfoNum ].FileAddr = malloc( FileMemInfo[ FileMemInfoNum ].FileSize ) ; // ファイルの読み込み fread( FileMemInfo[ FileMemInfoNum ].FileAddr, FileMemInfo[ FileMemInfoNum ].FileSize, 1, fp ) ; // ファイルを閉じる fclose( fp ) ; // ファイル名を保存する strcpy( FileMemInfo[ FileMemInfoNum ].FileName, FileName ) ; // ファイル情報を一つ増やす FileMemInfoNum ++ ; // 成功なら 0 を返す return 0 ; } // ファイル情報を開放する void ReleaseFileMemInfo( void ) { int i ; // 全てのメモリに読み込んだファイル情報用に確保したメモリを解放する for( i = 0 ; i < FileMemInfoNum ; i ++ ) { free( FileMemInfo[ i ].FileAddr ) ; } // メモリに読み込んであるファイル情報の数を0にする FileMemInfoNum = 0 ; } // ファイル読み込み用コールバック関数 int FileReadFunc( const TCHAR *FilePath, void **FileImageAddr, int *FileSize, void *FileReadFuncData ) { int i ; printfDx("%s\n",FilePath); // メモリに読み込んだファイル情報から該当するファイルパスのファイルを検索する for( i = 0 ; i < FileMemInfoNum ; i ++ ) { // ファイルパスが同じファイル情報があったら、その情報を返す if( strcmp( FileMemInfo[ i ].FileName, FilePath ) == 0 ) { *FileImageAddr = FileMemInfo[ i ].FileAddr ; *FileSize = FileMemInfo[ i ].FileSize ; // 成功を示す 0 を返す return 0 ; } } // ここにきたら指定のファイル情報が存在しなかったということなので、失敗を示す -1 を返す return -1 ; } // ファイル解放用コールバック関数 int FileReleaseFunc( void *MemoryAddr, void *FileReadFuncData ) { // FileReadFunc で新たにメモリを確保したりはしていないので特に何もしない return 0 ; } // WinMain 関数 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int ModelHandle ; int AttachAnimIndex ; ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 || SetDrawScreen( DX_SCREEN_BACK ) < 0 ) { // エラーが発生したら直ちに終了 return -1 ; } // PMDファイルを登録 AddFileMemInfo( "初音ミク.pmd", "初音ミク.pmd" ) ; // VMDファイルを登録( ファイル名の方は 000.vmd になります ) //AddFileMemInfo( "miku000.vmd", "000.vmd" ) ; // モデルの読み込みに必要なファイルを全部登録する AddFileMemInfo( "eye2.bmp", "eye2.bmp" ) ; AddFileMemInfo( "toon01.bmp", "toon01.bmp" ) ; AddFileMemInfo( "toon02.bmp", "toon02.bmp" ) ; AddFileMemInfo( "toon03.bmp", "toon03.bmp" ) ; // メモリ上に読み込んだ3Dモデルファイルから3Dモデルを作成 ModelHandle = MV1LoadModelFromMem( FileMemInfo[ 0 ].FileAddr, FileMemInfo[ 0 ].FileSize, FileReadFunc, FileReleaseFunc, ( void * )0x55556666 ) ; // 読み込み処理が終わったらもうメモリに読み込んだファイルはいらないので解放 ReleaseFileMemInfo() ; // 初期設定では Near クリップが遠すぎるのでクリップの範囲を変更 SetCameraNearFar( 1.0f, 1000.0f ) ; // カメラの位置を設定 SetCameraPositionAndTarget_UpVecY( VGet( 0.0f, 19.0f, -22.5f ), VGet( 0.0f, 10.0f, 0.0f ) ) ; // モデルにアニメーションをアタッチ //AttachAnimIndex = MV1AttachAnim( ModelHandle, 0 ) ; SetUseASyncChangeWindowModeFunction( TRUE, 0, 0 ); SetChangeScreenModeGraphicsSystemResetFlag( FALSE ); SetUseGraphBaseDataBackup( TRUE ); int ModelHandle2 = MV1LoadModel("初音ミク.pmd"); MV1SetPosition( ModelHandle, VGet( -8.0f, 0.0f, 0.0f ) ); MV1SetPosition( ModelHandle2, VGet( 8.0f, 0.0f, 0.0f ) ); while( !ProcessMessage() ) { ClearDrawScreen(); // 3Dモデルの描画 MV1DrawModel( ModelHandle ) ; MV1DrawModel( ModelHandle2 ) ; ScreenFlip(); } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; } それとMV1LoadModelFromMemの最後の引数のFileDataFuncDataに( void * )0x55556666 )と指定してるのですが、 これはどういう意味でしょうか? どの用な時に使うのか教えていただければ助かります。
Re: モデル名からテクスチャ名を取得する方法 ( No.3 )
名前:いっち 日時:2013/02/13 21:29

> しかしまた問題があって、SetUseASyncChangeWindowModeFunctionでフルスクリーンモードへ切り替えると、 > モデルハンドルが失われてしまうようです。 私の環境では問題なくフッキします。 スクリーン切り替え後にカメラの再設定を行っていないためにモデルが表示されなくなっているのではないでしょうか。 問題が解決しない場合は環境やDXライブラリのバージョンを教えてください。 > それとMV1LoadModelFromMemの最後の引数のFileDataFuncDataに( void * )0x55556666 )と指定してるのですが、 > これはどういう意味でしょうか? 特に意味はないかと思います。DEADBEEF的なダミー値ではないでしょうか。 本来の用途はそこに設定したアドレス値がコールバック関数(FileReadFunc)の第4引数にそのまま渡されます。 テストコードでは変数FileMemInfoをグローバルにしているので不要なためダミー値を渡したのだと思いますが、 普通はデフォルト引数のNULLで良いと思います。 > とりあえずFindFirstFileを使ってアーカイブを作成することでなんとか実現できました。 解決されているとの事ですが、FindFirstFile が必要になる状況が良く分からないので、念のための確認ですが、 管理人さんが作成したテストコード内の AddFileMemInfo と ReleaseFileMemInfo はテストコードの便宜上、 擬似的なアーカイブをメモリ内に作成するための関数で MV1LoadModelFromMem を利用する上で 必要な関数ではありません。(vmdのファイル名に細工をしているので完全に不要とは言えませんが)
Re: モデル名からテクスチャ名を取得する方法 ( No.4 )
名前:ジュンヤ 日時:2013/02/13 23:55

>スクリーン切り替え後にカメラの再設定を行っていないためにモデルが表示されなくなっているのではないでしょうか。 いっちさんの仰せの通りSetCameraNearFarとSetCameraPositionAndTarget_UpVecYを再設定したら こちらの環境でも問題なく復帰しました。 >本来の用途はそこに設定したアドレス値がコールバック関数(FileReadFunc)の第4引数にそのまま渡されます。 ちょうどアーカイブのデータをFileReadFuncに渡すことができないかと思っていました。 現在のコードではわざわざグローバルに渡してから処理していたので、ありがたく使わせていただきます。 今回はフォルダ内にあるモデルデータを片っ端から読み込んでアーカイブ化し、 それを読み込んでモデルハンドルを作成したかったのですが、 その時にモデルとテクスチャのファイル名を関連付けておかなければいけないと勘違いしてました。 いっちさんのおかげですべての問題が解決しました。ありがとうございました。

Page: 1 |