   c++ / Direct3d : access violation problem
  Hi there,First of all I like to say that I have very little experience in programming c++, but i do have some experience in programming Java, C#, php and a few other languages. My project is not a very big one in terms of the game itself, I chose a small project to learn c++ and directx with. I am following the Direct3D 9 tutorials on http://www.directxtutorial.com. After reading the final lesson (http://www.directxtutorial.com/Tutorial9/C-Direct3DMeshes/dx9C3.aspx) I decided that I wanted to expand the example provided so it would be a bit more useful for a real game. So I decided to create my own mesh class to handle meshes. After moving some of the code to my new class i get MessageBox saying :  Unhandled exception at 0x00412bd1 in Wim3D.exe: 0xC0000005: Access violation reading location 0xcccccccc. This happens after trying to run D3DXLoadMeshFromX(). This is my source code :W3DMesh.cpp// W3DMesh.cpp//// ERROR HAPPENS IN THIS FILE, AFTER RUNNING D3DXLoadMeshFromX() in W3DMesh::load_mesh()#include <d3d9.h>#include <d3dx9.h>#include <atlbase.h>#include "W3DMesh.h"// include the Direct3D Library files#pragma comment (lib, "d3d9.lib")#pragma comment (lib, "d3dx9.lib")W3DMesh::W3DMesh() // Constructor{}W3DMesh::~W3DMesh() // Destructor{delete mesh;    delete material; delete texture;  }W3DMesh::W3DMesh(LPDIRECT3DDEVICE9 &dev, LPCWSTR fileName){d3ddev = dev;load_mesh(fileName);}void W3DMesh::load_mesh(LPCWSTR fileName){LPD3DXBUFFER bufMaterial;D3DXLoadMeshFromX(fileName,    // load this file D3DXMESH_SYSTEMMEM,    // load the mesh into system memory d3ddev,    // the Direct3D Device NULL,    // we aren't using adjacency &bufMaterial,    // put the materials here NULL,    // we aren't using effect instances &numMaterials,    // the number of materials in this model &mesh);    // put the mesh here// retrieve the pointer to the buffer containing the material informationD3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufMaterial->GetBufferPointer();    // create a new material buffer and texture for each material in the mesh    material = new D3DMATERIAL9[numMaterials];    texture = new LPDIRECT3DTEXTURE9[numMaterials];    for(DWORD i = 0; i < numMaterials; i++)    // for each material...    {material = tempMaterials.MatD3D;    // get the material infomaterial.Ambient = material.Diffuse;    // make ambient the same as diffuseUSES_CONVERSION;    // allows certain string conversions// if there is a texture to load, load itif(FAILED(D3DXCreateTextureFromFile(d3ddev,   CA2W(tempMaterials.pTextureFilename),   &texture)))texture = NULL;    // if there is no texture, set the texture to NULL}return;}W3DMesh.h//  W3DMesh.h//#ifndef _MYHEADER_H // if not defined#define _MYHEADER_H // define MyHeader#include <windows.h>#include <windowsx.h>class W3DMesh{// the members placed below the public operator is declared publicpublic: // class constructor (called on class initialisation)W3DMesh();W3DMesh(LPDIRECT3DDEVICE9 &dev, LPCWSTR fileName); // class destructor (called on class destruction)virtual ~W3DMesh();void load_mesh(LPCWSTR fileName);LPD3DXMESH mesh;    // define the mesh pointerD3DMATERIAL9* material;    // define the material objectLPDIRECT3DTEXTURE9* texture;    // a pointer to a textureDWORD numMaterials;    // stores the number of materials in the meshLPDIRECT3DDEVICE9 d3ddev;};#endif // end if not defined, and end the header fileAnd finallyW3D.cpp (this piece of code _should_ be working)// W3D.cpp//// THIS CODE SHOULD BE WORKING FINE, I DONT THINK THERE ARE ANY ERRORS HERE// include the basic windows header files and the Direct3D header file#include <windows.h>#include <windowsx.h>#include <d3d9.h>#include <d3dx9.h>#include <atlbase.h>#include "W3DMesh.h"// define the screen resolution and keyboard macros#define SCREEN_WIDTH 640#define SCREEN_HEIGHT 480#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)// include the Direct3D Library files#pragma comment (lib, "d3d9.lib")#pragma comment (lib, "d3dx9.lib")// global declarationsLPDIRECT3D9 d3d;    // the pointer to our Direct3D interfaceLPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device classLPDIRECT3DVERTEXBUFFER9 t_buffer = NULL;    // the pointer to the vertex bufferLPDIRECT3DSURFACE9 z_buffer = NULL;    // the pointer to the z-bufferW3DMesh *mesh;// function prototypesvoid initD3D(HWND hWnd);    // sets up and initializes Direct3Dvoid render_frame(void);    // renders a single framevoid cleanD3D(void);    // closes Direct3D and releases memoryvoid init_graphics(void);    // 3D declarationsvoid init_light(void);    // sets up the light and the material// the WindowProc function prototypeLRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);// the entry point for any Windows programint WINAPI WinMain(HINSTANCE hInstance,    HINSTANCE hPrevInstance,    LPSTR lpCmdLine,    int nCmdShow){    HWND hWnd;    WNDCLASSEX wc;    ZeroMemory(&wc, sizeof(WNDCLASSEX));    wc.cbSize = sizeof(WNDCLASSEX);    wc.style = CS_HREDRAW | CS_VREDRAW;    wc.lpfnWndProc = (WNDPROC)WindowProc;    wc.hInstance = hInstance;    wc.hCursor = LoadCursor(NULL, IDC_ARROW);    wc.lpszClassName = L"WindowClass1";    RegisterClassEx(&wc);    hWnd = CreateWindowEx(NULL, L"WindowClass1", L"Our Direct3D Program", WS_EX_TOPMOST | WS_POPUP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);    ShowWindow(hWnd, nCmdShow);    // set up and initialize Direct3D    initD3D(hWnd);    // enter the main loop:    MSG msg;    while(TRUE)    {   DWORD starting_point = GetTickCount();   if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))   {  if (msg.message == WM_QUIT) break;  TranslateMessage(&msg);  DispatchMessage(&msg);   }   render_frame();   // check the 'escape' key   if(KEY_DOWN(VK_ESCAPE))  PostMessage(hWnd, WM_DESTROY, 0, 0);   while ((GetTickCount() - starting_point) < 25);    }    // clean up DirectX and COM    cleanD3D();    return msg.wParam;}// this is the main message handler for the programLRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    switch(message)    {   case WM_DESTROY:  { PostQuitMessage(0); return 0;  } break;    }    return DefWindowProc (hWnd, message, wParam, lParam);}// this function initializes and prepares Direct3D for usevoid initD3D(HWND hWnd){    d3d = Direct3DCreate9(D3D_SDK_VERSION);    D3DPRESENT_PARAMETERS d3dpp;    ZeroMemory(&d3dpp, sizeof(d3dpp));    d3dpp.Windowed = TRUE;    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    d3dpp.hDeviceWindow = hWnd;    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;    d3dpp.BackBufferWidth = SCREEN_WIDTH;    d3dpp.BackBufferHeight = SCREEN_HEIGHT;    d3dpp.EnableAutoDepthStencil = TRUE;    // automatically run the z-buffer for us    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;    // 16-bit pixel format for the z-buffer    // create a device class using this information and the info from the d3dpp stuct    d3d->CreateDevice(D3DADAPTER_DEFAULT,  D3DDEVTYPE_HAL,  hWnd,  D3DCREATE_SOFTWARE_VERTEXPROCESSING,  &d3dpp,  &d3ddev);    // create the z-buffer    d3ddev->CreateDepthStencilSurface(SCREEN_WIDTH,   SCREEN_HEIGHT,   D3DFMT_D16,   D3DMULTISAMPLE_NONE,   0,   TRUE,   &z_buffer,   NULL);    init_graphics();    // call the function to initialize the triangle    init_light();    // call the function to initialize the light and material    d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);    // turn on the 3D lighting    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer    d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light    return;}// this is the function used to render a single framevoid render_frame(void){    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);    d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);    d3ddev->BeginScene();    // SET UP THE TRANSFORMS    D3DXMATRIX matView;    // the view transform matrix    D3DXMatrixLookAtLH(&matView,    &D3DXVECTOR3 (0.0f, 8.0f, 16.0f),    // the camera position    &D3DXVECTOR3 (0.0f, 0.0f, 0.0f),    // the look-at position    &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView    D3DXMATRIX matProjection;    // the projection transform matrix    D3DXMatrixPerspectiveFovLH(&matProjection, D3DXToRadian(45),    // the horizontal field of view SCREEN_WIDTH / SCREEN_HEIGHT,    // the aspect ratio 1.0f,    // the near view-plane 100.0f);    // the far view-plane    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);    // set the projection    static float index = 0.0f; index+=0.03f;    // an ever-increasing float value    D3DXMATRIX matRotateY;    // a matrix to store the rotation for each triangle    D3DXMatrixRotationY(&matRotateY, index);    // the rotation matrix    d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY));    // set the world transform // draw the spaceship    for(DWORD i = 0; i < mesh->numMaterials; i++)    // loop through each subset    {   d3ddev->SetMaterial(&mesh->material);    // set the material for the subset   if(mesh->texture != NULL)    // if the subset has a texture (if texture is not NULL)  d3ddev->SetTexture(0, mesh->texture);    // ...then set the texture   mesh->mesh->DrawSubset(i);    // draw the subset    }    d3ddev->EndScene();d3ddev->Present(NULL, NULL, NULL, NULL);    return;}// this is the function that cleans up Direct3D and COMvoid cleanD3D(void){    mesh->mesh->Release();    // close and release the spaceship mesh    d3ddev->Release();    // close and release the 3D device    d3d->Release();    // close and release Direct3D    return;}// this is the function that puts the 3D models into video RAMvoid init_graphics(void){    mesh = new W3DMesh(d3ddev, L"spaceship 2.x");    return;}// this is the function that sets up the lights and materialsvoid init_light(void){    D3DLIGHT9 light;    // create the light struct    ZeroMemory(&light, sizeof(light));    // clear out the struct for use    light.Type = D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'    light.Diffuse.r = 0.5f;    // .5 red    light.Diffuse.g = 0.5f;    // .5 green    light.Diffuse.b = 0.5f;    // .5 blue    light.Diffuse.a = 1.0f;    // full alpha (we'll get to that soon)    D3DVECTOR vecDirection = {-1.0f, -0.3f, -1.0f};    // the direction of the light    light.Direction = vecDirection;    // set the direction    d3ddev->SetLight(0, &light);    // send the light struct properties to light #0    d3ddev->LightEnable(0, TRUE);    // turn on light #0    return;}The code uses these resources :http://www.directxtutorial.com/Graphics/Meshes/airplane%202.xhttp://www.directxtutorial.com/Graphics/Meshes/bihull.bmphttp://www.directxtutorial.com/Graphics/Meshes/wings.bmpWhy do i get that access violation error? I am using Visual Studio 2008 beta on Win XP Pro if thats relevant.[Edited by - wims on September 14, 2007 10:04:14 PM]
  That's a LOT of code to read.But since it happens only in runtime, I'd guess it's somewhere in the drawing code.d3ddev->SetMaterial(&mesh->material);    // set the material for the subset   if(mesh->texture != NULL)    // if the subset has a texture (if texture is not NULL)  d3ddev->SetTexture(0, mesh->texture);    // ...then set the textureFirst of all, I have absolutely NO idea about d3d..However, is number of textures the same as number of materials? You can have different materials (persumably) using the same texture as base. So at some point you might be reading material 20, and trying to access texture 20, while there are only 10 textures in total.That's my first guess, really. You could also try posting about this in the d3d section.Try to include what you have changed from the previous version next time.   ;Quote:Original post by NestorPLThat's a LOT of code to read.But since it happens only in runtime, I'd guess it's somewhere in the drawing code.d3ddev->SetMaterial(&mesh->material);    // set the material for the subset   if(mesh->texture != NULL)    // if the subset has a texture (if texture is not NULL)  d3ddev->SetTexture(0, mesh->texture);    // ...then set the textureFirst of all, I have absolutely NO idea about d3d..However, is number of textures the same as number of materials? You can have different materials (persumably) using the same texture as base. So at some point you might be reading material 20, and trying to access texture 20, while there are only 10 textures in total.That's my first guess, really. You could also try posting about this in the d3d section.Try to include what you have changed from the previous version next time.I'm pretty sure the amount of materials and textures are the same, and the code did work in the tutorial i followed. I just moved parts of the code to a new class. The program doesnt break at that location though, it breaks at  D3DXLoadMeshFromX(fileName,    // load this file D3DXMESH_SYSTEMMEM,    // load the mesh into system memory d3ddev,    // the Direct3D Device NULL,    // we aren't using adjacency &bufMaterial,    // put the materials here NULL,    // we aren't using effect instances &numMaterials,    // the number of materials in this model &mesh);    // put the mesh herein W3DMesh.cpp . There seem to be some kind of problem with the material, because when i hold my mouse pointer over &numMaterials it says numMaterials = 3452816845 (!). When i hold my mouse pointer over &bufMaterial and click through the two nodes thats available i get a node with a warning sign infront of it with this text : __vfptr = CXX0030: Error: expression cannot be evaluated   ;D3DXLoadMeshFromX(fileName,    // load this file D3DXMESH_SYSTEMMEM,    // load the mesh into system memory d3ddev,    // the Direct3D Device NULL,    // we aren't using adjacency &bufMaterial,    // put the materials here NULL,    // we aren't using effect instances &numMaterials,    // the number of materials in this model &mesh);    // put the mesh hereAt least numMaterials is NOT initialised anywhere. Check where you load the data regarding the materials, because currently you're loading the Xmesh with uninitialized data, or the data you're loading it from is corrupted.Also, make sure that you actually manage to load the file and that file format is correct.For now, my bet is on the fact that you did not prepare the variables needed for loading the file, and then try to access textures basing on an unitialised value.   