天行健 君子当自强而不息

Direct3D程序设计基础(2)

创建窗口

Direct3D是基于Microsoft Windows的图形开发接口,它的使用必须建立在Windows窗口的基础上,这就需要创建一个窗口,而创建窗口首先需要注册一个窗口类。示例程序中注册窗口类并根据窗口类创建窗口的代码如下:

	WNDCLASSEX wc;
	wc.cbSize			= sizeof(WNDCLASSEX);
wc.style = CS_CLASSDC;
wc.lpfnWndProc = WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = inst;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = CLASS_NAME;
wc.hIconSm = NULL;
	if(! RegisterClassEx(&wc))
return -1;
	HWND hwnd = CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200, 100, 600, 500,
NULL, NULL, wc.hInstance, NULL);
	if(hwnd == NULL)
return -1;

 

初始化Direct3D

创建了可供绘制图形的窗口后,在使用Direct3D渲染图形前,还需要进行与Direct3D相关的初始化操作,主要包括创建Direct3D对象并获取其接口指针,通过Direct3D对象创建Direct3D设备对象。

bool init_d3d(HWND hwnd)
{
g_d3d = Direct3DCreate9(D3D_SDK_VERSION);
	if(g_d3d == NULL)
return false;
	D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed			= TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_device)))
{
return false;
}
	return true;
}

Direct3D设备(Direct3D Device)定义了Direct3D的所有绘图操作,绝大多数Direct3D操作都是通过Direct3D设备接口进行的。比较而言,Direct3D对象更像是DirectX显示信息的说明,而Direct3D设备对象则是3D功能的具体实现。

要创建Direct3D设备,可调用IDirect3D9::CreateDevice()函数。

Creates a device to represent the display adapter.

HRESULT CreateDevice(
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS * pPresentationParameters,
IDirect3DDevice9 ** ppReturnedDeviceInterface
);

Parameters

Adapter
[in] Ordinal number that denotes the display adapter. D3DADAPTER_DEFAULT is always the primary display adapter.
DeviceType
[in] Member of the D3DDEVTYPE enumerated type that denotes the desired device type. If the desired device type is not available, the method will fail.
hFocusWindow
[in] The focus window alerts Direct3D when an application switches from foreground mode to background mode. See Remarks.
  • For full-screen mode, the window specified must be a top-level window.
  • For windowed mode, this parameter may be NULL only if the hDeviceWindow member of pPresentationParameters is set to a valid, non-NULL value.
BehaviorFlags
[in] Combination of one or more options that control device creation. For more information, see D3DCREATE.
pPresentationParameters

Pointer to a D3DPRESENT_PARAMETERS structure, describing the presentation parameters for the device to be created. If BehaviorFlags specifies D3DCREATE_ADAPTERGROUP_DEVICE, pPresentationParameters is an array. Regardless of the number of heads that exist, only one depth/stencil surface is automatically created.

[in, out] For Windows 2000 and Windows XP, the full-screen device display refresh rate is set in the following order:
  1. User-specified nonzero ForcedRefreshRate registry key, if supported by the device.
  2. Application-specified nonzero refresh rate value in the presentation parameter.
  3. Refresh rate of the latest desktop mode, if supported by the device.
  4. 75 hertz if supported by the device.
  5. 60 hertz if supported by the device.
  6. Device default.

An unsupported refresh rate will default to the closest supported refresh rate below it. For example, if the application specifies 63 hertz, 60 hertz will be used. There are no supported refresh rates below 57 hertz.

pPresentationParameters is both an input and an output parameter. Calling this method may change several members including:

  • If BackBufferCount, BackBufferWidth, and BackBufferHeight are 0 before the method is called, they will be changed when the method returns.
  • If BackBufferFormat equals D3DFMT_UNKNOWN before the method is called, it will be changed when the method returns.

 

ppReturnedDeviceInterface
[out, retval] Address of a pointer to the returned IDirect3DDevice9 interface, which represents the created device.

Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be one of the following: D3DERR_DEVICELOST, D3DERR_INVALIDCALL, D3DERR_NOTAVAILABLE, D3DERR_OUTOFVIDEOMEMORY.

Remarks

This method returns a fully working device interface, set to the required display mode (or windowed), and allocated with the appropriate back buffers. To begin rendering, the application needs only to create and set a depth buffer (assuming EnableAutoDepthStencil is FALSE in D3DPRESENT_PARAMETERS).

When you create a Direct3D device, you supply two different window parameters: a focus window (hFocusWindow) and a device window (the hDeviceWindow in D3DPRESENT_PARAMETERS). The purpose of each window is:

  • The focus window alerts Direct3D when an application switches from foreground mode to background mode (via Alt-Tab, a mouse click, or some other method). A single focus window is shared by each device created by an application.
  • The device window determines the location and size of the back buffer on screen. This is used by Direct3D when the back buffer contents are copied to the front buffer during IDirect3DDevice9::Present.

This method should not be run during the handling of WM_CREATE. An application should never pass a window handle to Direct3D while handling WM_CREATE. Any call to create, release, or reset the device must be done using the same thread as the window procedure of the focus window.

Note that D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, and D3DCREATE_SOFTWARE_VERTEXPROCESSING are mutually exclusive flags, and at least one of these vertex processing flags must be specified when calling this method.

Back buffers created as part of the device are only lockable if D3DPRESENTFLAG_LOCKABLE_BACKBUFFER is specified in the presentation parameters. (Multisampled back buffers and depth surfaces are never lockable.)

The methods IDirect3DDevice9::Reset, IUnknown, and IDirect3DDevice9::TestCooperativeLevel must be called from the same thread that used this method to create a device.

D3DFMT_UNKNOWN can be specified for the windowed mode back buffer format when calling IDirect3D9::CreateDevice, IDirect3DDevice9::Reset, and IDirect3DDevice9::CreateAdditionalSwapChain. This means the application does not have to query the current desktop format before calling IDirect3D9::CreateDevice for windowed mode. For full-screen mode, the back buffer format must be specified.

If you attempt to create a device on a 0x0 sized window, IDirect3D9::CreateDevice will fail.

 

消息循环

在Direct3D中,渲染图形通常是在消息循环中进行的:

		MSG msg;
ZeroMemory(&msg, sizeof(msg));
		while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
render();
}
}

这段代码的主要部分由PeekMessage()、TranslateMessage()和DispatchMessage()构成,它们是Windows程序标准的消息循环处理代码。当应用程序消息队列中出现一条消息时,PeekMessage()返回布尔值TRUE,执行TranslateMessage()进行消息转换,然后由DispatchMessage()把消息传递给窗口过程函数。

特别需要注意的是,在消息循环中使用的是PeekMessage()函数,而不是GetMessage()函数。函数PeekMessage()和GetMessage()的功能大体相同,作用都是从消息队列中取一条消息出来,唯一不同的是,每当GetMessage()发现消息队列中没有消息时,过门不入,而PeekMessage()发现消息队列中没有消息时,会取回系统控制权,让程序在此停留一段时间,应用程序就是在这时候处理render()函数。也就是说,渲染函数render()都是在程序运行时的空闲时间调用的。

注意理解PeekMessage()和GetMessage()运行机制的区别,这对理解Direct3D程序中如何实现动画是很关键的。


posted on 2008-04-29 13:55 lovedday 阅读(1258) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论