Trying to show a sprite

Started by
5 comments, last by Nypyren 15 years, 4 months ago
I am trying to get this to show a sprite there are no error messages in the build log(Visual Studio 2005) but when I compile I get just a blank window and an error message telling me an unhandled win32 exception occured and on which program I would like to debug. Any idea why this is happening? Edit: Updated code.

#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>

IDirect3D9* d3dObject = NULL;
IDirect3DDevice9* d3dDevice = NULL;
LPD3DXSPRITE sprite = NULL;
IDirect3DTexture9* texture = NULL;

void initD3D(HWND);
void closeD3D();
void render();

LRESULT CALLBACK WndProc(HWND, 
						 UINT, 
						 WPARAM,
						 LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, 
				   HINSTANCE hPrevInstance, 
				   LPSTR lpCmdLine, 
				   int nCmdShow)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = (WNDPROC)WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = 0;
	wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = 0;
	wcex.lpszClassName = "WndClass";
	wcex.hIconSm = 0;

	RegisterClassEx(&wcex);
	
	HWND hWnd = CreateWindow("WndClass", "Title", WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
		NULL, NULL, hInstance, NULL);

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	initD3D(hWnd);



	MSG msg;
	ZeroMemory(&msg, sizeof(msg));

	while(msg.message!=WM_QUIT)
	{
		if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		render();

	}

	closeD3D();

	return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, 
						 UINT message, 
						 WPARAM wParam,
						 LPARAM lParam)
{
	switch(message)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

void initD3D(HWND hWnd){
	d3dObject = Direct3DCreate9(D3D_SDK_VERSION);

	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));

	d3dpp.Windowed = FALSE	;	
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

	d3dObject->CreateDevice(D3DADAPTER_DEFAULT, 
							D3DDEVTYPE_HAL,
							hWnd, 
							D3DCREATE_HARDWARE_VERTEXPROCESSING, 
							&d3dpp,
							&d3dDevice);

	D3DXCreateSprite(d3dDevice, &sprite);

	D3DXCreateTextureFromFile(d3dDevice, "chrono.bmp", &texture);

	return;
}

void closeD3D(){
	texture->Release();
	d3dDevice->Release();
	d3dObject->Release();

	return;
}

void render(){
	d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0);

	d3dDevice->BeginScene();

	D3DXVECTOR3 pos;
	pos.x = 10.0f;
	pos.y = 20.0f;
	pos.z = 0.0f;
	
	sprite->Begin(D3DXSPRITE_ALPHABLEND);
	sprite->Draw(texture, NULL, NULL, &pos, 0xFFFFFFFF);
	sprite->End();

	d3dDevice->EndScene();

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

	return;
}

[Edited by - Antonym on December 6, 2008 12:29:18 AM]
Advertisement
To me, it looks like your message pump is the problem.
How so? What should I do?
Look at the logic of your program:

You are processing messages in a while loop until you receive WM_QUIT. Which is a shut down signal for your window. Once you receive that the while loop is left and you show the sprite (on a destroyed window).

It's best to make a inner while loop with PeekMessage and after that the rendering code:

while ( msg.message != WM_QUIT ){  while ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )  {    TranslateMessage( &msg );    DispatchMessage(&msg);  }  // put rendering code here}


Also, one of my favourite nitpicks, remove the return DefWindowProc from the default case and put it after the switch. There is no default return value for unhandled messages and it most certainly is not 0.

It does not make a difference now, but it will once you handle a message which you also have to pass on to DefWindowProc:

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){  switch ( message )  {    case WM_DESTROY:      PostQuitMessage( 0 );      break;  }  return DefWindowProc( hWnd, message, wParam, lParam );}

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Yeah that didn't made sense, I updated the code, the problem is still present though. Now though it doesn't even wait for me to close the window for the error message to pop up(An unhandled win32 exception occured...), it pops up asoon as I compile, the window is still blank ):
I did not really look over the code and I am not even sure if this would cause that error (I'm on my way to work so I can't really look into it, sorry), but are you sure the image is in the correct directory/path? It could be that it is not even being loaded up. Though I am not entirely sure since I don't have much time.

A bunch of the DirectX functions will return a result code (HRESULT maybe, the last time I did C++ DirectX was a few years ago). Try checking the error code after each function and see if any of them return out something other than S_OK or whatever the DirectX 'ok' result is.

DirectX will also spit out some more useful debugging messages... I think the How-To for that is on this site somewhere.

From a quick glance through your code, perhaps try changing your back-buffer format from _UNKNOWN to _A8R8G8B8 or some other 32-bit color depth. I'm not sure what _UNKNOWN actually does.

This topic is closed to new replies.

Advertisement