Sign in to follow this  

c++ / Direct3d : access violation problem

This topic is 3742 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

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 information
	D3DXMATERIAL* 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[i] = tempMaterials[i].MatD3D;    // get the material info
		material[i].Ambient = material[i].Diffuse;    // make ambient the same as diffuse
		USES_CONVERSION;    // allows certain string conversions
		// if there is a texture to load, load it
		if(FAILED(D3DXCreateTextureFromFile(d3ddev,
                                           CA2W(tempMaterials[i].pTextureFilename),
                                           &texture[i])))
			texture[i] = 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 public
	public:
		 // 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 pointer
		D3DMATERIAL9* material;    // define the material object
		LPDIRECT3DTEXTURE9* texture;    // a pointer to a texture
		DWORD numMaterials;    // stores the number of materials in the mesh
		LPDIRECT3DDEVICE9 d3ddev;
};

#endif // end if not defined, and end the header file
And finally W3D.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 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
W3DMesh *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_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 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);

    // 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 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, 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[i]);    // set the material for the subset
        if(mesh->texture[i] != NULL)    // if the subset has a texture (if texture is not NULL)
            d3ddev->SetTexture(0, mesh->texture[i]);    // ...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 COM
void 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 RAM
void init_graphics(void)
{
    mesh = new W3DMesh(d3ddev, L"spaceship 2.x");
    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;
}
The code uses these resources : http://www.directxtutorial.com/Graphics/Meshes/airplane%202.x http://www.directxtutorial.com/Graphics/Meshes/bihull.bmp http://www.directxtutorial.com/Graphics/Meshes/wings.bmp Why 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]

Share this post


Link to post
Share on other sites
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[i]); // set the material for the subset
if(mesh->texture[i] != NULL) // if the subset has a texture (if texture is not NULL)
d3ddev->SetTexture(0, mesh->texture[i]); // ...then set the texture


First 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.

Share this post


Link to post
Share on other sites
Quote:
Original post by NestorPL
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[i]); // set the material for the subset
if(mesh->texture[i] != NULL) // if the subset has a texture (if texture is not NULL)
d3ddev->SetTexture(0, mesh->texture[i]); // ...then set the texture


First 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 here


in 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

Share this post


Link to post
Share on other sites

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


At 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.

Share this post


Link to post
Share on other sites

This topic is 3742 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