DirectX 游戏编程之开篇

DirectX并不是一个单纯的图形API,它是由微软公司开发的用途广泛的API,它包含有Direct Graphics(Direct 3D+Direct Draw)、Direct Input、Direct Play、Direct Sound、Direct Show、Direct Setup、Direct Media Objects等多个组件,它提供了一整套的多媒体接口方案。
DirectX是一系列的COM对象或接口,Direct 3D只是DirectX的一个部分,Direct3D是一个相当高级的类,它封装了你运行2D和3D图形所需要的全部硬件啊,软件啊,以及其他。
COM
COM对象实际就是C++类,或者说是供你调用以实现一定目标的类内的函数。每个类都可以单独而不是相互间配合才能进行工作,而且可以作为一个单独组件卸载或加载而不影响程序的运行。独立性是COM的最大特性之一。
COM的特点,让DirectX 独立于语言而向下兼容。
一般将COM对象作为接口,将其视为C++类使用,我们所必须知道的仅是通过某个特定函数或另一个COM接口来获取指向某一个COM接口的指针。通常使用CreateX()函数。获得指针后就可以该接口的功能(接口内的方法)。

注意到创建COM接口不可使用C++的关键字new,而是特定的函数,同时使用完一个接口,应该地调用接口对应的Release方法而不是delete。

这是因为每一个对象都有其的应用计数(Reference Counter),当创建对象时,为该计数初始为1,当使用该对象时进行AddRef(),递增计数,每次试图删除进行Release(),只有当引用计数为0,表明该对象正式删除,进行delete操作。

这样保证了当我们进行一次Create操作时,我们获得的是该对象指针,至于该指针是在哪里new出来的我们不在需要关注,而只需要Release,就能使该对象准确的时机被delete:

LPDIRECT3D9 d3d;
d3d = Direct3DCreate9(D3D_SDK_VERSION);    // create the Direct3D interface
d3d->Release();    // close and release Direct3D 

在D3D学习的过程我们需要的NEED:

  • Visual Studio 2010 以及以上版本
  • The DirectX SDK June 2010
  • C++基础知识
  • 开发游戏的强烈热情
WIN32基础
游戏基本流程
1 Initialize the program:初始化程序如创建窗口,初始化Direct3D
2 Start the game:启动游戏
3 Get input from the player:获取输入,是游戏与玩家的交互部分
4 Run the game logic, such as physics and AI:运行游戏物理引擎、逻辑AI等
5 Render graphics:渲染图形
6 Loop:进入游戏循环
7 Cleanup:资源的释放

WIN32窗口程序
1 注册窗口类 RegisterClassEx
2 创建窗口 CreateWindowEx
3 显示窗口 ShowWindow
4 消息循环 Loop GetMessage
以下为完整的WIN32窗口程序代码
// include the basic windows header file
#include <windows.h>

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd,
	UINT message,
	WPARAM wParam,
	LPARAM lParam);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	// the handle for the window, filled by a function
	HWND hWnd;
	// this struct holds information for the window class
	WNDCLASSEX wc;

	// clear out the window class for use
	ZeroMemory(&wc, sizeof(WNDCLASSEX));

	// fill in the struct with the needed information
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WindowProc;
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wc.lpszClassName = L"WindowClass";

	// register the window class
	RegisterClassEx(&wc);

	// create the window and use the result as the handle
	hWnd = CreateWindowEx(NULL,
		L"WindowClass",    // name of the window class
		L"First Window",   // title of the window
		WS_OVERLAPPEDWINDOW,    // window style
		300,    // x-position of the window
		300,    // y-position of the window
		500,    // width of the window
		400,    // height of the window
		NULL,    // we have no parent window, NULL
		NULL,    // we aren't using menus, NULL
		hInstance,    // application handle
		NULL);    // used with multiple windows, NULL

	// display the window on the screen
	ShowWindow(hWnd, nCmdShow);

	// enter the main loop:

	// this struct holds Windows event messages
	MSG msg;

	// wait for the next message in the queue, store the result in 'msg'
	while(GetMessage(&msg, NULL, 0, 0))
	{
		// translate keystroke messages into the right format
		TranslateMessage(&msg);

		// send the message to the WindowProc function
		DispatchMessage(&msg);
	}

	// return this part of the WM_QUIT message to Windows
	return msg.wParam;
}

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	// sort through and find what code to run for the message given
	switch(message)
	{
		// this message is read when the window is closed
	case WM_DESTROY:
		{
			// close the application entirely
			PostQuitMessage(0);
			return 0;
		} break;
	}

	// Handle any messages the switch statement didn't
	return DefWindowProc (hWnd, message, wParam, lParam);
}
游戏循环消息处理函数PeekMessage与GetMessage的区别之处:它不在等待消息,相当于对窗口消息队列消息进行检查而已,所以我们必须另外处理循环的退出情况。
while(TRUE)
{
	// Check to see if any messages are waiting in the queue
	while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	{
		// translate keystroke messages into the right format
		TranslateMessage(&msg);

		// send the message to the WindowProc function
		DispatchMessage(&msg);
	}

	// If the message is WM_QUIT, exit the while loop
	if(msg.message == WM_QUIT)
		break;

	// Run game code here
	// ...
	// ...
}

Direct3D程序

  1. 创建全局变量与函数原型
  2. 写初始化Direct3D函数,创建Direct3D Device
  3. 写渲染函数
  4. 关闭与释放Direct3D资源的函数

1 创建全局变量与函数原型

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

// include the Direct3D Library file
#pragma comment (lib, "d3d9.lib")

// global declarations
LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class

// function prototypes
void initD3D(HWND hWnd);    // sets up and initializes Direct3D
void render_frame(void);    // renders a single frame
void cleanD3D(void);    // closes Direct3D and releases memory

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

2 写初始化Direct3D函数,创建Direct3D Device

初始化Direct3D的步骤:

  • 获取IDirect3D9指针(Direct3DCreate9)
  • 检查设备性能(D3DCAPS9 -Device Capabilities)
  • 填充D3DPRESENT_PARAMETERS结构,该结构用于指定创建IDirect3DDevice9对象的特性
  • 创建IDirect3DDevice9对象,其代表了我们显示图像的物理设备
// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
	d3d = Direct3DCreate9(D3D_SDK_VERSION);    // create the Direct3D interface

	D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information

	ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use
	d3dpp.Windowed = TRUE;    // program windowed, not fullscreen
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames
	d3dpp.hDeviceWindow = hWnd;    // set the window to be used by Direct3D

	// create a device class using this information and information from the d3dpp stuct
	d3d->CreateDevice(D3DADAPTER_DEFAULT,
		D3DDEVTYPE_HAL,
		hWnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpp,
		&d3ddev);
}
3 写渲染函数
// this is the function used to render a single frame
void render_frame(void)
{
    // clear the window to a deep blue
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

    d3ddev->BeginScene();    // begins the 3D scene

    // do 3D rendering on the back buffer here

    d3ddev->EndScene();    // ends the 3D scene

    d3ddev->Present(NULL, NULL, NULL, NULL);    // displays the created frame
}
4 关闭与释放Direct3D资源的函数
// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
	d3ddev->Release();    // close and release the 3D device
	d3d->Release();    // close and release Direct3D
}
REL
网络教程:
DirectXTutorial.com
书籍:
《DIRECTX 9.0 3D 游戏开发编程基础》 Frank D.Luna 清华大学出版社
《Windows程序设计第五版》
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值