Loading X File Mesh
by bkenwright@xbdev.net
Once you get your head around how exactly the Direct X File format works, you then have to think up a method of writing a loader! But DirectX gives us a hand with this by supplying some pre-made x file parser API's which make reading in our .x file data a piece of cake.
 | Parsing X File with the DirectX API |  |
The very first thing we need to get familar with, is the API's...which API's we'll use and what we'll use them for:
With the first few pieces of code, well I wrote them a long time ago,...and used the command prompt to compile them. Of course I'm still using Visual Studio, so if you download them...you can simply create a blank project and import the .cpp file and compile it that way.
But once you understand how it all clicks together, you'll be writing your own reusable .x loader....and of course creating super cool games which make your friends drewl :)
Starting simple! Its the best way...especially with tutorials.
DownloadSourceCode
#include <windows.h> #include <stdio.h> #include <rmxftmpl.h> // D3DRM_XTEMPLATES definition #define ULONG_PTR unsigned long #pragma comment(lib, "D3d8.lib") //DirectX 8 Lib Files #pragma comment(lib, "D3dx8.lib") #include <d3dx8.h> //DirectX 8 Header Files #include <Dxfile.h> #pragma comment(lib, "D3dxof.lib") typedef struct sFrame { } sFrame; void ParseXFileData(IDirectXFileData* pData, sFrame* ParentFrame) { DWORD dwSize; pData->GetName(NULL, &dwSize); if( dwSize ) { char str[100]; pData->GetName( str, &dwSize ); //* Ba-Bing - For each Data Type in your .x file - e.g. Mesh, Frame etc *// //* a message box will pop up and tell you. *// MessageBox(0, str, str, 0); } }// End of ParseXFileData(..) bool ParseXFile(char* filename) { IDirectXFile *pDXFile = NULL; IDirectXFileEnumObject *pDXEnum = NULL; IDirectXFileData *pDXData = NULL; DirectXFileCreate(&pDXFile); // requires Dxfile.h and D3dxof.lib // return 0 if okay // Tell direct3D which templates to use pDXFile->RegisterTemplates( (LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES ); // Need to mention "rmxftmpl.h" pDXFile->CreateEnumObject( (LPVOID)filename, DXFILELOAD_FROMFILE, &pDXEnum ); while( pDXEnum->GetNextDataObject(&pDXData) == 0 ) { // Call our custom function that we defined above. ParseXFileData( pDXData, NULL ); } // Tidy up pDXEnum->Release(); pDXFile->Release(); return true; }// End of ParseXFile(..) // Program entry point. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) { ParseXFile("bomb.x"); return 0; }// End of WinMain(..)
Well that code above is what you call the simple code!...My God!....yup...DirectX gives you a lot to swallow in one go doesn't it. But if you run that code, what happens is a messagebox will pop up for each data type.... when I say data type, I mean, Mesh...Material...MaterialList...etc
ParseXFile(..) is the simple setup function...passing the filename and template details to DirectX. The parsing of our data is done in ParseXFileData(..). When I say parse, I mean the data is extracted and put into some sort of data structure which we've defined already. For example if we wanted to just read vertices in...then we would check in that function call for the 'Mesh' identifier...and read the data in and save it. Then when the ParseXFile(..) function has finished, we have our data! Ready to use.
Recursion! Recursion...recursion... Now if your unfamiliar with the principle of functions calling themselves...well you'll have to get used to it. Because the .x file format uses hierarchy...and the simplest way to parse hierarchy of files is by calling functions with themselves...and passing a pointer to the parent....hmmm....
Where the data would for example be:
|