Super crash.

Started by
13 comments, last by SSJCORY 18 years, 9 months ago
I am trying to get into d3dxsprites and all and something i did made it CRASH! I cant even run it thru the debugger bc it crashes indefinately and i have to ctrl-alt-delete end task on msvc++. What did i do that was so wrong? i have two files. main.h and main.cpp. MAIN.H

#ifndef MAIN_H
#define MAIN_H
#include<d3d9.h>
#include<d3dx9.h>
#include<string>
using namespace std;
class cPlayer{
private:
	ID3DXSprite *sprite;
	IDirect3DTexture9 *texture;
	int x;
	int y;
	string name;
public:
	cPlayer(IDirect3DDevice9 *device){
		D3DXCreateSprite(device,&sprite);
		D3DXCreateTextureFromFile(device,"default.bmp",&texture);
		x = 0;
		y = 0;
		name = "Default";
	}
	cPlayer(IDirect3DDevice9 *device,string filename){
		D3DXCreateSprite(device,&sprite);
		D3DXCreateTextureFromFile(device,filename.c_str(),&texture);
		x = 0;
		y = 0;
		name = "Default";
	}
	cPlayer(IDirect3DDevice9 *device,string filename,string newname){
		D3DXCreateSprite(device,&sprite);
		D3DXCreateTextureFromFile(device,filename.c_str(),&texture);
		x = 0;
		y = 0;
		name = newname;
	}
	void draw(){
		sprite->Begin();
		sprite->Draw(texture,NULL,NULL,NULL,NULL,NULL,NULL);
		sprite->End();
	}
};
#endif

MAIN.CPP

#include<d3d9.h>
#include<d3dx9.h>
#include"main.h"
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
IDirect3D9 *pd3d;
IDirect3DDevice9 *pdevice;
bool done = false;
cPlayer player1(pdevice);
void initD3D(HWND hwnd){
	pd3d = Direct3DCreate9(D3D_SDK_VERSION);
	D3DDISPLAYMODE displaymode;
	pd3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&displaymode);
	D3DPRESENT_PARAMETERS params;
	ZeroMemory(&params,sizeof(params));
	params.BackBufferHeight = GetSystemMetrics(SM_CYSCREEN);
	params.BackBufferWidth = GetSystemMetrics(SM_CXSCREEN);
	params.SwapEffect = D3DSWAPEFFECT_DISCARD;
	params.Windowed = false;
	params.BackBufferFormat = displaymode.Format;
	pd3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&params,&pdevice);
}
void render(){
	pdevice->Clear(0,NULL,D3DCLEAR_TARGET,RGB(0,0,255),1,0);
	pdevice->BeginScene();
	player1.draw();
	pdevice->EndScene();
	pdevice->Present(NULL,NULL,NULL,NULL);
}
void shutdownD3D(){
	if(pd3d)
	pd3d->Release();
	if(pdevice)
	pdevice->Release();
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam){
	switch(iMsg){
	case WM_DESTROY:
		PostQuitMessage(0);
		done = true;
		break;
	case WM_KEYDOWN:
		switch(wParam){
		case VK_ESCAPE:
			PostQuitMessage(0);
			done = true;
			break;
		}
		break;
	}
	return DefWindowProc(hwnd,iMsg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hpInstance,PSTR cmdLine,int iCmd){
	WNDCLASS wc;
	ZeroMemory(&wc,sizeof(wc));
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.hCursor = LoadCursor(NULL,IDC_ARROW);
	wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = "class";
	wc.lpszMenuName = NULL;
	wc.style = CS_VREDRAW|CS_HREDRAW;
	RegisterClass(&wc);
	HWND hwnd = CreateWindow("class","",WS_OVERLAPPEDWINDOW,0,0,
		GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),NULL,NULL,hInstance,NULL);
	initD3D(hwnd);
	ShowWindow(hwnd,iCmd);
	UpdateWindow(hwnd);
	MSG msg;
	while(!done){
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else{
			render();
		}
	}
	shutdownD3D();
	return 0;
}

