• (2 Pages)
  • +
  • 1
  • 2

Introduction to DirectX Intialization and simple window drawn with DX9

#1 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3120
  • View blog
  • Posts: 19,163
  • Joined: 14-September 07

Posted 03 March 2008 - 03:05 AM

*
POPULAR

We see thread after thread around here on what language to use to make a game or how to program the next halo. The truth is, any language can be used to program a video game (in which case it is simply a loop with animations, user input, sound, etc...) to create an awesome (and sometimes mediocre) interactive experience.

In order to have the computer draw awsome images for you, you need a framework. There are several APIs (Application programming interfaces) out there for game/graphics programming. Some include OpenGL, Allegro, Dark GDK, and of course DirectX. This is microsoft's API that they developed and that has pretty much dominated the commercial video game API scene (especially on PC's.) Since this is a tutorial on some beginning use of DirectX on a PC, I won't be going into MS's XNA or other game programming API's since:

a. they are closely guarded secrets
b. I don't know sqaut about them :P

Alright so let's delve into some fun!

(This tutorial assumes you know how to set up a basic windows app including WinMain, callback, etc...)

DirectX relates to your hardware and software in this manner:

Application --> Direct3D --> HAL (Hardware Abstraction Layer) --> Graphics Device (such as an Nvidia 8800 GTX, etc...)

Your application utilizes DirectX which takes care of the low level HAL and graphics device functions. Back in the earlier days each game/app coder had to write drivers for each type of device. Consider DirectX to be the C++ code instead of having everything in assembly (although it can be used to make algorithms more effcient, so on and so forht).

First, we must intialize DirectX in our program so we can use all of its goodies. This code utilizes a 'game loop' to illustrate where it would go in the code.

/* KYA DirectX tutorial
 * 3-3-08
*/

//header files to include
#include <d3d9.h>
#include <time.h>

//application title
#define APPTITLE "Direct3D_Windowed"

//forward declarations
LRESULT WINAPI WinProc(HWND,UINT,WPARAM,LPARAM);
ATOM MyRegisterClass(HINSTANCE);
int Game_Init(HWND);
void Game_Run(HWND);
void Game_End(HWND);

//Direct3D objects
LPDIRECT3D9 d3d = NULL; 
LPDIRECT3DDEVICE9 d3ddev = NULL; 


//window event callback function
LRESULT WINAPI WinProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
		case WM_DESTROY:
			Game_End(hWnd);
			PostQuitMessage(0);
			return 0;
	}

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


//helper function to set up the window properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	//create the window class structure
	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX); 

	//fill the struct with info
	wc.style		 = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc   = (WNDPROC)WinProc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon		 = NULL;
	wc.hCursor	   = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = APPTITLE;
	wc.hIconSm	   = NULL;

	//set up the window with the class info
	return RegisterClassEx(&wc);
}


//entry point for a Windows program
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR	 lpCmdLine,
				   int	   nCmdShow)
{
	// declare variables
	MSG msg;

	// register the class
	MyRegisterClass(hInstance);

	// initialize application 
	HWND hWnd;

	//create a new window
	hWnd = CreateWindow(
	   APPTITLE,			  //window class
	   APPTITLE,			  //title bar
	   WS_OVERLAPPEDWINDOW,   //window style
	   CW_USEDEFAULT,		 //x position of window
	   CW_USEDEFAULT,		 //y position of window
	   500,				   //width of the window
	   400,				   //height of the window
	   NULL,				  //parent window
	   NULL,				  //menu
	   hInstance,			 //application instance
	   NULL);				 //window parameters

	//was there an error creating the window?
	if (!hWnd)
	  return FALSE;

	//display the window
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	
	//initialize the game
	if (!Game_Init(hWnd))
		return 0;


	// main message loop
	int done = 0;
	while (!done)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
		{
			//look for quit message
			if (msg.message == WM_QUIT)
			{
				MessageBox(hWnd, "Received WM_QUIT message", "WinMain", MB_OK);
				done = 1;
			}

			//decode and pass messages on to WndProc
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
			//process game loop (else prevents running after window is closed)
			Game_Run(hWnd);
	}

	return msg.wParam;
}


