• <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>

            天行健 君子當(dāng)自強而不息

            Using the .X File Format(6)

            Enumerating Data Objects

            At this point, you have opened your .X file and registered the templates you'll be using (such as the DirectX standard templates). The enumeration object has been created, and you are now ready to pull data from the .X file.

            In its current state, the IDirectXFileEnumObject object you created points to the first data object in the file, which is typically the Header object. All top−level data objects are siblings of the Header object (or the first object in the file). Each data object you read might contain embedded objects (child objects) or references to other data objects; you can query for both of these.

            The enumerator object itself doesn't handle a data object's data. Rather, you need to obtain a data object interface, called IDirectXFileData, to access the data.

            Applications use the methods of the IDirectXFileData interface to build or to access the immediate hierarchy of the data object. Template restrictions determine the hierarchy. Data types allowed by the template are called optional members. The optional members are not required, but an object might miss important information without them. These optional members are saved as children of the data object. The children can be another data object, a reference to an earlier data object, or a binary object. Deprecated.

            IDirectXFileData Members

            Method Description
            IDirectXFileData::AddBinaryObject Creates a binary object and adds it as a child object. Deprecated.
            IDirectXFileData::AddDataObject Adds a data object as a child object. Deprecated.
            IDirectXFileData::AddDataReference Creates and adds a data reference object as a child object. Deprecated.
            IDirectXFileData::GetData Retrieves the data for one of the object's members or the data for all members. Deprecated.
            IDirectXFileData::GetNextObject Retrieves the next child data object, data reference object, or binary object in the DirectX file. Deprecated.
            IDirectXFileData::GetType Retrieves the GUID of the object's template. Deprecated.

            Remarks

            The GUID for the IDirectXFileData interface is IID_IDirectXFileData.

            The LPDIRECTXFILEDATA type is defined as a pointer to this interface.

            typedef interface IDirectXFileData *LPDIRECTXFILEDATA;

            To obtain an IDirectXFileData interface, you need to call the IDirectXFileEnumObject::GetNextDataObject function.

            Retrieves the next top-level object in the DirectX file. Deprecated.

            HRESULT GetNextDataObject(
            LPDIRECTXFILEDATA * ppDataObj
            );

            Parameters

            ppDataObj
            [out] Address of a pointer to an IDirectXFileData interface, representing the returned file data object.

            Return Values

            If the method succeeds, the return value is DXFILE_OK. If the method fails, the return value can be one of the following values: DXFILEERR_BADVALUE, DXFILEERR_NOMOREOBJECTS

            Remarks

            Top-level objects are always data objects. Data reference objects and binary objects can only be children of data objects.

            With only one parameter, the GetNextDataObject is a breeze to use. You just need to instance an IDirectXFileData object and use it in your call to GetNextDataObject.

            IDirectXFileData *pData;
            HRESULT hr = pEnum−>GetNextDataObject(&pData);

            Notice how I'm saving the return value of the GetNextDataObject call? If the return code is an error(which you can check by using the FAILED macro), it signifies that the enumeration is complete. If the call to GetNextDataObject is successful, then you have yourself a spiffy new interface for accessing the data object's data!

            Before you get into working with the object's data, let's finish the discussion on enumeration. So far, you've been able to enumerate the first data object in a file and retrieve its data interface. What do you do when you want to go to the next data object in the .X file or query for embedded data objects?

            Once you're finished with a data interface, you need to free it to go to the next data object. Simply calling IDirectXFileData::Release will free the data interface, and repeating the call to IDirectXFileEnumObject::GetNextDataObject will get the next enumerated sibling (top−level) data object for you. You can wrap the entire enumeration of siblings (grabbing their respective data interfaces)
            into a code bite such as this one:

            while(SUCCEEDED(pEnum−>GetNextDataObject(&pData))) {
              // Do something with pData data object
              // Free the data interface in order to continue
              pData−>Release();
            }

            All that's left is to add the ability to query for child (lower−level) data objects, and to allow those child objects to be enumerated and accessed. To query for a child data object, you use the IDirectXFileData::GetNextObject function to first see whether a data object contains any embedded objects.

            Retrieves the next child data object, data reference object, or binary object in the DirectX file. Deprecated.

            HRESULT GetNextObject(
            LPDIRECTXFILEOBJECT * ppChildObj
            );

            Parameters

            ppChildObj
            [out, retval] Address of a pointer to an IDirectXFileObject interface, representing the returned child object's file object interface.

            Return Values

            If the method succeeds, the return value is DXFILE_OK. If the method fails, the return value can be one of the following values: DXFILEERR_BADVALUE, DXFILEERR_NOMOREOBJECTS.

            Remarks

            To determine the type of object retrieved, use QueryInterface to query the retrieved object for support of IDirectXFileData, IDirectXFileDataReference, or IDirectXFileBinary interfaces. The interface supported indicates the type of object (data, data reference, or binary).

            This is another simple function with only one parameter−the pointer to an IDirectXFileObject interface. If the call to GetNextObject is successful, then you need to process the child data object. Once you've done that, you can free it (by calling Release) and continue calling GetNextObject until it returns an error code, which signifies that no more child objects remain.

            You can wrap the continuous calling of GetNextObject into a small loop, as I have done here.

            IDirectXFileObject *pObject;

            while(SUCCEEDED(pData−>GetNextObject(&pObject))) {
              // A child data object exists, need to query for it
              // Free file object interface
              pObject−>Release();
            }

            Once you have a valid IDirectFileObject interface (after the call to GetNextObject), you can quickly determine which child data object it is currently enumerating (using the techniques coming up in the next section). There's a slight snag, however. A data object can either be referenced or instanced, and the way you access the object varies a bit depending on which type it is.

            For instanced objects (those defined normally in an .X file), you can query the IDirectXFileObject for an IDirectXFileData interface.

            IDirectXFileData *pSubData;

            // Check if child object is instanced (fails if not)
            if(SUCCEEDED(pObject−>QueryInterface( IID_IDirectXFileData, (void**)&pSubData))) {
              // Child data object exists, do something with it.
              // Free data object
              pSubData−>Release();
            }

            Using what you've just learned, you can query a child data object's IDirectXFileData object for its own embedded child objects.

            As for referenced data objects, you need to first query for the IDirectXFileDataReference object and resolve the reference into an IDirectXFileData object.

            Applications use the methods of the IDirectXFileDataReference interface to support data reference objects. A data reference object refers to a data object that is defined earlier in the file. This enables you to use the same object multiple times without repeating it in the file. Deprecated.

            IDirectXFileDataReference Members

            Method Description
            IDirectXFileDataReference::Resolve Resolves data references. Deprecated.

            Remarks

            After you have determined that an object is a data reference object, use the IDirectXFileDataReference::Resolve method to retrieve the referenced object defined earlier in the file. For information about how to identify a data reference object, see the IDirectXFileData interface.

            The GUID for the IDirectXFileDataReference interface is IID_IDirectXFileDataReference.

            The LPDIRECTXFILEDataReference type is defined as a pointer to this interface.

            typedef interface IDirectXFileDataReference *LPDIRECTXFILEDATAREFERENCE;

            IDirectXFileDataReference::Resolve

            Resolves data references. Deprecated.

            HRESULT Resolve(
            LPDIRECTXFILEDATA * ppDataObj
            );

            Parameters

            ppDataObj
            [out, retval] Address of a pointer to an IDirectXFileData interface, representing the returned file data object.

            Return Values

            If the method succeeds, the return value is DXFILE_OK. If the method fails, the return value can be one of the following values: DXFILEERR_BADVALUE, DXFILEERR_NOTFOUND.

            The following code will query and resolve the referenced data object for you.

            Tip If an instanced data object does not exist when you query for it, the call to QueryInterface will fail. This is a quick way to tell the type of the data object. The same goes for referenced objects−the query will fail, meaning the object is not referenced.

            IDirectXFileDataReference *pRef;
            IDirectXFileData *pSubData;

            // Check if the data object is referenced (fails if not)
            if(SUCCEEDED(pSubObj−>QueryInterface(IID_IDirectXFileDataReference, (void**)&pRef))) {
              // A data object reference exists. Resolve the reference
              pRef−>Resolve(&pSubData);

              // Do something with data object
              // Release the interfaces used
              pRef−>Release();
              pSubData−>Release();
            }

            Would you believe me if I told you that the hardest part is over? Enumerating the data objects and child objects is simple, and if that's as hard as it gets, then you're in for an easy ride! To make your programming job much easier, I suggest wrapping up the entire enumeration of data objects into two simple functions.

            The first function (called Parse) will open an .X file, create the enumeration object, and enumerate all top−level data objects. The function will then take each enumerated object and pass it to the second function (ParseObject), which will process the data object data based on its template type and scan for embedded child data objects. The ParseObject function will call itself using any child objects it finds, thus processing a child's embedded objects.

            The code for the Parse function follows.

            // Need to include rmxftmpl.h and rmxfguid.h
            BOOL Parse(char *Filename)
            {
            IDirectXFile *pFile = NULL;
            IDirectXFileEnumObject *pEnum = NULL;
            IDirectXFileData *pData = NULL;
            	// Create the enumeration object, return on error
            if(FAILED(DirectXFileCreate(&pFile)))
            return FALSE;
            	// Register the standard templates, return on error
            if(FAILED(pFile−>RegisterTemplates((LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES)))
            return FALSE;
            	// Create the enumeration object, return on error
            if(FAILED(pDXFile−>CreateEnumObject((LPVOID)Filename, DXFILELOAD_FROMFILE, &pEnum))) {
            pFile−>Release();
            return FALSE;
            }
            	// Loop through all top−level data objects
            while(SUCCEEDED(pEnum−>GetNextDataObject(&pData))) {
            // Parse the data object by calling ParseObject
            ParseObject(pData);
            		// Release the data object
            pData−>Release();
            }
            	// Release used COM objects
            pEnum−>Release();
            pFile−>Release();
            return TRUE;
            }

            The Parse function doesn't hold back any punches, and it certainly isn't overly complicated. I have already explained everything in the function, so there's no need to recap here. Instead, move on to the ParseObject function, which takes a data object and queries it for child objects.

            void ParseObject(IDirectXFileData *pData)
            {
            IDirectXFileObject *pObject = NULL;
            IDirectXFileData *pSubData = NULL;
            IDirectXFileDataReference *pRef = NULL;
            	// Scan for embedded objects
            while(SUCCEEDED(pData−>GetNextObject(&pObject))) {
            // Look for referenced objects
            if(SUCCEEDED(pObject−>QueryInterface(IID_IDirectXFileDataReference, (void**)&pRef))) {
            // Resolve the data object
            pRef−>Resolve(&pSubData);
            			// Parse the object by calling ParseObject
            ParseObject(pSubData);
            			// Free interfaces
            pSubData−>Release();
            pRef−>Release();
            }
            		// Look for instanced objects
            if(SUCCEEDED(pObject−>QueryInterface(IID_IDirectXFileData, (void**)&pSubData))) {
            // Parse the object by calling ParseObject
            ParseObject(pSubData);
            // Free the object interface
            pSubData−>Release();
            }
            		// Free the interface for next object to use
            pObject−>Release();
            }
            }

            Again, the ParseObject function doesn't contain anything new. The one thing you'll notice about Parse and ParseObject is that they don't really do anything except enumerate every data object in an .X file. When it comes time to work with an object's data, what do you do?


            posted on 2008-04-17 18:44 lovedday 閱讀(673) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評論

            少妇久久久久久久久久| 精品伊人久久久| 国产精品一久久香蕉国产线看| 午夜精品久久久久成人| 久久久久久极精品久久久| 久久亚洲精品成人av无码网站| 久久99精品久久只有精品| 久久精品国产只有精品2020| 久久精品国产精品青草| 久久久久久国产a免费观看不卡 | 久久精品国产一区二区| 国产精品亚洲综合专区片高清久久久| 欧美亚洲另类久久综合婷婷| 久久天天躁夜夜躁狠狠躁2022| 国内精品久久久人妻中文字幕| 久久久久久综合一区中文字幕 | 欧美麻豆久久久久久中文| 色播久久人人爽人人爽人人片aV| 久久精品www人人爽人人| 久久国产精品二国产精品| 伊人伊成久久人综合网777| 色8久久人人97超碰香蕉987| 热综合一本伊人久久精品| 99久久精品费精品国产一区二区| 久久久久亚洲AV成人网人人网站| 久久精品国产91久久综合麻豆自制| 欧美精品丝袜久久久中文字幕 | 国产精品久久久久久一区二区三区 | 久久亚洲美女精品国产精品| 亚洲国产精品久久久久婷婷老年| 精品一二三区久久aaa片| 久久久精品午夜免费不卡| 久久久久亚洲AV无码麻豆| 国产成人久久精品一区二区三区| 性做久久久久久久久| 国产精品岛国久久久久| 久久久噜噜噜久久熟女AA片| 久久久亚洲裙底偷窥综合| 久久午夜福利无码1000合集| 99久久国产亚洲综合精品| 久久天天躁狠狠躁夜夜不卡|