PMD+VMDファイルを MV1LoadModelFromMem で読み込むサンプルプログラムを組んでみましたので、
よろしければご覧ください
流れとしては、ファイルをメモリに読み込むとともに、読み込んだファイルの名前とサイズを
保存しておいて( 関数 AddFileMemInfo )、MV1LoadModelFormMem に渡すコールバック関数( FileReadFunc )では、
所望されたファイルと同名のファイルが読み込んだファイルの配列に存在したらその情報を返す、
という処理をしています
尚、PMDファイルとともに読み込まれる VMDファイルは、PMDファイル名+3桁の番号+.vmd と
なるのですが、MV1LoadModelFromMem ではファイル名を指定しないので、コールバック関数では
"000.vmd" や "001.vmd" など、ファイル名部分が存在しない VMDファイル名で呼ばれます
なので、初音ミク000.vmd を AddFileMemInfo で読み込む際は、読み込むファイルとしては当然
"初音ミク000.vmd" としますが、登録名は "000.vmd" となっています
#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 ;
// メモリに読み込んだファイル情報から該当するファイルパスのファイルを検索する
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 )
{
// エラーが発生したら直ちに終了
return -1 ;
}
// PMDファイルを登録
AddFileMemInfo( "初音ミク.pmd", "初音ミク.pmd" ) ;
// VMDファイルを登録( ファイル名の方は 000.vmd になります )
AddFileMemInfo( "初音ミク000.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 ) ;
// 3Dモデルの描画
MV1DrawModel( ModelHandle ) ;
// キーの入力待ち
WaitKey() ;
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}