所用编程工具vs2010
DirectX SDK版本Microsoft DirectX SDK (June 2010)(下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=6812)
首先,打开编辑器,如下图,创建一个win32的空项目,起名为sample。
创建项目完成后,先不要着急创建文件,让我们先对环境进行一下设置,这是至关重要的,很多情况下出现的错误就是因为环境配置错误造成的,特别是对于初学者。
如图,选择“项目”->“属性”,打开属性配置窗口。
再打开的属性配置窗口中,选择“VC++目录”选项,然后将DirectX SDK的“包含目录”(Include)以及“库目录”(Lib)添加进去。然后在“链接器”->“输入”选项的“附加依赖项”中添加d3d9.lib,这样我们的基本属性就配置完成了,点击“确定”退出属性配置窗口。
创建一个名为Sample的.cpp文件,添加头文件d3d9.h。
声明LPDIRECT3D9与LPDIRECT3DDEVICE9变量:
1 2 3 4 |
LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pDevice = NULL; |
然后添加InitD3D、Cleanup、Render方法。
首先,说一下InitD3D方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
HRESULT InitD3D(HWND hwnd) { if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION))) { return E_FAIL; } D3DPRESENT_PARAMETERS d3dpparams; ZeroMemory(&d3dpparams, sizeof(d3dpparams)); d3dpparams.Windowed = true; d3dpparams.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpparams.BackBufferFormat = D3DFMT_UNKNOWN; if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpparams, &g_pDevice))) { return E_FAIL; } return S_OK; } |
Hwnd为窗口句柄,在此为当前窗口,Direct3Dcreate方法创建Direct3D对象,其中只有一个参数,D3D_SDK_VERSION,当前SDK版本。
D3DPRESENT_PARAMETERS结构体定义了Direct3D设备的信息,在对相关参数进行赋值之前,先将所有参数归零处理,不然,有可能造成创建Direct3D设备失败。D3DPRESENT_PARAMETERS中信息有很多,在此我们只是用其中三个:Windowed = true,表示已窗口模式显示;SwapEffect指定系统如何将后台缓冲区的内容提交到前台,SwapEffect = D3DSWAPEFFECT_DISCARD,表示后台缓冲区的内容提交到前台后,清除后台缓冲区内容;BackBufferFormat指后台缓冲区像素格式,BackBufferFormat = D3DFMT_UNKNOWN,表示后台缓冲区像素格式和当前使用的显卡的像素格式是相同的。
Direct3D对象的CreateDevice方法,创建了Direct3D设备,第一个参数表示使用哪一块显卡,一般情况下为D3DADAPTER_DEFAULT,使用当前显卡;第二个参数表示Direct3D的设备类型,在此我们将其设置为硬件抽象层D3DDEVTYPE_HAL;第三个参数就是方法传入的窗口句柄;第四个参数为Direct3D设备的行为标志,在此选择D3DCREATE_SOFTWARE_VERTEXPROCESSING,表示由Direct3D软件进行顶点运算;第五和第六个参数分别为指向d3dpparams的指针和Direct3D设备指针的地址。
一切创建成功后,方法返回S_OK。
然后再说一下Cleanup()方法,
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void Cleanup() { if (NULL != g_pDevice) { g_pDevice->Release(); } if (NULL != g_pD3D) { g_pD3D->Release(); } } |
此方法主要是释放Direct3D资源,因为不管Direct3D对象还是Direct3D设备对象都是COM对象,所以,在此必须调用Release方法,使COM对象的引用计数-1。并且,必须先释放Direct3D设备对象,再释放Direct3D对象(因为Direct3D设备对象是通过Direct3D对象创建的)。
Render()方法,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
void Render() { if (NULL == g_pDevice) { return; } g_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(30, 60, 90), 1.0f, 0); if (SUCCEEDED(g_pDevice->BeginScene())) { g_pDevice->EndScene(); } g_pDevice->Present(NULL, NULL, NULL, NULL); } |
从Render()方法中我们可以看出,Direct3D设备对象是一切Direct 3D图形绘制的基础。
首先Clear方法,作用是清空后台缓冲区,其中参数分别为:count,表示pRect参数的矩形的数量,如果pRect为NULL,则count必须为0,如果pRect是有效的指针,则count必须不为0;pRect存储着需要清空的矩形区域;Flags参数表示要清空的缓冲区,此处设置为D3DCLEAR_TARGET,表示清空颜色缓冲区;Color参数表示以什么颜色填充清空后的缓冲区的每个像素的颜色;Z参数表示清空深度缓冲区(ZBUFFER)后每个像素的深度值;Stencil表示清空模板缓冲区后每个像素的模板值。
BeginScene()方法,必须在进行图形渲染之前调用此方法,而在图形渲染结束后,必须调用EndScene()方法,并且,两者必须成对出现。
Render的最后一个方法Present方法,是将在后台渲染的东西翻转到前台,这样就完成了图形渲染的过程。其中Present的第一个参数,表示后台复制源矩形指针,一般为NULL,表示整个后台区域;第二个参数表示前台目标矩形指针,一般为NULL,表示整个前台区域;第三个参数表示当前渲染图形的窗口句柄,一般情况为NULL;第四个参数为最小更新区域指针,一般为NULL。并且,在InitD3D方法中的D3DPRESENT_PARAMETERS结构的SwapEffect参数的值不是D3DSWAPEFFECT_COPY的时候,Present的第一、二、四个参数必须为NULL。
最后说一下消息循环,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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,而不使用GetMessage方法,因为GetMessage会在此等待,直至有消息到来,PeekMessage在没有消息时会直接返回,这样,我们的Render方法就在系统空闲之时得以运行(着对于我们的游戏至关重要,谨记)。
当一切搞定之后,Ctrl+F5运行程序,我们将看到,
至此,我们的第一个Direct3D项目就结束了,其中讲解了很多东西,需要仔细研究。
希望此文能对刚刚学习Direct3D编程的朋友有所帮助,当然,如有不足之处还请指出,我们共同学习进步。
ZXGoto祝大家编程愉快!
(代码地址:http://115.com/file/e767bumh#sample.rar)
- 本文固定链接: https://www.xuanyusong.com/archives/802
- 转载请注明: ZXGoto 于 雨松MOMO程序研究院 发表
像素模板值是什么?
好熟悉的工程 哈哈。。
调用Cleanup的时候程序为什么会崩溃。
支持~~~~~小小
感谢支持,大家一起学习
嗯,很有用
支持