int Game_Init(HWND hwnd)
{
	//display init message
	MessageBox(hwnd, "Program is about to start", "Game_Init", MB_OK);

	//initialize Direct3D
	d3d = Direct3DCreate9(D3D_SDK_VERSION);
	if (d3d == NULL)
	{
		MessageBox(hwnd, "Error initializing Direct3D", "Error", MB_OK);
		return 0;
	}

	//set Direct3D presentation parameters
	D3DPRESENT_PARAMETERS d3dpp; 
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

	//create Direct3D device
	d3d->CreateDevice(
		D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, 
		hwnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpp, 
		&d3ddev);

	if (d3ddev == NULL)
	{
		MessageBox(hwnd, "Error creating Direct3D device", "Error", MB_OK);
		return 0;
	}

	//set random number seed
	srand(time(NULL));

	//return okay
	return 1;
}

void Game_Run(HWND hwnd)
{
	//make sure the Direct3D device is valid
	if (d3ddev == NULL)
		return;

	//clear the backbuffer to black
	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,255,0), 1.0f, 0);
	
	//start rendering
	if (d3ddev->BeginScene())
	{
		
	
		//stop rendering
		d3ddev->EndScene();
	}

	//display the back buffer on the screen
	d3ddev->Present(NULL, NULL, NULL, NULL);

}

void Game_End(HWND hwnd)
{
	//display close message
	MessageBox(hwnd, "Program is about to end", "Game_End", MB_OK);

	//release the Direct3D device
	if (d3ddev != NULL) 
		d3ddev->Release();

	//release the Direct3D object
	if (d3d != NULL)
		d3d->Release();
}



Wow, that was alot of code! Let's break it down:

First, you need to link d3d9.lib to your project. Feel free to do it under your project settings or pragma it in whatever you want. Secondly, I compiled all the code in this tutorial using MSVS 2005. Provided you have the DirectX SDK and know your way around your compiler, this should compile for darn near everything.

OK Let's look at the windows portions first:

int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR	 lpCmdLine,
				   int	   nCmdShow)
{
	// declare variables
	MSG msg;

	// register the class
	MyRegisterClass(hInstance);

	// initialize application 
	HWND hWnd;

	//create a new window
	hWnd = CreateWindow(
	   APPTITLE,			  //window class
	   APPTITLE,			  //title bar
	   WS_OVERLAPPEDWINDOW,   //window style
	   CW_USEDEFAULT,		 //x position of window
	   CW_USEDEFAULT,		 //y position of window
	   500,				   //width of the window
	   400,				   //height of the window
	   NULL,				  //parent window
	   NULL,				  //menu
	   hInstance,			 //application instance
	   NULL);				 //window parameters

	//was there an error creating the window?
	if (!hWnd)
	  return FALSE;

	//display the window
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	
	//initialize the game
	if (!Game_Init(hWnd))
		return 0;


	// main message loop
	int done = 0;
	while (!done)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
		{
			//look for quit message
			if (msg.message == WM_QUIT)
			{
				MessageBox(hWnd, "Received WM_QUIT message", "WinMain", MB_OK);
				done = 1;
			}

			//decode and pass messages on to WndProc
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
			//process game loop (else prevents running after window is closed)
			Game_Run(hWnd);
	}

	return msg.wParam;
}



Here we set up our window, various properties, so that we can color, paint, etc... on our window later.

Assuming that everyone understands how windows programs are set up let's discuss the game functions called using some directX features:

Game_Init sets up our 'game' using directX. Notice the DX9 intialization. Usually this creates a pointer to a dirextX9 object that will be referenced throughout the life of a program:

 //initialize Direct3D
	d3d = Direct3DCreate9(D3D_SDK_VERSION);
	if (d3d == NULL)
	{
		MessageBox(hwnd, "Error initializing Direct3D", "Error", MB_OK);
		return 0;
	}



