Sign in to follow this  
Side Winder

Problems initialising DirectX - Window won't load

Recommended Posts

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

Share this post


Link to post
Share on other sites

Main.cpp
#include "Main.h"

Game game;

// the entry point for any Windows program
int 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_h

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!

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