Problems initialising DirectX - Window won't load

Started by
4 comments, last by gharen2 16 years, 10 months ago
I initialised it yesterday in a single source file, but thought I'd try and create a "Game" class which handles everything. Everything compiles perfectly, but when the game loads it doesn't actually create a window. The game then crashes when I call the D3D->Clear() function. I can give code if needed. Cheers
Advertisement
Quote:Original post by Side Winder
I can give code if needed. Cheers


Please do, we're not psychic... yet [grin]

Best regards, Omid

Main.cpp
#include "Main.h"Game game;// the entry point for any Windows programint WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){    MSG msg;	ShowWindow(game.GetHWND(), nCmdShow);    while(true)    {        DWORD starting_point = GetTickCount();        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))        {            TranslateMessage(&msg);            DispatchMessage(&msg);	        }		game.renderFrame();		while ((GetTickCount() - starting_point) < 25);	}		           return 0;}



main.h
#ifndef main_h#define main_h#pragma comment (lib, "d3d9.lib")#pragma comment (lib, "d3dx9.lib")#include <windows.h>#include <windowsx.h>#include <d3d9.h>#include <d3dx9.h>#include <cmath>#include "Game.h"#define SCREEN_WIDTH  1280#define SCREEN_HEIGHT 1024#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)#define PI 3.14159265#define TITLE L"Asteroids"extern Game game;LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);#endif


game.h
#ifndef game_h#define game_hclass Game{public:		Game();	~Game();	void InitWindow();	void InitD3D();	void CleanD3D();	void CleanWindow();	void renderFrame();	HWND GetHWND()					{ return m_hWnd; }	LPDIRECT3DDEVICE9 GetDevice()	{ return m_d3dDevice; }		private:			HWND					m_hWnd;	LPDIRECT3D9				m_d3dObject;	LPDIRECT3DDEVICE9		m_d3dDevice;	LPD3DXSPRITE			m_d3dSprite;	LPD3DXFONT				m_d3dFont;	D3DPRESENT_PARAMETERS	m_d3dpp;	LPDIRECT3DTEXTURE9		m_Sprite;				};#endif


game.cpp
#include "Main.h"Game::Game(){	m_d3dObject = NULL;	m_d3dDevice = NULL;	InitWindow();}void Game::InitWindow(){    WNDCLASSEX wc;	wc.cbSize			= sizeof(WNDCLASSEX);    wc.style			= CS_HREDRAW | CS_VREDRAW;    wc.lpfnWndProc		= (WNDPROC)WindowProc;    wc.hInstance		= GetModuleHandle(NULL);    wc.hCursor			= LoadCursor(NULL, IDC_ARROW);    wc.lpszClassName	= L"WindowClass";    RegisterClassEx(&wc);	m_hWnd = CreateWindowEx(NULL, 							L"WindowClass", 							TITLE,							WS_EX_TOPMOST | WS_POPUP, 							0, 0, 							SCREEN_WIDTH, SCREEN_HEIGHT,							NULL, 							NULL, 							GetModuleHandle(NULL), 							NULL);	}Game::~Game(){	CleanD3D();	CleanWindow();}void Game::InitD3D(){	 if ((m_d3dObject = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)	 {		 MessageBox(m_hWnd, L"Error - Failure to load", L"Error", NULL);	 };        ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));    m_d3dpp.Windowed			= FALSE;    m_d3dpp.SwapEffect			= D3DSWAPEFFECT_DISCARD;    m_d3dpp.hDeviceWindow		= m_hWnd;    m_d3dpp.BackBufferFormat	= D3DFMT_X8R8G8B8;    m_d3dpp.BackBufferWidth		= SCREEN_WIDTH;    m_d3dpp.BackBufferHeight	= SCREEN_HEIGHT;    // create a device class using this information and the info from the d3dpp stuct    m_d3dObject->CreateDevice(D3DADAPTER_DEFAULT,							  D3DDEVTYPE_HAL,							  m_hWnd,							  D3DCREATE_SOFTWARE_VERTEXPROCESSING,							  &m_d3dpp,							  &m_d3dDevice);    D3DXCreateSprite(m_d3dDevice, &m_d3dSprite);    // create the Direct3D Sprite object	D3DXCreateTextureFromFileEx(m_d3dDevice,    // the device pointer                                L"ShipBMP.bmp",    // the file name                                D3DX_DEFAULT,    // default width                                D3DX_DEFAULT,    // default height                                D3DX_DEFAULT,    // no mip mapping                                NULL,    // regular usage                                D3DFMT_A8R8G8B8,    // 32-bit pixels with alpha                                D3DPOOL_MANAGED,    // typical memory handling                                D3DX_DEFAULT,    // no filtering                                D3DX_DEFAULT,    // no mip filtering                                D3DCOLOR_XRGB(255, 0, 255),    // the hot-pink color key                                NULL,    // no image info struct                                NULL,    // not using 256 colors                                &m_Sprite);    // load to sprite}void Game::CleanD3D(){	m_d3dDevice->Release();	m_d3dDevice = NULL;	m_d3dObject->Release();	m_d3dObject = NULL;}void Game::CleanWindow(){	UnregisterClass(L"WindowClass", GetModuleHandle(NULL));}void Game::renderFrame(){	m_d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);	m_d3dDevice->BeginScene();	m_d3dDevice->EndScene();	m_d3dDevice->Present(NULL, NULL, NULL, NULL);}


wndproc.cpp
#include "Main.h"LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    switch(message)    {        case WM_DESTROY:            {                PostQuitMessage(0);                return 0;            } break;		case WM_CREATE:			{				game.InitD3D();				SetFocus(hWnd);				break;			}		case WM_KEYDOWN:			{				switch(wParam)				{				case VK_ESCAPE:					{					DestroyWindow(hWnd);					break;					}				}			return 0;			}			    }    return DefWindowProc (hWnd, message, wParam, lParam);}


Also, if you know of anyway to optimise, please let me know. I'm kinda new at this.
It crashes because you forgot to zero out the WNDCLASSEX structure when you initialize your window. The resulting HWND is invalid, and therefore your presentation parameters and your Direct3D device are invalid as well.

WNDCLASSEX wc = {0}; // Alternatively, you can use ZeroMemory()

Another thing that I noticed is that your game loop is endless, resulting in the process never getting killed. Here's how to fix that:

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

You might also want to consider using consts instead of #defines. Also, declare your Game object inside of WinMain() instead of making it a global variable. You can then call InitD3D() from your Game() constructor, as opposed to calling it from your window procedure.
Ok, it works. Thanks. Also, how should I go about making a Sprite class? I'm making a sprite version of asteroids, with sprites for the ship, asteroids, powerups, bullets, UFO etc so I figure I may as well do it properly!
Direct3D already has a sprite class you can use.

This topic is closed to new replies.

Advertisement