Sign in to follow this  
m4gnus

App crashes while rendering a x-file

Recommended Posts

Hi I want to write a class that loads and renders a X-file and i fixed most of the errors and the app starts but crashes when i call the render function :( the errormessage says "The instruction at 0x00401a6c points at storage at 0x00000000. The operation "read" can not perfromed on this storage. Click ok to blablabla" The class:
#include "XMesh.h"
#include <iostream>
#include <d3d9.h>
#include <d3dx9mesh.h>
using namespace std;
LPD3DXBUFFER pMaterialBuffer;
ID3DXMesh* pMesh;
DWORD NumMaterials = 0;
D3DMATERIAL9* pMeshMats;
LPDIRECT3DTEXTURE9* pMeshTexs;
LPDIRECT3DDEVICE9 Device;


void XMesh::LoadXFile(char filePath[256],LPDIRECT3DDEVICE9 Device) {
if( FAILED( D3DXLoadMeshFromX(filePath,D3DXMESH_SYSTEMMEM,Device, NULL,&pMaterialBuffer, NULL,&NumMaterials,&pMesh)))
{

MessageBox(NULL, "Could not find .xFile",
			     "Blabla.exe", MB_OK);
            
}
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();

D3DMATERIAL9* pMeshMaterials = new D3DMATERIAL9[NumMaterials];
LPDIRECT3DTEXTURE9* pMeshTextures  = new LPDIRECT3DTEXTURE9[NumMaterials];

//Extract the Materialinfromation
for(DWORD i=0;i<NumMaterials;i++) {  //for start
pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
if( FAILED( D3DXCreateTextureFromFile(Device, 
d3dxMaterials[i].pTextureFilename, &pMeshTextures[i] ) ) )
pMeshTextures[i] = NULL;
} //for-end

//MaterialBuffer not needed anymore
pMaterialBuffer->Release();
}
void XMesh::Render() {

for(DWORD i=0;i<NumMaterials;i++){
//set the material
Device->SetMaterial(pMeshMats);
//set texture
Device->SetTexture(0,*pMeshTexs);
//draw the subset
pMesh->DrawSubset(i);
//jump to next Material and next Texture
pMeshMats++;
pMeshTexs++;
}
}

btw. in my main unit i also have a method called Render but i don't think that that is the problem.. regards, m4gnus Edited by Coder: Added source tags [Edited by - Coder on December 5, 2004 11:28:43 AM]

Share this post


Link to post
Share on other sites
The "The instruction at 0x00401a6c points at storage at 0x00000000. The operation "read" can not perfromed on this storage. Click ok to blablabla" error usually means you are trying to dereferance a NULL pointer. From looking at your code I'm guessing this could be occuring in one of two places (or maybe even both):

replace
if( FAILED( D3DXCreateTextureFromFile(Device, d3dxMaterials[i].pTextureFilename, &pMeshTextures[i] ) ) )
pMeshTextures[i] = NULL;






with
 if(d3dxMaterials[i].pTextureFilename)
{
if( FAILED( D3DXCreateTextureFromFile(Device, d3dxMaterials[i].pTextureFilename, &pMeshTextures[i] ) ) ) { assert(false); }
}
else { pMeshTextures[i] = NULL; }







and replace
//set texture
Device->SetTexture(0,*pMeshTexs);






with
 if(pMeshTexs) { Device->SetTexture(0,*pMeshTexs); }
else { Device->SetTexture(0,0); }







Hope this fixes your problem. Failing that, assert that pointers are non-zero before you dereference any and you should catch the problem before the program crashes. Note that when you pass a pointer into a DX function, chances are it'll get derefenced inside the function so make sure these are non-zero too.

[Edited by - Motorherp on December 4, 2004 6:52:45 AM]

Share this post


Link to post
Share on other sites
My guess is it'll be the pTextureFilename pointer. If this is NULL then D3DXCreateTextureFromFile(...) will be trying to read a string from 0x00000000 (ie NULL), hence the error. But I can't be 100% sure without actualy being there.

Share this post


Link to post
Share on other sites
how can i look which pointer is NULL?? i tried if(d3dxMaterials[i].pTextureFilename==NULL) {
MessageBox(NULL, "NULL",
"Blabla.exe", MB_OK);
}

but that didn't help...still the assertion error. Any suggestions how to fix that? and how is it possible that the pointer to nothing? i mean the x-file has been loaded and the material buffer should work too(that part is copied from the directX9 c++ reference).

regards,
m4gnus

Share this post


Link to post
Share on other sites
the problem has to be there:
Device->SetMaterial(pMeshMats);

When i open a messageBox before that command the messageBox shows up but when i place the messageBox after it there's only the usual Windows message with the storage reda stuff...but i don't know how to fix that :( that's my 2nd directX app..
I thought probably "pMeshMats=pMeshMaterials;" is wrong so i changed it to: "pMeshMats=&pMeshMaterials[0];" don't know if sth is wrong there...

regards,
m4gnus

Share this post


Link to post
Share on other sites
ok forget about the pointer i think the problem has something to do with the device, because neither SetMaterial nor SetTexture works...is everything wrong with the device? how can i drectly get the device?? atm i get it with the LoadXFile function as a parameter but that isn't a very good way...

i edited the code a little bit:


#include "XMesh.h"
#include <iostream>
#include <d3d9.h>
#include <d3dx9mesh.h>
#include <assert.h>
using namespace std;
LPD3DXBUFFER pMaterialBuffer;
ID3DXMesh* pMesh;
DWORD NumMaterials = 0;
D3DMATERIAL9* pMeshMats;
LPDIRECT3DTEXTURE9* pMeshTexs;



void XMesh::LoadXFile(char filePath[256],LPDIRECT3DDEVICE9 Device) {
if( FAILED( D3DXLoadMeshFromX(filePath,D3DXMESH_SYSTEMMEM,Device, NULL,&pMaterialBuffer, NULL,&NumMaterials,&pMesh)))
{
MessageBox(NULL, "Could not find .xFile",
"Blabla.exe", MB_OK);

}
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();

D3DMATERIAL9* pMeshMaterials = new D3DMATERIAL9[NumMaterials];
LPDIRECT3DTEXTURE9* pMeshTextures = new LPDIRECT3DTEXTURE9[NumMaterials];

//Extract the Materialinfromation
for(DWORD i=0;i<NumMaterials;i++) { //for start
pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
if( FAILED( D3DXCreateTextureFromFile(Device, d3dxMaterials[i].pTextureFilename, &pMeshTextures[i] ) ) ) { assert(false); }
if(d3dxMaterials[i].pTextureFilename)
{
if( FAILED( D3DXCreateTextureFromFile(Device, d3dxMaterials[i].pTextureFilename, &pMeshTextures[i] ) ) ) { assert(false); }
}
else { pMeshTextures[i] = NULL; }
} //for-end

pMeshMats=pMeshMaterials;
pMeshTexs=pMeshTextures;


//MaterialBuffer not needed anymore
pMaterialBuffer->Release();

}
void XMesh::Render(LPDIRECT3DDEVICE9 d3dDevice) {

for(DWORD i=0;i<NumMaterials;i++){
//set the material

d3dDevice->SetMaterial(pMeshMats);

//set texture
if(pMeshTexs) { d3dDevice->SetTexture(0,*pMeshTexs); }
else { d3dDevice->SetTexture(0,0); }
//draw the subset
pMesh->DrawSubset(i);
//jump to next Material and next Texture
pMeshMats++;
pMeshTexs++;
}
}



regards,
m4gnus

Edited by Coder: Added source tags

[Edited by - Coder on December 5, 2004 11:56:03 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by m4gnus
and how is it possible that the pointer to nothing? i mean the x-file has been loaded and the material buffer should work too(that part is copied from the directX9 c++ reference).

Its possible to have a material without a texture, hence the texure filname pointer in this instance will be NULL. Also in your new code you should remove the first call to D3DXCreateTextureFromFile.
Quote:
Original post by m4gnus
how can i drectly get the device?? atm i get it with the LoadXFile function as a parameter but that isn't a very good way...

Ok, you've just pointed out what the problem you are having is. The device is something you have to create an instance of and initialise yourself before you can start using DirectX functionality. This is usualy initialised to a global pointer or singleton so that you can then get to the device from anywhere in your program. The device pointer paramater in the D3DXCreateTextureFromFile(...) function is used for inputting a pointer to the device you've already created rather than it outputting the device pointer for you. Check the DirectX SDK Docs for more info on setting up DirectX or use the sample code frame that comes supplied.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this