Thanks for any help u can give. -Cory
Favorite Quotes:Gandalf: You cannot pass!|Smeagol: We don't need you!|Sloth: Hey you guys!|
Advertisement
Run in windowed mode or hook up your debugger to a seperate monitor/computer so you can see the debugger. Find out what line's causing the problem.
i guess i will try windowed mode i dont ahve another comp/monitor.
-Cory
Favorite Quotes:Gandalf: You cannot pass!|Smeagol: We don't need you!|Sloth: Hey you guys!|
access violation sprite->Begin ...?
-Cory
Favorite Quotes:Gandalf: You cannot pass!|Smeagol: We don't need you!|Sloth: Hey you guys!|
Did your D3D device initialize fine?
Quote:Original post by SSJCORY
access violation sprite->Begin ...?
-Cory


That probably means your ID3DXSprite wasn't initialized properly. Check the HRESULT of D3DXCreateSprite() and verify it SUCCEEDED(). I think the problem might lie in your IDirect3DDevice9 *device constructor parameter. Change it to LPDIRECT3DDEVICE9& device (LPDIRECT3DDEVICE9 is a #define for IDirect3DDevice9*) and see if it works.
I figured it out i'm creating the sprite and texture with a device that is not been created yet because i made the player global. So what i ended up having to do was have the constructor do nothing and i made a method called setUP(IDirect3DDevice9* device){
same as constructor
}
that i call after i call initD3D().
Thanks for your help load_bitmap_file,
-Cory
Favorite Quotes:Gandalf: You cannot pass!|Smeagol: We don't need you!|Sloth: Hey you guys!|
The tile still isnt showing up tho :-/ but no access violation.
#ifndef MAIN_H#define MAIN_H#include<windows.h>#include<d3d9.h>#include<d3dx9.h>#include<string>using namespace std;class cPlayer{private:	ID3DXSprite *sprite;	IDirect3DTexture9 *texture;	int x;	int y;	string name;public:	cPlayer(){	}	cPlayer(IDirect3DDevice9 *device,string filename){		D3DXCreateSprite(device,&sprite);		D3DXCreateTextureFromFile(device,filename.c_str(),&texture);		x = 0;		y = 0;		name = "Default";	}	cPlayer(IDirect3DDevice9 *device,string filename,string newname){		D3DXCreateSprite(device,&sprite);		D3DXCreateTextureFromFile(device,filename.c_str(),&texture);		x = 0;		y = 0;		name = newname;	}	void setUp(IDirect3DDevice9* device){		D3DXCreateSprite(device,&sprite);		D3DXCreateTextureFromFile(device,"default.bmp",&texture);		x = 0;		y = 0;		name = "Default";	}	ID3DXSprite* getsprite(){		return sprite;	}	IDirect3DTexture9* gettexture(){		return texture;	}	void draw(){		sprite->Begin();		sprite->Draw(texture,NULL,NULL,NULL,NULL,NULL,NULL);		sprite->End();	}};#endif

.cpp
#include<d3d9.h>#include<d3dx9.h>#include"main.h"#pragma comment(lib,"d3d9.lib")#pragma comment(lib,"d3dx9.lib")IDirect3D9 *pd3d;IDirect3DDevice9 *pdevice;bool done = false;cPlayer player1;void initD3D(HWND hwnd){	pd3d = Direct3DCreate9(D3D_SDK_VERSION);	D3DDISPLAYMODE displaymode;	pd3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&displaymode);	D3DPRESENT_PARAMETERS params;	ZeroMemory(&params,sizeof(params));	params.BackBufferHeight = 500;	params.BackBufferWidth = 500;	params.SwapEffect = D3DSWAPEFFECT_DISCARD;	params.Windowed = true;	params.BackBufferFormat = displaymode.Format;	pd3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&params,&pdevice);}void render(){	D3DXMATRIX matWorld;	D3DXMatrixIdentity(&matWorld);	pdevice->SetTransform(D3DTS_WORLD,&matWorld);	D3DXMATRIX matView;	D3DXMatrixIdentity(&matView);	D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0,0,-50), &D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,1,0));	pdevice->SetTransform(D3DTS_VIEW,&matView);	D3DXMATRIX matProj;	D3DXMatrixIdentity(&matProj);	D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,GetSystemMetrics(SM_CXSCREEN)/GetSystemMetrics(SM_CYSCREEN),1,1000);	pdevice->SetTransform(D3DTS_PROJECTION,&matProj);	pdevice->Clear(0,NULL,D3DCLEAR_TARGET,RGB(0,0,0),1,0);	pdevice->BeginScene();	player1.getsprite()->Begin();	player1.getsprite()->Draw(player1.gettexture(),NULL,NULL,NULL,NULL,NULL,NULL);	player1.getsprite()->End();	pdevice->EndScene();	pdevice->Present(NULL,NULL,NULL,NULL);}void shutdownD3D(){	if(pd3d)	pd3d->Release();	if(pdevice)	pdevice->Release();}LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam){	switch(iMsg){	case WM_DESTROY:		PostQuitMessage(0);		done = true;		break;	case WM_KEYDOWN:		switch(wParam){		case VK_ESCAPE:			PostQuitMessage(0);			done = true;			break;		}		break;	}	return DefWindowProc(hwnd,iMsg,wParam,lParam);}int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hpInstance,PSTR cmdLine,int iCmd){	WNDCLASS wc;	ZeroMemory(&wc,sizeof(wc));	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);	wc.hCursor = LoadCursor(NULL,IDC_ARROW);	wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);	wc.hInstance = hInstance;	wc.lpfnWndProc = WndProc;	wc.lpszClassName = "class";	wc.lpszMenuName = NULL;	wc.style = CS_VREDRAW|CS_HREDRAW;	RegisterClass(&wc);	HWND hwnd = CreateWindow("class","",WS_OVERLAPPEDWINDOW,0,0,		500,500,NULL,NULL,hInstance,NULL);	initD3D(hwnd);	player1.setUp(pdevice);	ShowWindow(hwnd,iCmd);	UpdateWindow(hwnd);	MSG msg;	while(!done){		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){			TranslateMessage(&msg);			DispatchMessage(&msg);		}		else{			render();		}	}	shutdownD3D();	return 0;}

