Sign in to follow this  
BlackIgloo

Code problem!

Recommended Posts

Hey all i have this code

//>-----------------------------------------------<<//
//>                                               <<//
//>		Ape Dash Application Class                <<//
//>		Created by Matthew Scott                  <<// 
//>		25/05/2007                                <<//
//>                                               <<//
//>-----------------------------------------------<<//

// #include's
#include <windows.h>
#include <d3dx9.h>

// #define's
#define KEYPRESS(KEY) ((GetAsyncKeyState(KEY) & 0x8000) ? 1 : 0)

class ApeDashApplication
{
public:
	ApeDashApplication();
	~ApeDashApplication();
	HRESULT ApeDashApplication::Initialise(HINSTANCE hInstance, int winWidth, int winHeight, bool isWindowed);
	HRESULT ApeDashApplication::Update(float DeltaTime);
	HRESULT ApeDashApplication::Render();
	HRESULT ApeDashApplication::Quit();

private:
	IDirect3DDevice9* pmD3DDevice;
	HWND mMainWindow;
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR cmdLine, int showCmd)
{
	ApeDashApplication ApeDash;

	// Create new windows message, set to NULL
	MSG msg;
	msg.message = WM_NULL;
	// Get Current System Time
	int StartTimer = timeGetTime();

	while(msg.message != WM_QUIT)
	{
		// Process current window messages if avaliable
		if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			// Calculate DeltaTime
			int CurrentTimer = timeGetTime();
			float DeltaTime = (CurrentTimer - StartTimer) * 0.001;


			// Update Application
			ApeDash.Update(DeltaTime);
			// Render Application
			ApeDash.Render();

			// Reset Start Timer
			StartTimer = CurrentTimer;
		}
	}
}

ApeDashApplication::ApeDashApplication()
{
	pmD3DDevice = NULL;
	mMainWindow = 0;
}

ApeDashApplication::~ApeDashApplication()
{
	// Application Cleanup
}

HRESULT ApeDashApplication::Initialise(HINSTANCE hInstance, int winWidth, int winHeight, bool isWindowed)
{
	// DEBUG - Application Initialised!

	// Create and Register WINDOW class
	WNDCLASS apeWndClass;
	memset(&apeWndClass, 0, sizeof(WNDCLASS));
	apeWndClass.style         = CS_HREDRAW | CS_VREDRAW;
	apeWndClass.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
	apeWndClass.hInstance     = hInstance;

	RegisterClass(&apeWndClass);

	// Create new WINDOW
	mMainWindow = CreateWindow("apeWndClass", "ApeDash", WS_EX_TOPMOST, 0, 0, winWidth, winHeight, 0, 0, hInstance, 0);
	SetCursor(NULL);
	ShowWindow(mMainWindow, SW_SHOW);
	UpdateWindow(mMainWindow);

	// Create new Direct3D Interface
	IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

	// Create D3DPRESENT PARAMETERS
	D3DPRESENT_PARAMETERS d3dpp;
	d3dpp.BackBufferWidth            = winWidth;
	d3dpp.BackBufferHeight           = winHeight;
	d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
	d3dpp.BackBufferCount            = 1;
	d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
	d3dpp.MultiSampleQuality         = 0;
	d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
	d3dpp.hDeviceWindow              = mMainWindow;
	d3dpp.Windowed                   = isWindowed;
	d3dpp.EnableAutoDepthStencil     = true; 
	d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
	d3dpp.Flags                      = 0;
	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

	// Create Direct3D9 Device
	d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mMainWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pmD3DDevice);

	// Release Direct3D Interface
	d3d9->Release();

	// Return OK
	return S_OK;
}

HRESULT ApeDashApplication::Update(float DeltaTime)
{
	// Update Stuff!

	// If ESC is pressed Quit()	
	if(KEYPRESS(VK_ESCAPE))
		Quit();

	// Return OK
	return S_OK;
}

HRESULT ApeDashApplication::Render()
{
	// Clear viewport
	pmD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
	// Begin the scene
	pmD3DDevice->BeginScene();

	// Paint Mouse Cursor Last

	// End the scene
	pmD3DDevice->EndScene();
	// Present the scene
	pmD3DDevice->Present(0, 0, 0, 0);

	// Return OK
	return S_OK;
}

HRESULT ApeDashApplication::Quit()
{
	// Destroy MainWindow
	DestroyWindow(mMainWindow);
	// Post Quit Message
	PostQuitMessage(0);
	// Return OK
	return S_OK;
}

Basically im creating a new D3D window but i get this error Unhandled exception at 0x00413d8f in ApeDash.exe: 0xC0000005: Access violation reading location 0x00000000. on line pmD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); when the code is run Cheers for any help

Share this post


Link to post
Share on other sites
Im not a Win32 programmer so I can't comment on much, but the cause of the crash is that you don't call Initialise() on the "ApeDash" variable in main().

