Sign in to follow this  

crash when trying to load mesh from .x

This topic is 3481 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ok i have followed the tutorial at [URL="http://www.directxtutorial.com"]this site[/url] 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: [img]http://img514.imageshack.us/img514/9940/dxbugzo3.jpg[/img] 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[i]);    // 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[i] = tempMaterials[i].MatD3D;    // get the material info
        material[i].Ambient = material[i].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 :/

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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 -_-

Share this post


Link to post
Share on other sites
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);


Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 here
if( FAILED(hr) ) MessageBox(NULL,"D3DXLoadMeshFromX failed.","Load Error",MB_OK);

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
[quote]Original post by Buckeye
If you use it, you'll need to include dxerr.lib in your links...quote]
how exactly do i do that? *blush*
is it in the project proberties>linker> additional libary directories?
and if, should i just type in "dxerr.lib" ? *even more blush*

Thanks :D

Share this post


Link to post
Share on other sites
No need to blush; we're all learning here.

I'm not sure what interface you're using but try something like:

project properties->linker->input->additional dependencies.

It can't be just a directory. It must be a library.

Oh! I think you can include
#pragma comment(lib,"dxerr.lib").

Share this post


Link to post
Share on other sites
for some reason all the lib, and include directories have been deleted from visual studio :S
anyway should i just put in "#pragma comment (lib,"dxerr.lib")" or should i put it in AND include it in the linker thingy?

[Edited by - craksy on May 30, 2008 10:51:52 AM]

Share this post


Link to post
Share on other sites
I've never used the #pragma libary technique myself. However, it certainly doesn't seem necessary to do both. Just one or the other.

You do need to have the

#include "dxerr.h"

line in any file that calls DXGetErrorDescription.

Share this post


Link to post
Share on other sites
Quote:
No need to blush; we're all learning here.

i dont really care right now:
for(i=0;i<1000000000;i++){
*blush*
}
just not to spam the post with *blush* -_-

anyway: "File not found"
that means that i messed up with the folders where i put the .x file, right?

Share this post


Link to post
Share on other sites
Quote:
"File not found"

Yeah, it looks that way.

Locating resource files can be a little painful, particularly since the path may change when you switch from Debug exe to Release exe.

Suggestion:

Declare a global variable "char appPath[MAX_PATH];" or something similar. In your initialization, call getcwd, look for the root folder of your application in that string and copy it to appPath.

Put resource files in the same location, such as "[appPath]/resources" or similar. Whenever you want to load a file, create a string from appPath and append the resource filename. That way the path will be correct whether you're in Debug or Release.

Share this post


Link to post
Share on other sites

// global variables declared probably in your main cpp file
char appPath[MAX_PATH];
char texturePath[MAX_PATH];

//... somewhere in your initialization in the main cpp file
int pos;
char *appName = "YourAppFolderName"; // like "MyApp", NOT "MyApp/Debug"
// find the texture directory
GetCurrentDirectory(MAX_PATH,texturePath);
pos = (int)strlen(texturePath);
while( true ) { // work backwards until appName found
// find first '\' from end
while( texturePath[pos] != '\\' && pos > 0 ) pos--;
if( pos==0 ) break;
pos++;
if( strnicmp(&texturePath[pos],appName,strlen(appName)) == 0 ) { // found it
texturePath[pos+strlen(appName)] = 0;
strcat(strcpy(appPath,texturePath),"\\");
strcat(texturePath,"\\textures\\");
break;
} else {
pos--;
pos--;
}
}


That's for a texture directory but you can substitute a resource folder name, etc.

Then, when you go to load a resource file located in the folder MyApp\textures:

char path[MAX_PATH];
strcat(strcpy(path,texturePath),"someResource.jpg");
LoadSomeResource(path);

If your resource loading is not done in the same file in which you declare "texturePath," then, near the top of the file add
extern char texturePath[];

Share this post


Link to post
Share on other sites
so i should add the file in the project folder?
as far as i understanded from the tutorial i read, it was enough to add it to the solution explorer!
so my project is named "DirectX" so i should add a folder inside that one named "textures" ?

so i would get something like


// global variables declared probably in your main cpp file
char appPath[MAX_PATH];
char texturePath[MAX_PATH];

//... somewhere in your initialization in the main cpp file
int pos;
char *appName = "DirextX"; // like "MyApp", NOT "MyApp/Debug"
// find the texture directory
GetCurrentDirectory(MAX_PATH,texturePath);
pos = (int)strlen(texturePath);
while( true ) { // work backwards until appName found
// find first '\' from end
while( texturePath[pos] != '\\' && pos > 0 ) pos--;
if( pos==0 ) break;
pos++;
if( strnicmp(&texturePath[pos],appName,strlen(appName)) == 0 ) { // found it
texturePath[pos+strlen(appName)] = 0;
strcat(strcpy(appPath,texturePath),"\\");
strcat(texturePath,"\\textures\\");
break;
} else {
pos--;
pos--;
}
}


??