In case there is some sort of error we have the message box tell us so we don't pull our hair out thinking it is a software issue. The most important part of all this code is this:

//create Direct3D device
	d3d->CreateDevice(
		D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, 
		hwnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpp, 
		&d3ddev);



At this point, we won't delve into all of these various parameters, but know that there are many different routes we can take with DX9 objects, and can custom tailor it to our needs (such as bump mapping, lighting, texturing, etc...)

Next we have the Game_Run function:

void Game_Run(HWND hwnd)
{
	//make sure the Direct3D device is valid
	if (d3ddev == NULL)
		return;

	//clear the backbuffer to black
	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,255,0), 1.0f, 0);
	
	//start rendering
	if (d3ddev->BeginScene())
	{
		
	
		//stop rendering
		d3ddev->EndScene();
	}

	//display the back buffer on the screen
	d3ddev->Present(NULL, NULL, NULL, NULL);

}



This is the function that is ran every 'loop' of the program. It is barebones here -- i.e. it does much of nothing, but illustrates how to use directx in a possible game program. the D3D device renders the scene, then ends the scene each time the method is ran. Consecutive images appear as animations to the human eye and thus we are entertained. See this segment:

//clear the backbuffer to black
	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,255,0), 1.0f, 0);



Just like the WinAPI functions such as BitBLT, DirectX draws to an offscreen buffer before the image is sent to your screen (which could be a hardware tutorial all on its own).

After creating objects/devices you must clean up after them! Forgetting to do so can lead to a nasty memory leak later on down the road:

void Game_End(HWND hwnd)
{
	//display close message
	MessageBox(hwnd, "Program is about to end", "Game_End", MB_OK);

	//release the Direct3D device
	if (d3ddev != NULL) 
		d3ddev->Release();

	//release the Direct3D object
	if (d3d != NULL)
		d3d->Release();
}



When running the program, a small window should pop up with a message box that states the 'game is about to start. The window should turn a shade of green and then when you press the 'X' in the upper right corner a message box will state the the 'game' is ending. Hopefully this helped you on your quest to learn more about directX. This barely scratched the surface on what directX can do or what you can do with its features. If this is somewhat well received I'll sit down and write a few more on vertex/matrix processing, some shaders, etc... We can write our D3D functions to create a reusable framework in applications over and over. Never reinvent the wheel!

--KYA

Is This A Good Question/Topic? 6
  • +

Replies To: Introduction to DirectX

#2 born2c0de  Icon User is offline

  • printf("I'm a %XR",195936478);
  • member icon

Reputation: 180
  • View blog
  • Posts: 4,667
  • Joined: 26-November 04

Posted 04 March 2008 - 12:18 AM

Nice Work. :^:
Was This Post Helpful? 0
  • +
  • -

#3 bhandari  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 9
  • View blog
  • Posts: 754
  • Joined: 31-January 08

Posted 04 March 2008 - 12:47 AM

that's quite a different topic touched.
thanks for that!!!
Was This Post Helpful? 0
  • +
  • -

#4 xerox23  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 27-April 09

Posted 11 May 2009 - 05:50 AM

how do you get the d3d9/10.lib?
Was This Post Helpful? 0
  • +
  • -

#5 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Posted 11 May 2009 - 05:34 PM

View Postxerox23, on 11 May, 2009 - 06:50 AM, said:

how do you get the d3d9/10.lib?


You need to download the DirectX SDK from Microsoft.
Was This Post Helpful? 0
  • +
  • -

#6 mainak001  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 25-June 09

Posted 08 August 2009 - 02:42 AM

View PostSixOfEleven, on 11 May, 2009 - 04:34 PM, said:

View Postxerox23, on 11 May, 2009 - 06:50 AM, said:

how do you get the d3d9/10.lib?


You need to download the DirectX SDK from Microsoft.



If u can tell how to add d3d9.h to the code it will be helpful to me .. I'm trying to run a program where it is not able to locate the D3D9.h , though i've added the header file by clicking add reference dialog .
Was This Post Helpful? 0
  • +
  • -

