Problems initialising DirectX - Window won't load
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
Quote:Original post by Side Winder
I can give code if needed. Cheers
Please do, we're not psychic... yet [grin]
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.
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:
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement