Mesh access violation, Previously working fine.

Started by
7 comments, last by zyrolasting 15 years, 6 months ago
My application, which was working well before, had lost it's ability to function at this line. D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufMaterial->GetBufferPointer(); In this function. void LoadModel(MODEL* Model, LPCTSTR File) { LPD3DXBUFFER bufMaterial; D3DXLoadMeshFromX(File, D3DXMESH_SYSTEMMEM, d3ddev, NULL, &bufMaterial, NULL, &Model->numMaterials, &Model->Mesh); D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufMaterial->GetBufferPointer(); Model->Material = new D3DMATERIAL9[Model->numMaterials]; Model->Texture = new LPDIRECT3DTEXTURE9[Model->numMaterials]; for(DWORD index = 0; index < Model->numMaterials; index++) { Model->Material[index] = tempMaterials[index].MatD3D; Model->Material[index].Ambient = Model->Material[index].Diffuse; USES_CONVERSION; if(FAILED(D3DXCreateTextureFromFile(d3ddev, CA2W(tempMaterials[index].pTextureFilename), &Model->Texture[index]))) Model->Texture[index] = NULL; } return; } Everything in the structure is in order; the compiler complains about nothing. On run, I get an access violation error 0xfffffff 0xC0000005 or whatever is more relevant for the first line I mentioned. The only change I made is adding a struct to my game with floats. Nothing in it could change the behavior of this function. The .x files are where they need to be. HOWEVER, I moved the solution and project files from my Sony VAIO to my Alienware. From Vista to XP, from weaker specs to stronger specs. Both machines have DirectX 9.0c August 2008 Anything about transferring between computers that can cause this? I'M NOT TOO FLUENT IN THAT!
Advertisement
Quote:Original post by zyrolasting
My application, which was working well before, had lost it's ability to function at this line.

D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufMaterial->GetBufferPointer();

In this function.

void LoadModel(MODEL* Model, LPCTSTR File)
{
LPD3DXBUFFER bufMaterial;

D3DXLoadMeshFromX(File,
D3DXMESH_SYSTEMMEM,
d3ddev,
NULL,
&bufMaterial,
NULL,
&Model->numMaterials,
&Model->Mesh);

D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufMaterial->GetBufferPointer();

Model->Material = new D3DMATERIAL9[Model->numMaterials];
Model->Texture = new LPDIRECT3DTEXTURE9[Model->numMaterials];

for(DWORD index = 0; index < Model->numMaterials; index++)
{
Model->Material[index] = tempMaterials[index].MatD3D;
Model->Material[index].Ambient = Model->Material[index].Diffuse;

USES_CONVERSION;
if(FAILED(D3DXCreateTextureFromFile(d3ddev,
CA2W(tempMaterials[index].pTextureFilename),
&Model->Texture[index])))
Model->Texture[index] = NULL;
}

return;
}


Everything in the structure is in order; the compiler complains about nothing.
On run, I get an access violation error 0xfffffff 0xC0000005 or whatever is more relevant for the first line I mentioned. The only change I made is adding a struct to my game with floats. Nothing in it could change the behavior of this function. The .x files are where they need to be.

HOWEVER, I moved the solution and project files from my Sony VAIO to my Alienware. From Vista to XP, from weaker specs to stronger specs.

Both machines have DirectX 9.0c August 2008

Anything about transferring between computers that can cause this?
I'M NOT TOO FLUENT IN THAT!
Your bufMaterial pointer is invalid, probably because D3DXLoadMeshFromX is failing and you're ignoring it.
You MUST check the return values for ALL functions that create an object, or otherwise return information that you rely on, or you'll just crash horribly with errors like you've seen.

Also, installing the Debug Runtimes will help track the problem down.
Please clarify other reasons for an "invalid pointer" as you have mentioned.
The function is creating meshes from .X files with no absolute path, and the meshes are right there with the game so there is no lengthy relative path.
Of course, I mention this if file existence is an issue.

EDIT: I see that the runtime debugger told me one file did fail to load, like you thought. Good to know, but why is that when the path is right? Texture is correct, so is it's path... Loads in viewer. Any thoughts on why it failed on run?

This function is copied and pasted from a tutorial site so I could study wrappers, but nonetheless, there have been no edits. Again, and I stress, it worked fine before, and no changes were made to it.
Do you need to see all code?

It should be apparent by now I'm inexperienced.
I noted your return suggestion and I added FAILED() conditions and changed to HRESULT.
Quote:Original post by zyrolasting
The function is creating meshes from .X files with no absolute path, and the meshes are right there with the game so there is no lengthy relative path.
The .X file needs to be in the current working directory if you're not using a full path, and the CWD isn't necessarily the same as the directory the EXE is in. If you're running your app from Visual Studio, then the CWD is set to the directory that your solution file is in, so you'd need to move the .X file to there if that's the case, or change the CWD in the project settings.
I got into the habit of building the solution and running the app like anything else on my PC. I only run debug builds from inside VS.

Even so, I did place copies of the meshes by the solution and triple-checked that paths. Nothing has changed.

Do you have any other ideas? I don't want to flood this post by adding my code just yet (emphasis on flood), but if it helps, this is what I see in my output box from the runtime debugger.

D3DX: Unicode support: 1
D3DX: Failed to open file floor.x.
D3DX: Failed to open file floor.x.
First-chance exception at 0xffffffff in DirectX Practice.exe: 0xC0000005: Access violation reading location 0xffffffff.
Unhandled exception at 0xffffffff in DirectX Practice.exe: 0xC0000005: Access violation reading location 0xffffffff.

Pretty much the same as I already mentioned.

I would now like to mention I have 2 meshes I'm playing with. The "floor.x" that failed to load is the first mesh to be loaded. So I commented all of it's related code out to allow my other to load. The exact same thing happened, same error id and all.

I'm getting a bit frustrated.
Is the Model pointer passed into the function valid? I just noticed that you're dereferencing it to pass parameters to D3DXLoadMeshFromX. The other possibility is that the File pointer is invalid. In either case, the debugger will let you inspect the values of pointers so you can see where the problem lies.
...I just don't understand what you mean by "invalid pointer".
The parameters just call for the address to a MODEL class, and a LPCTSTR
to a file. This is how I call it.

LoadModel(&Mfloor,L"floor.x");

Mfloor was global, and I am sure it was declared before the call.

Now, I want to mention this error I get at my call to initialize a render for a scene.

The only things in that function are typical. Clear the buffers to black and call BeginScene()

Access violation writing location 0x7e418a01

But you know what? I just can't figure it out, and I'm done chasing wild geese for a solution elsewhere. The same models and their textures have about 3 different copies, clogging up my directories so there should be no excuse for this inability to find files path-wise. Listen thanks for staying with me on this thus far, but let me just ask you to keep it up and look at this code. I appreciate it.

First things first, a class.

class MODEL
{
public:
LPD3DXMESH Mesh;
D3DMATERIAL9* Material;
LPDIRECT3DTEXTURE9* Texture;
DWORD numMaterials;

~MODEL()
{
delete [] Material;
delete [] Texture;
}
};

After the class is made, prototypes are declared and the D3D device initializes, I run this funtion before my main message handling loop begins.
You only need to note the LoadModel calls.

Again, Mfloor and crate are global.

void LoadGraphics()
{
LoadModel(&Mfloor,L"floor.x");
LoadModel(&crate,L"quoCrate.x");
//SetLight(&lght,1,1.0f,0.5f,0.0f, 200.0f);
CreateD3DFont();
SetCamera();
return;
}

I did change LoadModel to HRESULT and enclosed the Load from X function in if (FAILED()) and had it return S_OK if finished.

But this is all I know. If you have an idea, please tell me in a way a novice of DirectX can understand. I really am still fresh meat here.
This line:
D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufMaterial->GetBufferPointer();
Will cause a crash if bufMaterial is an invalid pointer. By "invalid", I mean null, not initialised, already freed, etc.

The only reason that pointer would be invalid is if D3DXLoadMeshFromX() didn't initialise the pointer, and that would only happen if the function fails - Which is what you saw in the debug output.

So, if you're still getting a crash, and you're correctly checking for errors, then the problem is elsewhere, and we'll need to see your new code, the line the crash occurs on, and the output from the debug runtimes.
Would it be alright if I post a link to my solution, zipped and uploaded to a file host for you to look at?

Seems most convenient.

This topic is closed to new replies.

Advertisement