and the same for meshes?

Share this post


Link to post
Share on other sites
If you want to keep your resource files (jpegs, fx files, etc.) in your project folder, that's okay. I just keep stuff like that in separate folders to keep the clutter down. That's up to you. It's certainly not a requirement.

If you want to keep files in your Windows project folder, then just setup the "appPath" variable and use that. Just make sure the needed files are in the correct Windows folder - like c:/projects/directx - if that's where your project files are. In that case, char *appName = "directx";

You can set a breakpoint after that code and check that appPath = "c:\projects\directx\"

Then you can use it like so:

HRESULT hr;
char path[MAX_PATH];
strcat(strcpy(path,appPath),"resourcefile.x");
hr = D3DXLoadMeshFromX(path,...);
if( FAILED(hr) ) ...

Share this post


Link to post
Share on other sites
well mine is is "C:\Users\<user>\Documents\Visual Studio 2008\Projects\" does that matter?

so i could do like this:


HRESULT hr;
char path[MAX_PATH];
strcat(strcpy(path,appPath),"myMesh.x");
hr = D3DXLoadMeshFromX(C:\Users\<user>\Documents\Visual Studio 2008\Projects\DirectX\);
if( FAILED(hr) ) ...


sorry that you have to cut it out in peices... i am not verry good at this =(

i dont realy understand the code!
never seen stuff like "[MAX_PATH]", and "strcat()"
i have seen the HRESULT before... dont know what it means though -_-

Thanks alot for helping me so far, though i am so hard to explain anything to :/

Share this post


Link to post
Share on other sites
I should have been more specific. This isn't really DirectX stuff; it's basic C and C++ programming.

Assuming the path to your project directory is C:\Users\<user>\Documents\Visual Studio 2008\Projects\DirectX\, you would set
char *appName = "directx";


The GetCurrentDirectory(MAX_PATH,texturePath) fills the char array texturePath with "C:\Users\<user>\Documents\Visual Studio 2008\Projects\DirectX" if you're launching the app from the studio. MAX_PATH is just a global constant defined in stdlib.h that defines the maximum length of a string that the system will return for a path. I use it to size the array so there's no overflow.

The routine I posted starts at the end of the texturePath string, looking for "directx". When it finds that string, it adds a backslash and copies it to the array "appPath."

strcat, strcpy, etc., are string functions for manipulating char arrays. Basic C language stuff.

Why go to the trouble of finding that path? Your code is only valid if your program is launched from the studio environment (or you setup an appropriate shortcut). If you double-click "yourapp.exe" in the \debug directory rather than launching it from the studio environment, your files won't load because the working directory will be "..projects\directx\debug" instead of "..projects\directx."

By including the "appPath" routine and using it as described, your files will always load, provided that your exe file is launched from anywhere in any of the folders in "..projects\directx", whether it's in the \debug or \release folders, etc.

Share this post


Link to post
Share on other sites
ok this is my code:


//those in the top with my other variable, and stuff:
char appPath[MAX_PATH];
char meshPath[MAX_PATH];

//and this in my init_graphics:
void init_graphics(void)
{
LPD3DXBUFFER bufShipMaterial;
HRESULT hr;
char path[MAX_PATH];
strcat(strcpy(path,appPath),"spaceship 2.x");

int pos;
char *appName = "DirextX2"; // like "MyApp", NOT "MyApp/Debug"
// find the texture directory
GetCurrentDirectory(MAX_PATH,texturePath);
pos = (int)strlen(meshPath);
while( true ) { // work backwards until appName found
// find first '\' from end
while( meshPath[pos] != '\\' && pos > 0 ) pos--;
if( pos==0 ) break;
pos++;
if( strnicmp(&meshPath[pos],appName,strlen(appName)) == 0 ) { // found it
texturePath[pos+strlen(appName)] = 0;
strcat(strcpy(appPath,meshPath),"\\");
strcat(texturePath,"\\textures\\");
break;
} else {
pos--;
pos--;
}
}



hr = D3DXLoadMeshFromX(L"spaceship 2.x" ....




if this isn't right ether could you please insert the right values for me, so i can just copy and insert? then i can allways understand it later (sounds kinda lazy).
this is really tearing me apart! i could cry right now :o

i know i am asking for much but i realy need to know this!

heres the info (i guess) you'll need:
app folder: C:\Users\<user>\Documents\Visual Studio 2008\Projects\DirectX
mesh location C:\Users\<user>\Documents\Visual Studio 2008\Projects\DirectX\spaceship 2.x
its also located in the solution explorer in the same folder as my main.cpp .

sorry about asking that much (seriusly) but your my last hope (sounds dramaticly huh?)

Share this post


Link to post
Share on other sites
yes it does have a space.. i can change it if it will course any problems?

anyway, i am getting this error: error C2664: 'GetCurrentDirectoryW' : cannot convert parameter 2 from 'char [260]' to 'LPWSTR'

what do i do here?

Share this post


Link to post
Share on other sites

This topic is 3481 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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