Problem rendering textures with .x files

Started by
8 comments, last by ILoveSpaced 15 years, 4 months ago
I'm currently writing a 3D rail shooter with DirectX and everything's going fine apart from the class I've written to display .x files. It renders the meshes fine but won't render any textures. I've compared my code to several tutorials and can't see where I'm going wrong and I've been through it with breakpoints, as far as I can tell it's loading the texture but by the time it reaches the render method the output says the texture contains a bad pointer. The meshes I'm using work perfectly in the DirectX visualiser so I'm totally stuck with what I'm doing wrong, does anyone have any suggestions? The constructor is:
SimpleXfile::SimpleXfile(LPCSTR fileName, LPDIRECT3DDEVICE9 device):
myDevice(device)
{
	HRESULT hr = NULL;

	LPD3DXBUFFER mtrlBuffer;
	DWORD numMtrls = NULL;

	// load the xfile
	hr = D3DXLoadMeshFromX(fileName, D3DXMESH_SYSTEMMEM, myDevice, NULL, &mtrlBuffer, NULL, &numMtrls, &myMesh);

	if (FAILED(hr))
	{
		printf("SimpleXfile - Failed to load mesh");
	}

	if (mtrlBuffer && numMtrls != 0)
	{
		D3DXMATERIAL * mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();

		for (int i = 0; i < int(numMtrls); ++i)
		{
			// set the ambient value
			mtrls.MatD3D.Ambient = mtrls.MatD3D.Diffuse;

			// save the material
			myMaterials.push_back(mtrls.MatD3D);

			// if the material has an associated texture, load and save it
			if (mtrls.pTextureFilename)
			{
				IDirect3DTexture9 * tex = NULL;
				D3DXCreateTextureFromFile(myDevice, mtrls.pTextureFilename, &tex);
				myTextures.push_back(tex);
			}
			else
			{
				myTextures.push_back(NULL);
			}
		}
	}

	mtrlBuffer->Release();

	// create vertex normals if the xfile doesn't have any
	if ( !(myMesh->GetFVF() & D3DFVF_NORMAL) )
	{
		// no normals so create a clone of the mesh and add them
		ID3DXMesh * tempMesh = NULL;
		myMesh->CloneMeshFVF(D3DXMESH_MANAGED, myMesh->GetFVF() | D3DFVF_NORMAL, myDevice, &tempMesh);
		D3DXComputeNormals(tempMesh, 0);
		myMesh->Release();
		myMesh = tempMesh;
	}
}
and the render method is:
void SimpleXfile::Render()
{
	for (unsigned int i = 0; i < myMaterials.size(); ++i)
	{
		myDevice->SetMaterial(&myMaterials);
		myDevice->SetTexture(0, myTextures);
		myMesh->DrawSubset(i);
	}
}
It'd be great if someone could help me out, this is holding up my project and I don't have a clue how to fix it, thanks
Advertisement
A common problem is that the paths to the textures do not correspond with the their actual (relative) location on disk. What does D3DXCreateTextureFromFile return? Have a looked what pTextureFilename points to?
Thanks for the reply, D3DXCreateTextureFromFile returns S_OK and pTextureFilename contains Saucer.dds which is the correct filename. As far as paths go, to keep my folders tidy, I have all my code except for main.h and main.cpp in one sub-folder and all my meshes and audio in another sub-folder. This was causing problems with loading the textures in the constructor but was fixed when I moved the textures to the same folder as main.cpp
So if I understand correctly, the problem is fixed? Or do you still having issues with it?


sorry, it's the end of a long day for me ;)
Sorry, no. I meant I was having issues with file paths a while back but fixed those, this is something different (sorry, I should have explained that better in my reply)
No problem. :)

Unfortunately I can't see any obvious problems with it.

Does it show up anything if you bypass the texture loading part and 'hard-code' a texture, as in:

D3DXCreateTextureFromFile(device, "some/texture.bmp", &texture);device->SetTexture(0, texture);/* ... */for (unsigned int i = 0; i < numSubSets; ++i){  mesh->DrawSubset(i);}
Link to the debug D3DX and then check your debug output stream for informative messages. With the debug D3DX library, whenever a D3DX function fails, it reports the reason for the failure to the debug output.

My free book on Direct3D: "The Direct3D Graphics Pipeline"
My blog on programming, vintage computing, music, politics, etc.: Legalize Adulthood!

Thanks for your suggestions. I tried hard coding the texture filename but had the same result as before, it loads the texture but doesn't display it and according to my debug output, none of the functions are failing. It just gives a big list of all the .dlls it loads (most of which are followed by "no symbols loaded") then a list of "Win32 thread ... has exited with code 0 (0x0)"

One thought I had though, I'm scaling the models down a lot in my program, could this be causing problems? It hasn't done in the past but this is the first time I've used my own .x file class rather than someone elses.
Quote:Original post by ILoveSpaced
I tried hard coding the texture filename but had the same result as before, it loads the texture but doesn't display it and according to my debug output, none of the functions are failing.

Do textures show up at all in your application, or is this issue only appearing when using ID3DXMesh meshes? You haven't set any render states that could prevent the (correct) rendering of your texture?

Quote:It just gives a big list of all the .dlls it loads (most of which are followed by "no symbols loaded") then a list of "Win32 thread ... has exited with code 0 (0x0)"

That's normal. Have you, besides linking against them, enabled the debug run times (which can be found in the control panel most of the time) and defined the D3D_DEBUG_INFO preprocessor flag for the maximum debug output? If all of this doesn't give you any clue, you may have to trim your code down to it's simplest form and try to find where it starts to fail.

Quote:One thought I had though, I'm scaling the models down a lot in my program, could this be causing problems? It hasn't done in the past but this is the first time I've used my own .x file class rather than someone elses.

Shouldn't be, unless your scaling your UV coordinates as well, which wouldn't make any sense. You may end up with 'wrong' normals, which could affect the lighting but shouldn't directly influence the texture.
Textures show up fine when I render them on primitives, just not when I use the .x files.

I turned the debug info up to full in the control panel and got the following several times:

First-chance exception at 0x764c42eb in GainDrain.exe: Microsoft C++ exception: long at memory location 0x0012f400..
Direct3D9: (ERROR) :DrawPrimitive failed.

D3D9 Helper: IDirect3DDevice9::DrawPrimitive failed: D3DERR_INVALIDCALL
Direct3D9: (ERROR) :Invalid primitive count

I'm afraid I haven't got a clue what any of this means though, I've tried googling bits of it but only found basic information on DrawPrimitive. What I find strange is that it's rendering all the meshes but saying that DrawPrimitive's failed

This topic is closed to new replies.

Advertisement