01−03、mqo読み込み

読み込みの流れ

mqoファイルの読み込み処理はdisp4/CPP/mqofile.cppで行います。
mqoの材質はCMQOMaterialクラス, オブジェクトはCMQOObjectクラスに格納します。

mqoの読み込み方法についてですが
まずはファイル全体をバッファに読み込みます。
そしてそのバッファを1行ずつ調べていきます。

現在どの情報を読み込んでいるかということを調べて、m_stateにセットしつつ解析していきます。

m_stateに従って読み込み処理をするコードは以下のようなものです。

m_state = BEGIN_FINDCHUNK;
while( m_state != BEGIN_FINISH ){
    switch( m_state ){
    case BEGIN_FINDCHUNK:
        ret = FindChunk( &m_state );
        if( ret ){
            if( mqobuf.isend == 1 ){
                ret = 0;
            }else{
                _ASSERT( 0 );
                return 1;
            }
        }
        break;
    case BEGIN_SCENE:
        CallF( ReadScene( &m_state ), return 1 );
        break;
    case BEGIN_BACKIMAGE:
        CallF( SkipChunk(), return 1 );
        m_state = BEGIN_FINDCHUNK;
        break;
    case BEGIN_MATERIAL:
        CallF( ReadMaterial( &m_state, srcmaterial ), return 1 );
        break;
    case BEGIN_OBJECT://子チャンクをもつ
        CallF( ReadObject( &m_state, srcobj ), return 1 );
        break;
    case BEGIN_VERTEX:
        if( currentobj ){
            CallF( ReadVertex( &m_state ), return 1 );
        }else{
            DbgOut( L"MQOFile : LoadMQOFile : BEGIN_VERTEX : currentobj error !!!" );
            _ASSERT( 0 );

            CallF( SkipChunk(), return 1 );
            m_state = BEGIN_FINDCHUNK;
        }
        break;
    case BEGIN_FACE:
        if( currentobj ){
            CallF( ReadFace( &m_state ), return 1 );
        }else{
            DbgOut( L"MQOFile : LoadMQOFile : BEGIN_FACE : currentobj error !!!" );
            _ASSERT( 0 );

            CallF( SkipChunk(), return 1 );
            m_state = BEGIN_FINDCHUNK;
        }
        break;
    case BEGIN_BVERTEX://子チャンクをもつ
        if( currentobj ){
            CallF( ReadBVertex( &m_state ), return 1 );
        }else{
            DbgOut( L"MQOFile : LoadMQOFile : BEGIN_BVERTEX : currentobj error !!!" );
            _ASSERT( 0 );

            CallF( SkipChunk(), return 1 );
            m_state = BEGIN_FINDCHUNK;
        }
        break;
    case BEGIN_COLOR:
        if( currentobj ){
            CallF( ReadColor( &m_state ), return 1 );
        }else{
            DbgOut( L"MQOFile : LoadMQOFile : BEGIN_COLOR : currentobj error !!!" );
            _ASSERT( 0 );

            CallF( SkipChunk(), return 1 );
            m_state = BEGIN_FINDCHUNK;
        }
        break;
    case BEGIN_VERTEXATTR://子チャンクをもつ
        m_state = BEGIN_FINDCHUNK;
        break;

    case BEGIN_VECTOR:
    case BEGIN_WEIT:
    case BEGIN_BLOB:
    case BEGIN_UNKCHUNK:
        CallF( SkipChunk(), return 1 );
        m_state = BEGIN_FINDCHUNK;
        break;

    case BEGIN_TRIALNOISE:
    case BEGIN_FINISH:
    case BEGIN_NONE:
    default:
        m_state = BEGIN_FINISH
        break;
    }
}

難しいことは何もないです。
ミソは対応しないチャンクはSkipChunk()で読み飛ばすことです。


マテリアル

材質(マテリアル)はCMQOMaterialに格納します。
CMQOMaterialの変数メンバは以下のようなものです。

class CMQOMaterial
{
    ...(関数メンバ省略)

public:
    int materialno;
    char name[256];

    D3DXVECTOR4 col;
    float dif;
    float amb;
    float emi;
    float spc;
    float power;
    int texnum;
    char tex[256];
    char alpha[256];
    char bump[256];
    int vcolflag;
    int shader;
////
    D3DXVECTOR4 dif4f;
    D3DXVECTOR3 amb3f;
    D3DXVECTOR3 emi3f;
    D3DXVECTOR3 spc3f;
    D3DXVECTOR4 sceneamb;

    int transparent;
    int texrule;
    int blendmode;

    float uanime;
    float vanime;

    char* curtexname;

    char alphatest;
    unsigned char alphaval;

    float glowmult[3];
    float orgalpha;

    int m_texid;
};

materialnoは自分で付けるマテリアルのシリアル番号です。
nameは材質名、colは基本色、difは拡散光、ambは環境光、emiは自己照明、spcは反射光、powerは反射の強さです。
dif, amb, emi, spcはfloatの係数です。実際の色はこれに基本色colを掛け算したものになります。
この基本色に係数を掛け算したものがdif4f, amb3f, emi3f, spc3fです。

テクスチャについては後の章で説明しますが
簡単に説明すると
texにテクスチャ名を格納し、DirectXで使用できる形式にした後にそのデータへのシリアル番号m_texidを決定します。
描画の際にはこのm_texidによりテクスチャデータを参照します。


vertex, face

mqoのオブジェクトはCMQOObjectクラスに読み込みます。
CMQOObjectの中核は頂点データと面データです。
これらは以下のように宣言されています。

D3DXVECTOR3* m_pointbuf;
    CMQOFace* m_facebuf;

頂点データはm_pointbufに3次元座標として格納します。
面データはCMQOFaceクラスに格納します。
CMQOFaceの変数メンバは以下のようになっています。

class CMQOFace
{

    ...(関数メンバ省略)

public:
    int m_faceno;
    int m_pointnum;
    int m_index[4];
    int m_materialno;

    int m_hasuv;
    D3DXVECTOR2 m_uv[4];

    __int64 m_col[4];
    int m_vcolsetflag;

    int m_dirtyflag;
    int m_serialno;
};

CMQOFaceは線分、三角、四角に対応しています。
線分のときはm_pointnumに2が、三角のときは3が、四角のときは4が入ります。
そして面を構成する頂点の番号がm_indexに入ります。


01章のトップに戻る

オープンソースのトップに戻る

トップページに戻る