Jump to content
  • Advertisement
Sign in to follow this  
mike_ix

D3DXLoadMeshFromX fails to load any other mesh besides tiger.x!!

This topic is 4486 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What's going on here!?! I think I'm losing my mind. I thought I had conquered the mesh blues, and set this issue aside. I've done everything right so far, and everything works beautifully when I load and render tiger.x. But if I use any other .x file that comes in the DXSDK C++ Samples, D3DXLoadMeshFromX throws an error and fails. I've already checked that all the correct images, etc. are in the correct directories. The DXSDK Mesh Viewer loads all the .x files from the directory my project is in and renders them fine. However, when I load them in my ap, the HRESULT fails and debugger (VS .NET) throws unhandled exception error on the next line where I make an invlaid call to the material buffer with a pointer that was never created by D3DXLoadMeshFromX. Below is the function I use in my Mesh class to load a .x file using D3DXLoadMeshFromX.

MESHOBJECT CMesh::Load(LPCSTR filename, IDirect3DDevice9 *gD3dDevice) {

	LPD3DXMESH   pMeshTemp;
	BOOL         bNormalsInFile;
	MESHOBJECT   workMesh;
	meshMaterials = NULL;
	meshTextures = NULL;
	d3dxMaterials = NULL;
	// Load the mesh from the specified file
	HRESULT hr=D3DXLoadMeshFromX(filename, D3DXMESH_SYSTEMMEM, 
                             gD3dDevice, NULL, 
                             &materialBuffer,NULL, &numMaterials, 
							 &ppMesh );

	if (FAILED(hr)) {
		MessageBox(NULL, "Could not load .x file!", "Error!",
        MB_ICONEXCLAMATION | MB_OK);
		//return false; 
	}
	d3dxMaterials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer();

	meshMaterials = new D3DMATERIAL9[numMaterials];
	meshTextures = new LPDIRECT3DTEXTURE9[numMaterials];

	for (DWORD i=0; i<numMaterials; i++)
	{
		// Copy the material
		meshMaterials = d3dxMaterials.MatD3D;
		// Set the ambient color for the material (D3DX does not do this)
		meshMaterials.Ambient = meshMaterials.Diffuse;

		// Create the texture if it exists - it may not
		meshTextures = NULL;
		if (d3dxMaterials.pTextureFilename)
		D3DXCreateTextureFromFile(gD3dDevice, 
			d3dxMaterials.pTextureFilename,    
			&meshTextures);

	}
	materialBuffer->Release();
	bNormalsInFile = ppMesh->GetFVF() & D3DFVF_NORMAL;
	if ( !(ppMesh->GetFVF() & D3DFVF_NORMAL) )
    {
        hr = ppMesh->CloneMeshFVF( ppMesh->GetOptions(), ppMesh->GetFVF() | D3DFVF_NORMAL, 
                                            gD3dDevice, &pMeshTemp );
        ppMesh->Release();
        ppMesh = pMeshTemp;
    }
	if (!bNormalsInFile)
    {
		D3DXComputeNormals(ppMesh, NULL);
	}
	workMesh.Mesh = ppMesh;
	workMesh.numMat = numMaterials;
	workMesh.mText = new LPDIRECT3DTEXTURE9[numMaterials];
	workMesh.mText = meshTextures;
	workMesh.mMat = new D3DMATERIAL9[numMaterials];
	workMesh.mMat = meshMaterials;


	return workMesh;
	ppMesh->Release();
	ppMeshTemp->Release();
}




The interesting part of this is that the MSDN docs state there are three return values for D3DXLoadMeshFromX (D3D_OK, D3DERR_INVALIDCALL and E_OUTOFMEMORY), but when I test with the later two with something like:

if (hr == D3DERR_INVALIDCALL) { }

-or-

if (hr == E_OUTOFMEMORY) { }

-instead of-

if (FAILED(hr)) { }


then I do not get an error (?!?). Debugger just throws the unhandled exception error on the call to the material buffer. KEEP IN MIND THAT EVERYTHING WORKS FINE WHEN I USE THE tiger.x FILE FROM THE DXSDK DOCS, IT JUST FAILS ON EVERY OTHER .X FILE I TRY! Can anyone help? Perhaps direct me to other .x files I can try besides the ones in the docs? I know it's probably something simple that I'm overlooking. Anyway, ANY ideas would be appreciated!

Share this post


Link to post
Share on other sites
Advertisement
The only advice I can give you is to get extended error information from directx :

1- Switch to debug runtime with maximum warning level and execute your program step-by-step while checking for D3DX outputs (also link to the debug library of D3DX)

2- Using the step-by-step execution or an output procedure, get the HRESULT returned by directx and paste it in the d3d error lookup program located at :
c:/program files/microsoft directx9.0 sdk ***/utilities/x86/ or something like this. Usually, a shortcut to it will be made in the start menu also.

So be sure to analyse carefully:
- What error message directx outputs
- Precisely when in your program the bug happens (which line)

That's all I can do to help you, sorry!

Share this post


Link to post
Share on other sites
OK, it was silly, but the problem was indeed where my .x files and textures were located. Apparently, the .x file needs to be in the directory where my project files are, and the textures need to be in the DEBUG folder when the program runs. I did not realize that the "root folder" changes after compilation, so if I ask to load a .x file by just giving the name of the file (tiger.x instead of meshes\tiger.x, etc.) it considers it to be the folder my project is in (.vcproj) . If I ask D3DXCreateTextureFromFile to load a file in the same way, it considers the root folder to be the one my compiled .exe file is in (the DEBUG folder). I had all my meshes and textures together in the same folder. This is a bit wierd, but it solved the problem. Oh hum. Thanks for the reply though. I think I will implement your ideas anyway as it seems like something I should be doing anyway. Thanks again!

Share this post


Link to post
Share on other sites
There are several Win32 functions that make managing your default directory location easier. When you first startup the app, your working directory is usually the one where your project is, unless you change it in the properties menus. However, if you do an open/save dialog, Windows remembers the last directory chosen, and subsequent attempts by you to load files of various types can fail.

// Save current default path
TCHAR CurrPath[MAX_PATH+1];
DWORD CPL = GetCurrentDirectory(MAX_PATH, CurrPath); // save current directory
if (CPL == NULL)
return E_FAIL;

// Restore it when done
SetCurrentDirectory(CurrPath);

Use _tsplitpath() to break up a drive:directory/filename.extension into its components. This is really handy when loading .x files, if the texture file names include the path, which may not exist on your system.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!