#7 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3120
  • View blog
  • Posts: 19,163
  • Joined: 14-September 07

Posted 08 August 2009 - 06:59 PM

Put it in the compiler/IDE's include folder, if you're using Visual Studio:

C:\Program Files\Microsoft Visual Studio 8\VC\include

(for example), you could also have a subfolder (like I do):

C:\Program Files\Microsoft Visual Studio 8\VC\include\d3d

All the headers are in there. Like SixOfEleven said, you'll need to aquire these files from the directX SDK.
Was This Post Helpful? 0
  • +
  • -

#8 James_Alex  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 156
  • Joined: 21-August 09

Posted 04 October 2009 - 03:36 PM

i always got "Error creating Direct3D device"
and i juste taked the Game_init and Game_Run Functions
so i tryed to create a device in an other game window !
Pes 2009
is this possible ?
Was This Post Helpful? 0
  • +
  • -

#9 LuckyPierre  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 30
  • Joined: 23-September 09

Posted 08 October 2009 - 05:34 PM

Hi,

Trying to compile this using Visual Studio 2008 and getting the following error:

1>------ Build started: Project: DirectX01, Configuration: Debug Win32 ------
1>Compiling...
1>DirectX01.cpp
1>c:\users\ross\documents\visual studio 2008\projects\directx01\directx01\directx01.cpp(58) : error C2440: '=' : cannot convert from 'const char [18]' to 'LPCWSTR'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

which is pointing to line:


	wc.lpszClassName = APPTITLE;




(line 58 for me..)


I've installed the latest directX sdk so not sure what I should be doing ....

Help!
Was This Post Helpful? 0
  • +
  • -

#10 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3120
  • View blog
  • Posts: 19,163
  • Joined: 14-September 07

Posted 08 October 2009 - 09:26 PM

Check your unicode settings, you may need to put a L in front of the text.
Was This Post Helpful? 0
  • +
  • -

#11 LuckyPierre  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 30
  • Joined: 23-September 09

Posted 11 October 2009 - 04:44 PM

View PostKYA, on 8 Oct, 2009 - 08:26 PM, said:

Check your unicode settings, you may need to put a L in front of the text.


it was indeed unicode settings.. I changed them in the project settings...

interesting... ...

Thanks!

This post has been edited by LuckyPierre: 11 October 2009 - 04:44 PM

Was This Post Helpful? 0
  • +
  • -

#12 Kutlar  Icon User is offline

  • New D.I.C Head

Reputation: 6
  • View blog
  • Posts: 29
  • Joined: 04-March 10

Posted 06 July 2010 - 08:36 PM

Very fun stuff thanks!
Was This Post Helpful? 0
  • +
  • -

#13 sbdurdaller  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 19-April 13

Posted 20 April 2013 - 10:24 AM

"(This tutorial assumes you know how to set up a basic windows app including WinMain, callback, etc...)"

I'm already stumped. I have no idea what WinMain or callback is. Is there anything on here that lets me start out at a little lower of a level? Thanks.
Was This Post Helpful? 0
  • +
  • -

#14 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3120
  • View blog
  • Posts: 19,163
  • Joined: 14-September 07

Posted 20 April 2013 - 11:59 AM

You'll want to check out some WinAPI tutorials. Here's one from me.

Snoopy11 has a bunch of Win32 tutorials as well.
Was This Post Helpful? 0
  • +
  • -

#15 Magn0733  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 57
  • Joined: 04-April 13

Posted 21 May 2013 - 06:35 AM

Hey, When i try to setup DirectX (the first box), i get 2 errors:

error LNK2019: unresolved external symbol _Direct3DCreate9@4 referenced int function "int_cdecl Game_Init(struct HWND_*)" (?Game_Init@@YAHPAUHWND_@@@Z).

error LNK2020: unresolved externals?

What is this and how do i fix it? :)
Guess it's a problem with my directories? but i did link both libaries and includes? :)
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2