Thanks,
Cory
Favorite Quotes:Gandalf: You cannot pass!|Smeagol: We don't need you!|Sloth: Hey you guys!|
[edit]Bah - a little too late there - that'll teach me to do other things halfway through a post[/edit]

Problem # 1: cPlayer player1(pdevice);

- that's a global object. Global and static objects are constructed (i.e. cPlayer::cPlayer(IDirect3DDevice9 *device) is called) -=*BEFORE*=- WinMain is called.

- your cPlayer::cPlayer(IDirect3DDevice9 *device) constructor calls some D3DX functions to create the sprite and texture using the passed Direct3D device pointer.

- but because that global constructor is called before WinMain, the device pointer being passed is whatever the compiler initialised the "pdevice" variable to, that might be NULL, that might be complete garbage. The D3DX functions fail because of this

- after your application has gone fullscreen, your draw code tries to use the sprite/texture which wasn't created due to the above. This causes an access violation when you do "sprite->Begin()" - because the "sprite" pointer is NULL. The MSVC debugger traps the access violation and goes to the line that's at fault. Because the debugger is displaying the access violation dialog box, none of your usual application keys work (pressing enter and then shift-F5 might exit properly...).


Problem # 2: the docs for WM_DESTROY and WM_KEYDOWN say "An application should return zero if it processes this message."

- your app isn't - it's just passing the message onto the default handler.

- if you're performing some action such as quitting, you shouldn't be passing the messages on.

- luckily DefWindowProc is doing the right thing for you in these cases, in other cases it might not, and trust me, those kinds of problems can be a swine to track down.


[edit]Problem # 3: It's better to initialise the Direct3D device _after_ the window has been shown.[/edit]


Some advice:

a) always run in windowed mode until you absolutely need to use fullscreen. It means you can single step through your code to debug problems like this

b) link with d3dx9d.lib instead of d3dx9.lib; use the debug Direct3D runtime; and look at the output window. When I link with the debug version of D3DX, I get a hint about your main problem in my debug output: D3DX: pDevice pointer is invalid

c) remember that constructors of globals are called before anything else (where did you expect them to be called?) - so be very careful about whether anything in a global constructor depends on something else already being available/initialised (forget RAII if you're doing things with global objects).

[edit]
d)there could also be an issue with the path used to load your bitmap, i.e. if it's not in the current working directory and not in the \Debug folder of your project, then D3DX might not be able to find the texture. Using D3DX9D.LIB rather than D3DX9.LIB will also tell you if this is the case (look out for "D3DX: default.bmp: The system cannot find the file specified.")
[/edit]

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

still cant figure it out
:'(
-Cory
Favorite Quotes:Gandalf: You cannot pass!|Smeagol: We don't need you!|Sloth: Hey you guys!|

This topic is closed to new replies.

Advertisement