crash when trying to load mesh from .x

Started by
34 comments, last by craksy 15 years, 10 months ago
ok i have followed the tutorial at this site and (almost) everything went just fine until i came to the "load mesh from .x file". when i try to debug this the program stops with a "error... bla bla bla.. error.. even more bla" with a continue, and brake button, followed by a bunch of these: dxbugzo3.jpg and the debug output: "First-chance exception at 0x010d4899 in DirectX2.exe: 0xC0000005: Access violation reading location 0xcccccccc. Unhandled exception at 0x010d4899 in DirectX2.exe: 0xC0000005: Access violation reading location 0xcccccccc." it stops at this line: D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufShipMaterial->GetBufferPointer(); full code:

// include the basic windows header files and the Direct3D header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.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 declarations
LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class
LPDIRECT3DVERTEXBUFFER9 t_buffer = NULL;    // the pointer to the vertex buffer
LPDIRECT3DSURFACE9 z_buffer = NULL;    // the pointer to the z-buffer

// mesh declarations
LPD3DXMESH meshSpaceship;    // define the mesh pointer
D3DMATERIAL9* material;    // define the material object
DWORD numMaterials;    // stores the number of materials in the mesh


// function prototypes
void initD3D(HWND hWnd);    // sets up and initializes Direct3D
void render_frame(void);    // renders a single frame
void cleanD3D(void);    // closes Direct3D and releases memory
void init_graphics(void);    // 3D declarations
void init_light(void);    // sets up the light and the material

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


// the entry point for any Windows program
int 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_OVERLAPPEDWINDOW,
                          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 program
LRESULT 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 use
void 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);

    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 frame
void 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, 4.0f, 8.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 < numMaterials; i++)    // loop through each subset
    {
        d3ddev->SetMaterial(&material);    // set the material for the subset
        meshSpaceship->DrawSubset(i);    // draw the subset
    }

    d3ddev->EndScene(); 

    d3ddev->Present(NULL, NULL, NULL, NULL);

    return;
}


// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
    meshSpaceship->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 RAM
void init_graphics(void)
{
    LPD3DXBUFFER bufShipMaterial;

    D3DXLoadMeshFromX(L"spaceship 2.x",    // load this file
                      D3DXMESH_SYSTEMMEM,    // load the mesh into system memory
                      d3ddev,    // the Direct3D Device
                      NULL,    // we aren't using adjacency
                      &bufShipMaterial,    // put the materials here
                      NULL,    // we aren't using effect instances
                      &numMaterials,    // the number of materials in this model
                      &meshSpaceship);    // put the mesh here

    // retrieve the pointer to the buffer containing the material information
    D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufShipMaterial->GetBufferPointer();

    // create a new material buffer for each material in the mesh
    material = new D3DMATERIAL9[numMaterials];

    for(DWORD i = 0; i < numMaterials; i++)    // for each material...
    {
        material = tempMaterials.MatD3D;    // get the material info
        material.Ambient = material.Diffuse;    // make ambient the same as diffuse
    }

    return;
}


// this is the function that sets up the lights and materials
void 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;
}


i hope you can help me! in advance: Thanks! PS: i am not sure if i got the code tags right... had trouble with them before :/
Advertisement
Take a look at your bla-bla-bla. bufShipMaterial was not set.

First: it doesn't appear that you check ANY return codes for any of your calls.

You have dozens of lines of code which you're assuming will work correctly.. and they don't. Now you're complaining. :-)

Until you're sure your code and resources are correct, check return codes from DirectX calls and you'll get fewer problems like the one you encountered.

What return code do you get from the D3DXLoadMeshFromX call?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

i copied the code from a tutorial http://www.directxtutorial.com, so it should be working :S
i know this make it sound like "let me rip off some code, and make a game" but i actually read through the tutorial! just copied and pasted the code to make sure that i didnt have any errors :/

the messagebox that pops up says "Unhandled exception at 0x00054899 in DirectX2.exe: 0xC0000005: Access violation reading location 0xcccccccc." (maybe i should have writing that instead of "bla"?)

and it doesnt say anything about return code in the error/debug output -_-
Quote:so it should be working..


But it doesn't.

You can check the return code from the call yourself.
HRESULT hr;hr = D3DXLoadMeshFromX(...);if( FAILED(hr) ) MessageBox(NULL,DXGetErrorDescription(hr),"Load Error",MB_OK);


Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

i guess not?

error C2143: syntax error : missing ')' before '...'
1>c:\users\silas\documents\visual studio 2008\projects\directx2\directx2\main.cpp(102) : error C2660: 'D3DXLoadMeshFromXW' : function does not take 0 arguments
1>c:\users\silas\documents\visual studio 2008\projects\directx2\directx2\main.cpp(102) : error C2059: syntax error : ')'
1>c:\users\silas\documents\visual studio 2008\projects\directx2\directx2\main.cpp(103) : error C3861: 'DXGetErrorDescription': identifier not found
i guess not?

error C2143: syntax error : missing ')' before '...'
1>c:\users\silas\documents\visual studio 2008\projects\directx2\directx2\main.cpp(102) : error C2660: 'D3DXLoadMeshFromXW' : function does not take 0 arguments
1>c:\users\silas\documents\visual studio 2008\projects\directx2\directx2\main.cpp(102) : error C2059: syntax error : ')'
1>c:\users\silas\documents\visual studio 2008\projects\directx2\directx2\main.cpp(103) : error C3861: 'DXGetErrorDescription': identifier not found
The example code I posted was for you to implement, not copy. ;-)

It shows you how you can get the return code from your function call and check it. Your code would look something like:
HRESULT hr;hr = D3DXLoadMeshFromX(L"spaceship 2.x",    // load this file                      D3DXMESH_SYSTEMMEM,    // load the mesh into system memory                      d3ddev,    // the Direct3D Device                      NULL,    // we aren't using adjacency                      &bufShipMaterial,    // put the materials here                      NULL,    // we aren't using effect instances                      &numMaterials,    // the number of materials in this model                      &meshSpaceship);    // put the mesh hereif( FAILED(hr) ) MessageBox(NULL,"D3DXLoadMeshFromX failed.","Load Error",MB_OK);

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Why are you loading the mesh into the SYSTEMMEM pool?
i kinda figured out when i actually read the code :P

anyway how should a messagebox saying "D3DXLoadMeshFromX failed" help me?
Your first post said execution stopped at the line:
D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufShipMaterial->GetBufferPointer();

The message box (or something similar which you should always include in your code) will probably tell you that the error isn't with the line above but in your LoadMesh call.

You don't check return values for errors in your code. In general, when execution stops at a line, the error is likely elsewhere in your code.

Quote:anyway how should a messagebox saying "D3DXLoadMeshFromX failed" help me?

A better question to ask is, "If the D3DXLoadMeshFromX call failed, why?"

How else are you going to find out if the D3DXLoadMesh call is correct?

EDIT: Take a look at the DXGetErrorDescription function. If you use it, you'll need to include dxerr.lib in your links and "#include dxerr.h" in any .cpp that uses that function.

You can use that function directly in a message box:
if(FAILED(hr)) MessageBox(NULL,DXGetErrorDescription(hr),"Error!",MB_OK | MB_ICONEXCLAMATION);



[Edited by - Buckeye on May 29, 2008 1:18:21 PM]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement