• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            X文件的使用(完整)

            有很多朋友也許想更加了解X文件,正好,本文將全面的介紹X文件的使用。我想這是一篇純技術性的文檔,我就不加以詩篇歌頌潤色了。相信讀我的文章,就像啃牙簽;)好了,我們板起面孔。首先給你一個完整的印象----傳說中的X文件:
            xof 0302txt 0032

             

            template Header {
            <3D82AB43-62DA-11cf-AB39-0020AF71E433>
            DWORD major;
            DWORD minor;
            DWORD flags;
            }

            template Frame {
            <3D82AB46-62DA-11cf-AB39-0020AF71E433>
            [FrameTransformMatrix]
            [Mesh]
            }

            Header {
            1;
            0;
            1;
            }

            Frame Scene_Root {
            FrameTransformMatrix {
            1.000000, 0.000000, 0.000000, 0.000000,
            0.000000, 1.000000, 0.000000, 0.000000,
            0.000000, 0.000000, 1.000000, 0.000000,
            0.000000, 0.000000, 0.000000, 1.000000;;
                                 }
            Frame Pyramid_Frame {
            FrameTransformMatrix {
            1.000000, 0.000000, 0.000000, 0.000000,
            0.000000, 1.000000, 0.000000, 0.000000,
            0.000000, 0.000000, 1.000000, 0.000000,
            0.000000, 0.000000, 0.000000, 1.000000;;
            }
            Mesh PyramidMesh {
            5;
            0.00000;10.00000;0.00000;,
            -10.00000;0.00000;10.00000;,
            10.00000;0.00000;10.00000;,
            -10.00000;0.00000;-10.00000;,
            10.00000;0.00000;-10.00000;;
            6;
            3;0,1,2;,
            3;0,2,3;,
            3;0,3,4;,
            3;0,4,1;,
            3;2,1,4;,
            3;2,4,3;;
            MeshMaterialList {
            1;
            6;
            0,0,0,0,0,0;;
            Material Material0 {
            1.000000; 1.000000; 1.000000; 1.000000;;
            0.000000;  
            0.050000; 0.050000; 0.050000;;
            0.000000; 0.000000; 0.000000;;
                               }
                             }
                             }
                                }
            }
            xof 0302txt 0032
            xof表示這是一個真正的X文件。0302txt表示通知程序使用Directx的X文件,版本為3.2的模版,其中txt表示此文件為文本文件,可讀,并非是一個2進制文件。0032表示一個浮點數的位數為32,如果想要用64位的浮點數,可以寫成0064。

                下面將分別介紹各個主題。

            聲明一個模版:\\\\\\\\\\\\\\假設聲明 template ContactEntry 
            首先需要用guidgen.exe產生一個GUID。產生的GUID如下:
            // {4C9D055B-C64D-4bfe-A7D9-981F507E45FF}
            DEFINE_GUID(<<name>>,
            0x4c9d055b, 0xc64d, 0x4bfe, 0xa7, 0xd9, 0x98, 0x1f, 0x50, 0x7e, 0x45, 0xff);
            之后需要在程序代碼中加入:
            #include "initguid.h"
            // At beginning of source code file - add DEFINE_GUIDs
            DEFINE_GUID(ContactEntry, 0x4c9d055b, 0xc64d, 0x4bfe, 0xa7, 0xd9, 0x98, 0x1f, 0x50, 0x7e, 0x45, 0xff);
            還要在X文件中加入:
            template ContactEntry {
            <4C9D055B-C64D-4bfe-A7D9-981F507E45FF>

            聲明模版用到的數據類型:
            關鍵字       描述
            WORD         16-bit value (short)
            DWORD        32-bit value (32-bit int or long)
            FLOAT        IEEE float value (float)
            DOUBLE       64-bit floating-point value (double)
            CHAR         8-bit signed value (signed char)
            UCHAR        8-bit unsigned value (unsigned char)
            BYTE         8-bit unsigned value (unsigned char)
            STRING       A NULL-terminated string (char[]))
            array        Signifies an array of following data type to follow ([])
            舉例:
            DWORD value;   
            array STRING Text[20];//定義一個名為Text的數組,類型為STRING,大小為20。
            DWORD ArraySize; array STRING Names[ArraySize]; //可以將大小設置為變量。

            聲明一個ContactEntry模版:
            template ContactEntry {
            <4C9D055B-C64D-4bfe-A7D9-981F507E45FF>
            STRING Name; // The contact's name
            STRING PhoneNumber; // The contact's phone number
            DWORD Age; // The contact's age
            }
            實例化一個模版對象:
            ContactEntry JimsEntry {
            "Jim Adams";
            "(800) 555-1212";
            30;
            }
            {JimsEntry} 可以用這樣的形式引用一個數據對象。例如,在一個animation sequence template中引用

            一個Frame data object做為其內嵌數據對象。也可以利用引用表示一個數據對象的副本,沒有必要重復

            書寫這個數據對象。

            內嵌數據對象和模版約束:\\\\\\\\\\\\\\template ClosedTemplate {
            <4C9D055B-C64D-4bfe-A7D9-981F507E45FF>
            DWORD ClosedData;
            }
            template OpenTemplate {
            <4C9D055B-C64D-4bff-A7D9-981F507E45FF>
            DWORD OpenData;
            [...]
            }
            template RestrictedTemplate {
            <4C9D055B-C64D-4c00-A7D9-981F507E45FF>
            DWORD RestrictedData;
            [ClosedTemplate]
            [OpenTemplate]
            }
            ClosedTemplate是標準的模版聲明。
            OpenTemplate中包含一個[...],表示這是一個開放模版。開放模版允許在[]中內嵌任何數據對象。例如

            ,你可以實例化OpenTemplate,在里面定義一個OpenData變量和內嵌一個ClosedTemplate的實例。
            RestrictedTemplate為約束模版。約束模版實例化時只允許包含它列出的數據對象,如,不能在

            RestrictedTemplate包含[ClosedTemplate],[OpenTemplate]以外的數據對象。

            用DirectX .X Standard Templates工作:\\\\\\\\\\\\\\\\\X文件廣泛用于包含一個mesh信息。一個Standard Templates包含了過多的信息。
            Table 3.2: DirectX .X Standard Templates
            Template Name               Description
            Animation:                  Defines animation data for a single frame.
            AnimationKey:               Defines a single key frame for the parent animation template.
            AnimationOptions:           Contains animation playback information.
            AnimationSet:               Contains a collection of animation templates.
            Boolean:                    Holds a Boolean value.
            Boolean2d:                  Holds two Boolean values.
            ColorRGB:                   Contains red, green, and blue color values.
            ColorRGBA:                  Contains red, green, blue, and alpha color values.
            Coords2d:                   Defines two coordinate values.
            FloatKeys:                  Contains an array of floating-point values.
            FrameTransformMatrix:       Holds the transformation matrix for a parent Frame template.
            Frame:                      A frame-of-reference template that defines a hierarchy.
            Header:                     The .X file header that contains version numbers.
            IndexedColor:               Contains an indexed color value.
            Material:                   Contains material color values.
            Matrix4x4:                  Holds a 4x4 homogenous matrix container.
            Mesh:                       Contains a single mesh's data.
            MeshFace:                   Holds a mesh's face data.
            MeshFaceWraps:              Contains the texture wrapping for mesh faces.
            MeshMaterialList:           Contains the material for face-mapping values.
            MeshNormals:                Holds normals used for mesh data.
            MeshTextureCoords:          Holds texture coordinates used for mesh data.
            MeshVertexColors:           Holds vertex color information used for mesh vertices.
            Patch:                      Defines a control patch.
            PatchMesh:                  Contains a patch mesh (much like the Mesh template).
            Quaternion:                 Holds a quaternion value.
            SkinWeights:                Contains an array of weight values mapped to a mesh's vertices. 

            Used in skinned meshes.
            TextureFilename:            Contains the texture file name to use for a material.
            TimedFloatKeys:             Contains an array of FloatKeys templates.
            Vector:                     Holds a 3D coordinate value.
            VertexDuplicationIndices:   Informs you which vertices are duplicates of other vertices.
            XSkinMeshHeader:            Used by skinned meshes to define the number of bones contained 

            in a mesh.
            在rmxfguid.h中定義了各個模版的宏,例如:
            /* {3D82AB44-62DA-11cf-AB39-0020AF71E433} */
            DEFINE_GUID(TID_D3DRMMesh,
            0x3d82ab44, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33);
            每個模版名加上前綴TID_D3DRM就是宏定義名。

            訪問.X文件:\\\\\\\\\\\\\\\\\訪問任何X文件首先要調用DirectXFileCreate函數創建一個IDirectXFile接口。
            IDirectXFile *pDXFile = NULL;
            HRESULT Result = DirectXFileCreate(&pDXFile);//用&pDXFile返回指向接口的指針。用SUCCEEDED或者

            FAILED宏判斷返回值是否有效。

            注冊一個定制ro標準模版:\\\\\\\\\\\\\你可以把X文件中的模版移除,直接在代碼里定義那些模版。IDirectXFile接口支持這樣的特性。需要調

            用IDirectXfile::RegisterTemplates函數。
            HRESULT IDirectXfile::RegisterTemplates(
            LPVOID pvData, // 一個定義模版數據的緩存,應該精確無誤。
            DWORD cbSize); // pvData緩存的字節數。
            可以如下定義一個模版數據的緩存:
            char *Templates = "
            "xof 0303txt 0032 \  //標準X文件頭。
            template CustomTemplate { <4c944580-9e9a-11cf-ab43-0120af71e433> DWORD Length; array DWORD values[Length]; }";
            之后在用RegisterTemplates將其注冊:
            pFile->RegisterTemplates(Templates, strlen(Templates));
            注冊標準模版:
            首先需要在代碼中包含rmxfguid.h和rmxftmpl.h。rmxfguid.h定義了各個標準模版的GUDI,rmxftmpl.h以

            2進制數據形式定義了標準模版數據的緩存和其字節數。然后調用RegisterTemplates將其注冊:
            pFile->RegisterTemplates(D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);

            打開X文件:\\\\\\\\\\\\\\\創建完IDirectXFile接口,注冊模版之后需要打開X文件,枚舉其數據對象。調用

            IDirectXfile::CreateEnumObject函數。
            HRESULT IDirectXfile::CreateEnumObject(LPVOID pvSource, // .X filename
            DXFILELOADOPTIONS dwLoadOptions, // Load options
            LPDIRECTXFILEENUMOBJECT* ppEnumObj); // Enum interface
            當調用CreateEnumObject函數,用pvSource指定一個文件的名字,用ppEnumObj返回一個枚舉對象接口指

            針。用dwLoadOptions指定load操作方式。當指定DXFILELOAD_FROMFILE值,告訴DirectX從磁盤載入一個

            文件。還有DXFILELOAD_FROMRESOURCE,DXFILELOAD_FROMMEMORY和DXFILELOAD_FROMURL分別表示從一個資

            源,內存緩沖和Internet上加載X文件。當從Internet加載文件時,需要為其指定完整的網址。
            下面代碼從磁盤加載X文件:
            // Filename = filename to load ("test.x" for example)
            IDirectXFileEnumObject *pEnum;
            pFile->CreateEnumObject((LPVOID)Filename, DXFILELOAD_FROMFILE, &pEnum);
            Filename指向一個有效的文件名,pEnum返回一個枚舉對象接口指針。

            枚舉數據對象:\\\\\\\\\\\\\\\注冊完模版,打開X文件并且得到一個枚舉對象接口,下面需要從X文件讀出數據。枚舉對象接口指針指向

            文件的第一個數據對象,因為每一個數據對象可能包含內嵌數據對象或者引用的數據對象,所以與第一個

            數據對象同在一層級的其它數據對象為同層級數據對象。至于包含的子數據對象的類型,需要對其分別的

            行進詢問。
            可以用 HRESULT IDirectXFileEnumObject::GetNextDataObject(LPDIRECTXFILEDATA*ppDataObj)得到一

            個IDirectXFileData接口。它只有一個參數,如下:
            IDirectXFileData *pData;
            HRESULT hr = pEnum->GetNextDataObject(&pData);
            利用此函數,可以不斷地訪問同一層級的數據對象接口,具體代碼如下:
            while(SUCCEEDED(pEnum->GetNextDataObject(&pData))) {
            // 這里可以對pData數據對象進行操作。

            pData->Release();//釋放接口。
            }

            當返回值為FAILED,表示已經訪問完所有的接口。當訪問值為SUCCEEDED,你需要繼續判斷這個數據對象

            是否包含子對象。利用接口IDirectXFileObject,和HRESULT IDirectXFileData::GetNextObject( 

            LPDIRECTXFILEOBJECT* ppChildObj)函數,代碼如下:
            IDirectXFileObject *pObject;
            while(SUCCEEDED(pData->GetNextObject(&pObject))) 
            {
            // 如果一個子對象存在,需要繼續詢問它,判斷出它的類型為內嵌數據對象或者引用的數據對象。

            pObject->Release();// 釋放接口。
            }

            接下來詢問接口,看其是否為內嵌數據對象:

            IDirectXFileData *pSubData;
            if(SUCCEEDED(pObject->QueryInterface( IID_IDirectXFileData, (void**)&pSubData))) {
            // 如果詢問內嵌數據對象成功,可以對pSubData數據對象進行操作

            pSubData->Release();//釋放接口。
            }

            看其是否為引用數據對象:

            IDirectXFileDataReference *pRef;
            IDirectXFileData *pSubData;

            if(SUCCEEDED(pSubObj->QueryInterface( IID_IDirectXFileDataReference, (void**)&pRef))) {
            // 如果詢問引用的數據對象成功,解析出引用的原型。
            pRef->Resolve(&pSubData);
            //這里可以對pData數據對象進行操作。

            pRef->Release();
            pSubData->Release();//釋放接口。
            }

            現在整理下思路:大體的思路其實很簡單,首先枚舉最頂層的數據對象,然后判斷其是否有子對象,這個

            子對象可能是內嵌對象或者引用對象二者之一,分別詢問其接口,就可以判斷出具體的類型。

            下面是完整的Parse模版的函數:
            BOOL Parse(char *Filename)
            {
            IDirectXFile *pFile = NULL;
            IDirectXFileEnumObject *pEnum = NULL;
            IDirectXFileData *pData = NULL;

            if(FAILED(DirectXFileCreate(&pFile)))
            return FALSE;
            //注冊標準模版。
            if(FAILED(pFile->RegisterTemplates( (LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES)))
            return FALSE;
            //創建一個枚舉對象接口。
            if(FAILED(pDXFile->CreateEnumObject((LPVOID)Filename, DXFILELOAD_FROMFILE, &pEnum))) {
            pFile->Release();
            return FALSE;
            }
            // 遍歷所有的頂層數據對象。
            while(SUCCEEDED(pEnum->GetNextDataObject(&pData))) {
            // 用ParseObject解析其子數據對象。
            ParseObject(pData);

            pData->Release();
            }

            pEnum->Release();
            pFile->Release();
            return TRUE;
            }

            這個函數的主要部分在ParseObject(pData),它負責解析子數據對象:

            void ParseObject(IDirectXFileData *pData)
            {
              IDirectXFileObject *pObject = NULL;
              IDirectXFileData *pSubData = NULL;
              IDirectXFileDataReference *pRef = NULL;

              while(SUCCEEDED(pData->GetNextObject(&pObject))) {

              if(SUCCEEDED(pObject->QueryInterface( IID_IDirectXFileDataReference, (void**)&pRef))) {

              pRef->Resolve(&pSubData);

              ParseObject(pSubData);

              pSubData->Release();
              pRef->Release();
                                                                                                     }

              if(SUCCEEDED(pObject->QueryInterface( IID_IDirectXFileData, (void**)&pSubData))) {

                ParseObject(pSubData);

                pSubData->Release();
                                                                                                }

              pObject->Release();
                                                                } 
            }
            這是個第歸函數,調用函數自身。判斷子對象的類別,對其繼續解析,直到返回值為FAILED,表示已沒有

            子對象。從上面可以看出,這個函數除了枚舉所有的對象,并沒有做任何事情,下面就要從這些數據對象

            檢索數據。

            從數據對象檢索數據://///////////////
            當你用IDirectXFileData接口指針指向一個有效的數據對象,可以調用IDirectXFileData::GetName函數得到該數據對象的名字。函數原型為:
            HRESULT IDirectXFileData::GetName(
            LPSTR pstrNameBuf, // 名字緩沖
            LPDWORD pdwBufLen); // 名字緩沖的大小
            可以這樣使用這個函數:
            DWORD Size;
            pData->GetName(NULL, &Size);

            char *Name = new char[Size];
            pData->GetName(Name, &Size);
            首先聲明一個DWORD Size變量,調用GetName函數時將第一個參數設為NULL,在Size返回名字緩沖的大小。之后利用這個Size值創建存放名字的緩沖,再調用GetName在Name中返回數據對象的名字。

            得到了數據對象的名字,你需要得到這個數據對象的模版GUID,去判斷這個數據對象是否為你想使用的那個模版的數據對象。利用IDirectXFileData::GetType函數,其原型為:
            HRESULT IDirectXFileData::GetType(const GUID ** ppguid);
            可以這樣使用這個函數:
            const GUID *TemplateGUID = NULL;
            pData->GetType(&TemplateGUID);//在TemplateGUID中返回該數據對象對應模版的GUID。
            現在去匹配這個GUID,看它是否為你想使用的模版的數據對象。
            if(*TemplateGUID == TID_D3DRMMeshNormals) {
            // 如果匹配成功,這里可以繼續處理這個模版的數據對象。
            }
            最后將介紹GetData函數,用它真正的得到了數據對象的數據。其原型為:
            HRESULT IDirectXFileData::GetData(
            LPCSTR szMember, // 設置為NULL
            DWORD *pcbSize, // 數據的大小
            void **ppvData); // 數據指針
            下面介紹用GetData得到數據對象結構的大小和數據對象的數據。
            假設有這樣一個顏色的模版:
            template ColorRGBA {
            <35FF44E0-6C7C-11cf-8F52-0040333594A3>
            FLOAT red;
            FLOAT green;
            FLOAT blue;
            FLOAT alpha;
            }
            你想訪問基于此模版的數據對象的數據你可以這樣做: 
            DWORD DataSize;
            float *DataPtr;
            pData->GetData(NULL, &DataSize, (void**)&DataPtr);
            float red = *DataPtr++;
            float green = *DataPtr++;
            float blue = *DataPtr++;
            float alpha = *DataPtr++;
            得到指向數據對象的數據的指針后,就像訪問一般的結構一樣簡單。當然,你可以做得更直接:
            typedef struct {
            float red, green, blue, alpha;
            } sColorRGBA;//定一個結構方便訪問數據對象的數據。
            sColorRGBA *Color;
            DWORD DataSize;
            pData->GetData(NULL, &DataSize,(void**)&Color);
            這樣訪問數據時更直接:
            float red = Color->red;
            float blue = Color->blue;
            float green = Color->green;
            float alpha = Color->alpha;
            訪問單個變量是很簡單的,下面繼續介紹訪問數組或字符串。
            訪問數組:
            DWORD DataSize;
            DWORD *DataPtr;
            pData->GetData(NULL, &DataSize, (void**)&DataPtr);
            DWORD NumKeys = *DataPtr++;
            for(DWORD i=0;i<NumKeys;i++) {
            float fvalue = *(FLOAT*)DataPtr++;
            訪問字符串:
            DWORD DataSize;
            DWORD *DataPtr;
            pData->GetData(NULL, &DataSize, (void**)&DataPtr);
            char *StringPtr = (char*)DataPtr;
            MessageBox(NULL, StringPtr, "Texture Filename", MB_OK);
            為了訪問數組或字符串,其本質就是把指針轉化成匹配的類型,方便指針的定位操作。

            posted on 2008-05-11 13:32 RedLight 閱讀(554) 評論(0)  編輯 收藏 引用 所屬分類: 3D渲染技術

            <2008年12月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導航

            統計

            公告


            Name: Galen
            QQ: 88104725

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            相冊

            My Friend

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            91精品日韩人妻无码久久不卡| 欧美精品一区二区精品久久| 久久综合鬼色88久久精品综合自在自线噜噜| 精品国产综合区久久久久久| 久久久久国产精品嫩草影院| 亚洲国产精品无码久久久不卡| 日韩一区二区久久久久久| 国产亚州精品女人久久久久久 | 国产精品美女久久福利网站| 久久成人国产精品| 欧美久久久久久精选9999| 一本色道久久88综合日韩精品| 国产成人无码精品久久久免费| 久久亚洲精品无码AV红樱桃| 综合久久一区二区三区 | 少妇无套内谢久久久久| 久久九九全国免费| 久久亚洲中文字幕精品有坂深雪 | 久久精品国产亚洲精品2020| 久久噜噜久久久精品66| 狠狠色丁香久久婷婷综| 久久AV高清无码| 国产成年无码久久久久毛片| 中文字幕无码久久人妻| 国产呻吟久久久久久久92| 精品乱码久久久久久久| 亚洲国产精品无码久久久不卡 | 午夜精品久久久久久毛片| 久久亚洲AV永久无码精品| 国内精品伊人久久久久网站| 韩国无遮挡三级久久| 精品永久久福利一区二区| 亚洲精品无码久久久久久| 久久精品国产男包| 久久人爽人人爽人人片AV| 久久久久波多野结衣高潮| 伊人热热久久原色播放www| 久久97久久97精品免视看秋霞| 色综合久久综合网观看| 精品久久久久久99人妻| 久久久久久久综合综合狠狠|