Also, seeing as you have created a constructor and destructor, why not move the Initialise code to the constructor, and the Quit code to the destructor?

This way you cannot "forget" to call these methods, and you can guarentee that an ApeDashApplication object is in a consistent state.

The destructor would call DestroyWindow, and then you could still have a Quit method but it would only post the quit message, doing nothing else. Falling out of main would cause the destructor to free the window. Unless win32 specifies that you must destroy the window before PostQuitMessage, as I said Im not a win32 programmer.

Also Im surious as to why all your functions return HRESULTS, given that most of them return a constant anyway and then you don't check the results.

Also note we don't need to qualify methods with the class name while we are declaring them inside a "class Foo { ... };" block.

Does something like this work (ignoring minor errors):


// #include's
#include <windows.h>
#include <d3dx9.h>

// #define's
#define KEYPRESS(KEY) ((GetAsyncKeyState(KEY) & 0x8000) ? 1 : 0)

class ApeDashApplication
{
public:
ApeDashApplication(HINSTANCE hInstance, int winWidth, int winHeight, bool isWindowed);
~ApeDashApplication();
void Update(float DeltaTime);
void Render();
void Quit();

private:
IDirect3DDevice9* pmD3DDevice;
HWND mMainWindow;
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR cmdLine, int showCmd)
{
ApeDashApplication ApeDash(hInstance,800,600,false);

// Create new windows message, set to NULL
MSG msg;
msg.message = WM_NULL;
// Get Current System Time
int StartTimer = timeGetTime();

while(msg.message != WM_QUIT)
{
// Process current window messages if avaliable
if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Calculate DeltaTime
int CurrentTimer = timeGetTime();
float DeltaTime = (CurrentTimer - StartTimer) * 0.001;


// Update Application
ApeDash.Update(DeltaTime);
// Render Application
ApeDash.Render();

// Reset Start Timer
StartTimer = CurrentTimer;
}
}
}

ApeDashApplication::ApeDashApplication(HINSTANCE hInstance, int winWidth, int winHeight, bool isWindowed)
{
pmD3DDevice = NULL;
mMainWindow = 0;

// Create and Register WINDOW class
WNDCLASS apeWndClass;
memset(&apeWndClass, 0, sizeof(WNDCLASS));
apeWndClass.style = CS_HREDRAW | CS_VREDRAW;
apeWndClass.lpfnWndProc = (WNDPROC)::DefWindowProc;
apeWndClass.hInstance = hInstance;

RegisterClass(&apeWndClass);

// Create new WINDOW
mMainWindow = CreateWindow("apeWndClass", "ApeDash", WS_EX_TOPMOST, 0, 0, winWidth, winHeight, 0, 0, hInstance, 0);
SetCursor(NULL);
ShowWindow(mMainWindow, SW_SHOW);
UpdateWindow(mMainWindow);

// Create new Direct3D Interface
IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

// Create D3DPRESENT PARAMETERS
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = winWidth;
d3dpp.BackBufferHeight = winHeight;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = mMainWindow;
d3dpp.Windowed = isWindowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

// Create Direct3D9 Device
d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mMainWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pmD3DDevice);


}

ApeDashApplication::~ApeDashApplication()
{
// Release Direct3D Interface
d3d9->Release();
DestroyWindow(mMainWindow);
}


void ApeDashApplication::Update(float DeltaTime)
{
// Update Stuff!

// If ESC is pressed Quit()
if(KEYPRESS(VK_ESCAPE))
Quit();

}

void ApeDashApplication::Render()
{
// Clear viewport
pmD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
// Begin the scene
pmD3DDevice->BeginScene();

// Paint Mouse Cursor Last

// End the scene
pmD3DDevice->EndScene();
// Present the scene
pmD3DDevice->Present(0, 0, 0, 0);
}

void ApeDashApplication::Quit()
{
// Post Quit Message
PostQuitMessage(0);
}




I'm a bit sceptical about releasing the d3d9 device where you do, it would appear to me that that is done in the destructor, which is why I moved it. Again though, I may b incorrect

HTH.

Share this post


Link to post
Share on other sites
Hi, for what I can see there is that you are accessing a NULL pointer, and I think the problem is here...


HRESULT ApeDashApplication::Initialise(HINSTANCE hInstance, int winWidth, int winHeight, bool isWindowed)
{
/// .....

// YOU DON'T RELEASE THE D3D INTERFACE UNTIL YOU FINISH YOUR PROGRAM
// AND THE D3D DEVICE IT'S ALREADY RELEASED
d3d9->Release();

// Return OK
return S_OK;
}



You are releasing your interface before time...

And you are not releasing your Device at the end of the application, wich results in memory leaks. So what you must do is in the ..::Quit() function, not before, you release first the Device and then the Interface (backward order).

Hope it works! :)

Share this post


Link to post
Share on other sites
cheers thanks for the tips seems to be workin fine now :D

just incase anyone was interested in the final code this is what im going with


