花了一天的时间,终于看懂了部分代码,不容易。
虽然有光盘,但还是全部在VS2005中手写了所有代码,书中的例子貌似大部分照搬了DirectX SDK Sample里的很多Samples,当然,个人觉得写的不错,也是逛书城后选中的三本三维开发书之一,挑的累哦,自己基础太差了,还有两本是:《游戏开发-剧本与角色创造》和《计算机图形学》(书为:精通DirectX 3D 图形动画程序设计/人民邮电出版社,ISBN:978-7-115-15971-7/TP)
全部源代码如下(部分注释是我看书后自己加的):
// 最简单的Direct3D程序
// ============================================
#include < d3d9.h >
// --------------------------------------------
// 全局变量
// --------------------------------------------
LPDIRECT3D9 g_pD3D = NULL; // Direct3D对象
// g_pD3D是Direct3D接口指针
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Direct3D设备对象
// --------------------------------------------
// Desc:初始化Direct3D
// --------------------------------------------
HRESULT InitD3D(HWND hWnd)
... {
//创建Direct3D对象,该对象用来创建Direct3D设备对象
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
//设置D3DPRESENT_PARAMETERS结构,准备创建Direct3D设备对象)
D3DPRESENT_PARAMETERS d3dpp;//创建Direct3D设备对象参数d3dpp
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed =TRUE;//窗口还是全屏幕
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;//后台缓存复制到前台后,清除后台缓存
d3dpp.BackBufferFormat =D3DFMT_UNKNOWN;//后台缓存格式和前台缓存格式相同
//创建Direct3D设备对象
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL ,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pd3dDevice)))
//参数说明,按顺序:Adapter指定显卡序号,默认显卡,指定设备类型(HAL,硬件抽象层设备),窗口指针,软件运算方式)
...{
return E_FAIL;
}
return S_OK;
}
// ----------------------------------------------
// Desc:释放创建对象
// ----------------------------------------------
VOID Cleanup()
... {
//释放Direct3D设备对象
if (g_pd3dDevice!=NULL)
g_pd3dDevice->Release();//对应COM计数器会减1
//释放Direct3D对象
if (g_pD3D!=NULL)
g_pD3D->Release();//对应COM计数器会减1
}
// ----------------------------------------------
// Desc:渲染图形
// ----------------------------------------------
VOID Render()
... {
//清空后台缓冲
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(255,0,0),1.0f,0);
//矩形数量;要清空的矩形区域,若值为NULL,则第一个参数为0;清空的内容:颜色缓冲区;清空颜色缓冲区后颜色缓冲区的值;颜色深度;模板值
if (SUCCEEDED(g_pd3dDevice->BeginScene()))
...{
//在后台缓冲区绘制图形
//结束在后台缓冲区绘制图形
g_pd3dDevice->EndScene();
}
//将在后台缓冲区绘制的图形提交到前台缓冲区显示
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
//参数说明:复制源的矩形区域指针;复制目标的矩形区域指针;当前窗口指针;最小更新区域指针
}
// -----------------------------------------------
// Desc:消息处理
// -----------------------------------------------
LRESULT WINAPI MsgProc(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam)
... {
switch(msg)
...{
case WM_DESTROY:
Cleanup();
PostQuitMessage(0);
return 0;
case WM_PAINT:
Render();
ValidateRect(hWnd,NULL);
return 0;
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
// -----------------------------------------------
// Desc:程序入口
// -----------------------------------------------
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
... {
//注册窗口类
WNDCLASSEX wc=...{sizeof(WNDCLASSEX),CS_CLASSDC, MsgProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,L"ClassName",NULL};
RegisterClassEx( &wc);
//创建窗口
HWND hWnd=CreateWindow(L"ClassName",L"最简单的Direct3D程序",WS_OVERLAPPEDWINDOW,0,0,1024,768,NULL,NULL,wc.hInstance,NULL);
//初始化Direct3D
if (SUCCEEDED(InitD3D(hWnd)))
...{
//显示主窗口
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
//进入消息循环
MSG msg;
ZeroMemory(&msg,sizeof(msg));
while(msg.message!=WM_QUIT)
...{
if(PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))//PeekMessage和GetMessage的区别
//PeekMessage过程中用来处理Render而GetMessage过门不入,不会抢系统控制权
...{
TranslateMessage(&msg);//消息转换
DispatchMessage(&msg);//消息传递给窗口过程函数
}
else
...{
Render();//渲染图形,渲染函数一般都是在程序空闲时调用的
}
}
}
UnregisterClass(L"ClassName",wc.hInstance);//参数作用:要注销的类名字符串指针;应用程序句柄
return 0;
}
// 以上代码定义了一个具有最大,最小化按钮可调整大小的叠置式窗口。
// 关于LRESULT
// LRESULT Signed result of message processing.
// This type is declared in WinDef.h as follows:
// typedef LONG_PTR LRESULT;
// 关于LONG_PTR
// LONG_PTR Signed long type for pointer precision. Use when casting a pointer to a long to perform pointer arithmetic.
// This type is declared in BaseTsd.h as follows:
// #if defined(_WIN64)
// typedef __int64 LONG_PTR;
// #else
// typedef long LONG_PTR;
// #endif
通过本章(第二章:Direct3D程序设计基础)的学习:
一、了解了Direct3D学习需要的基础知识
(1).C++,学好C++,走便天下都不怕,更何况在DirectX中对C++更是要求很高,微软很多D3D SDK中的程序都是用C++写的。当然,有两种模式,一种是使用COM模式,另一种是.NET模式,可以使用C#和VB。但是,学好C++依然是一个很重要的前提。
(2).Win32 API基础
包括注册窗口类,消息循环,结束Windows程序等,还包括动画的渲染等,都离不开Win32 API。VB中有API么?呵呵,不怕,不怕。当然,VB中的API和C++中的API貌似区别还是很大。
(3).组件对象模型基础
本书是用COM接口方式提供的,希望能找到C#或VB.NET结合D3D SDK的书,当然,C++没什么不好!
(4).数学基础
矩阵变换,向量,四元数运算等。《计算机图形学》中有介绍,不过,蛮难的。要好好学习。基本的概念应该理解,这个是个基础的基础。
(5).计算机图形学基础
上面已经说到一些。三维变换,照明,光栅化等操作。
二、Direct3D体系结构
1.Direct3D程序开发层次
(1).硬件抽象层(HAL)
(2).硬件模拟层(HEL,DX8后已经不存在了)与软件参考层,现今的游戏要么运行于HAL,要么运行于(REF Layer,Reference Layer)软件参考层上
(3).D3D和GDI的关系(并列)
2.Direct3D对象/Direct3D设备对象的概念和创建
3.Direct3D程序的基本结构
(1).创建一个Windows窗口
(2).初始化Direct3D,包括创建Direct3D对象,Direct3D设备对象以及要渲染的图形对象
(3).消息循环
(4).清除初始化时创建的所有COM对象,退出程序
以上细节及代码细节下次日志分析