//> --------------------------------------------- <<//
//> <<//
//> Ape Dash Application Class <<//
//> Created by Matthew Scott <<//
//> 25/05/2007 <<//
//> <<//
//> --------------------------------------------- <<//

// #include's
#include <windows.h>
#include <d3dx9.h>

// #define's
#define KEYPRESS(KEY) ((GetAsyncKeyState(KEY) & 0x8000) ? 1 : 0)

// global variables


//> ------------------------------------
//> ApeDashApplication class declaration
//> ------------------------------------
class ApeDashApplication
{
public:
ApeDashApplication(HINSTANCE hInstance);
~ApeDashApplication();

void ApeDashApplication::Update(float DeltaTime);
void ApeDashApplication::Render();
void ApeDashApplication::Quit();

protected:
IDirect3D9* pmD3DObject;
IDirect3DDevice9* pmD3DDevice;
HWND mMainWindow;
};



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR cmdLine, int showCmd)
{

ApeDashApplication ApeDash(hInstance);


// Create new windows message, set to NULL
MSG msg;
msg.message = WM_NULL;
// Get Current System Time
int StartTimer = timeGetTime();

while(msg.message != WM_QUIT)
{
// Process current window messages if avaliable
if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Calculate DeltaTime
int CurrentTimer = timeGetTime();
float DeltaTime = (CurrentTimer - StartTimer) * 0.001;


// Update Application
ApeDash.Update(DeltaTime);
// Render Application
ApeDash.Render();

// Reset Start Timer
StartTimer = CurrentTimer;
}
}
}


//> ------------------------------
//> ApeDashApplication Constructor
//> ------------------------------
ApeDashApplication::ApeDashApplication(HINSTANCE hInstance)
{
pmD3DDevice = NULL;
mMainWindow = 0;
int winWidth = 1024;
int winHeight = 768;

// Create NEW window class
WNDCLASS apeWndClass;
apeWndClass.style = CS_HREDRAW | CS_VREDRAW;
apeWndClass.lpfnWndProc = (WNDPROC)::DefWindowProc;
apeWndClass.cbClsExtra = 0;
apeWndClass.cbWndExtra = 0;
apeWndClass.hInstance = hInstance;
apeWndClass.hIcon = LoadIcon(0, IDI_APPLICATION);
apeWndClass.hCursor = LoadCursor(0, IDC_ARROW);
apeWndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
apeWndClass.lpszMenuName = 0;
apeWndClass.lpszClassName = "apeWndClass";

RegisterClass(&apeWndClass);

// Create new WINDOW
mMainWindow = CreateWindow("apeWndClass", "ApeDash", WS_EX_TOPMOST, 100, 100, winWidth, winHeight, 0, 0, hInstance, 0);
SetCursor(NULL);
ShowWindow(mMainWindow, SW_SHOW);
UpdateWindow(mMainWindow);

// Create new Direct3D Interface
pmD3DObject = Direct3DCreate9(D3D_SDK_VERSION);

// Create D3DPRESENT PARAMETERS
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = winWidth;
d3dpp.BackBufferHeight = winHeight;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = mMainWindow;
d3dpp.Windowed = true;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

// Create Direct3D9 Device
pmD3DObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mMainWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pmD3DDevice);

}

//> -----------------------------
//> ApeDashApplication Destructor
//> -----------------------------
ApeDashApplication::~ApeDashApplication()
{
// Release Direct3D Object
pmD3DObject->Release();
// Release Direct3D Device
pmD3DDevice->Release();
// Destroy MainWindow
DestroyWindow(mMainWindow);
}


//> ----------------------------------
//> ApeDashApplication Update function
//> ----------------------------------
void ApeDashApplication::Update(float DeltaTime)
{
// Update Stuff!

// If ESC is pressed Quit()
if(KEYPRESS(VK_ESCAPE))
Quit();

}


//> ----------------------------------
//> ApeDashApplication Render function
//> ----------------------------------
void ApeDashApplication::Render()
{
// Clear viewport
pmD3DDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
// Begin the scene
pmD3DDevice->BeginScene();

// Paint Mouse Cursor

// End the scene
pmD3DDevice->EndScene();
// Present the scene
pmD3DDevice->Present(0, 0, 0, 0);
}


//> --------------------------------
//> ApeDashApplication Quit function
//> --------------------------------
void ApeDashApplication::Quit()
{
// Post Quit Message
PostQuitMessage(0);
}

Share this post


Link to post
Share on other sites
Hey, just as an advice... always check the return values of the functions. For example, in your D3D Device creation code. Imagine that you want to make your application full-screen, but the user (in that case) doesn't support BackBuffer's format of 32 bits. So the program would continue normally but with an invalid pointer for your device, so when it's called it would crash.

The state return value of most of the D3D functions it's a HRESULT variable. This var is kind of complex, but you can check with the macros SUCCEEDED() and FAILED() to see if the function ended ok...

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