1
#include
<
D3DX9.h
>
2
#include
<
string
>
3
typedef std::
string
String;
4
#define
SAFE_RELEASE(o) {if(o){o->Release();o = 0;}}
5
6
7
LPDIRECT3D9 g_pD3D
=
0
;
//
D3D Driver
8
LPDIRECT3DDEVICE9 g_pd3dDevice
=
0
;
//
D3D 设备
9
D3DCAPS9 g_Caps
=
{(D3DDEVTYPE)
0
}
;
//
D3D 的帽子
10
LPDIRECT3DVERTEXBUFFER9 g_pVB
=
0
;
//
顶点缓冲区
11
LPDIRECT3DINDEXBUFFER9 g_pIB
=
0
;
//
索引缓冲区
12
13
//
顶点定义
14
#define
D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
15
struct
CUSTOMVERTEX
16
{
17
D3DXVECTOR3 position;
18
D3DCOLOR color;
19
}
;
20
21
//
错误记录
22
void
D3DErr(String strMsg)
23
{
24
MessageBox(
0
, strMsg.c_str() ,
"
错误
"
, MB_OK);
25
}
26
27
//
初始化顶点缓冲区
28
HRESULT InitVB()
29
{
30
//
创建顶点缓冲区
31
if
(FAILED(g_pd3dDevice
->
CreateVertexBuffer(
6
*
sizeof
(CUSTOMVERTEX) ,
0
, D3DFVF_CUSTOMVERTEX , D3DPOOL_DEFAULT ,
&
g_pVB ,
0
)))
32
return
E_FAIL;
33
34
CUSTOMVERTEX
*
pVertecies;
35
//
锁定缓冲区
36
if
(SUCCEEDED(g_pVB
->
Lock(
0
,
6
*
sizeof
(CUSTOMVERTEX) , (
void
**
)
&
pVertecies ,
0
)))
37
{
38
pVertecies[
0
].position
=
D3DXVECTOR3(
0
,
0
,
0
);
39
pVertecies[
1
].position
=
D3DXVECTOR3(
0
,
1
,
0
);
40
pVertecies[
2
].position
=
D3DXVECTOR3(
1
,
0
,
0
);
41
pVertecies[
3
].position
=
D3DXVECTOR3(
1
,
0
,
0
);
42
pVertecies[
4
].position
=
D3DXVECTOR3(
1
,
1
,
0
);
43
pVertecies[
5
].position
=
D3DXVECTOR3(
0
,
1
,
0
);
44
45
46
pVertecies[
0
].color
=
D3DCOLOR_XRGB(
255
,
0
,
0
);
47
pVertecies[
1
].color
=
D3DCOLOR_XRGB(
0
,
255
,
0
);
48
pVertecies[
2
].color
=
D3DCOLOR_XRGB(
0
,
0
,
255
);
49
pVertecies[
3
].color
=
D3DCOLOR_XRGB(
0
,
0
,
255
);
50
pVertecies[
4
].color
=
D3DCOLOR_XRGB(
255
,
255
,
255
);
51
pVertecies[
5
].color
=
D3DCOLOR_XRGB(
0
,
255
,
0
);
52
53
g_pVB
->
Unlock();
54
}
55
else
56
{
57
return
E_FAIL;
58
}
59
return
S_OK;
60
}
61
62
63
//
初始化索引缓冲区
64
HRESULT InitIB()
65
{
66
//
创建顶点缓冲区
67
if
(FAILED(g_pd3dDevice
->
CreateIndexBuffer(
6
*
sizeof
(WORD) ,
0
, D3DFMT_INDEX16 , D3DPOOL_DEFAULT ,
&
g_pIB ,
0
)))
68
return
E_FAIL;
69
70
WORD
*
pIndices;
71
//
锁定缓冲区
72
if
(SUCCEEDED(g_pIB
->
Lock(
0
,
6
*
sizeof
(WORD) , (
void
**
)
&
pIndices ,
0
)))
73
{
74
pIndices[
0
]
=
0
;
75
pIndices[
1
]
=
1
;
76
pIndices[
2
]
=
2
;
77
pIndices[
3
]
=
2
;
78
pIndices[
4
]
=
3
;
79
pIndices[
5
]
=
1
;
80
g_pIB
->
Unlock();
81
}
82
else
83
{
84
return
E_FAIL;
85
}
86
return
S_OK;
87
}
88
89
//
初始化模型
90
HRESULT InitGeometry()
91
{
92
//
创建顶点缓冲区
93
if
(FAILED(InitVB()))
94
return
E_FAIL;
95
//
创建索引缓冲区
96
if
(FAILED(InitIB()))
97
return
E_FAIL;
98
return
S_OK;
99
}
100
101
//
设置矩阵变换
102
void
SetTransform()
103
{
104
105
//
世界变换
106
D3DXMATRIX matWorld , matT1 , matT2 , matR;
107
D3DXMatrixIdentity(
&
matWorld);
108
DWORD dwTime
=
timeGetTime();
109
//
角度
110
float
fAngle
=
2
*
D3DX_PI
*
(dwTime
%
3000
)
/
3000.0f
;
111
112
//
平移到原点
113
D3DXMatrixTranslation(
&
matT1 ,
-
0.5
,
-
1
,
0
);
114
//
Z旋转
115
D3DXMatrixRotationZ(
&
matR , sin(fAngle));
116
//
移动到原来的位置
117
D3DXMatrixTranslation(
&
matT2 ,
0.5
/**/
/*
- 3 * (dwTime % 5000) / 5000.0f
*/
,
1
,
0
);
118
//
平移到原点再旋转
119
matWorld
=
matT1
*
matR;
120
//
平移回原来的位置
121
matWorld
*=
matT2;
122
123
/**/
/*
124
// 放大缩小
125
D3DXMatrixScaling(&matWorld , abs(sin(2 * D3DX_PI * (dwTime % 3000) / 3000.0f)) , abs(sin(2 * D3DX_PI * (dwTime % 3000) / 3000.0f)) , 0);
126
// 设置缩放点
127
matWorld._41 = (1.0f - matWorld._11) * 0.5; // x
128
matWorld._42 = (1.0f - matWorld._22) * 0.5; // y
129
matWorld._43 = (1.0f - matWorld._33) * 1.0; // z
130
*/
131
132
//
设置世界矩阵
133
g_pd3dDevice
->
SetTransform(D3DTS_WORLD ,
&
matWorld);
134
//
视口变换
135
D3DXMATRIX matView;
136
D3DXMatrixLookAtLH(
&
matView ,
&
D3DXVECTOR3(
0
,
0
,
-
5
)
137
,
&
D3DXVECTOR3(
0
,
0
,
10
)
138
,
&
D3DXVECTOR3(
0
,
1
,
0
));
139
g_pd3dDevice
->
SetTransform(D3DTS_VIEW ,
&
matView);
140
141
//
投影变换
142
D3DXMATRIX matProj;
143
D3DXMatrixPerspectiveFovLH(
&
matProj , D3DX_PI
/
4
,
512
/
512
,
0
,
100
);
144
g_pd3dDevice
->
SetTransform(D3DTS_PROJECTION ,
&
matProj);
145
146
//
设置视口
147
D3DVIEWPORT9 vp;
148
vp.X
=
0
;
149
vp.Y
=
0
;
150
vp.Width
=
512
;
151
vp.Height
=
512
;
152
vp.MinZ
=
0
;
153
vp.MaxZ
=
1
;
154
g_pd3dDevice
->
SetViewport(
&
vp);
155
}
156
157
//
渲染场景
158
void
Render()
159
{
160
if
(g_pd3dDevice)
161
{
162
//
清空场景
163
g_pd3dDevice
->
Clear(
0
,
0
, D3DCLEAR_TARGET , D3DCOLOR_XRGB(
0
,
0
,
255
) ,
1
,
0
);
164
//
开始渲染
165
if
(SUCCEEDED(g_pd3dDevice
->
BeginScene()))
166
{
167
SetTransform();
168
g_pd3dDevice
->
SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
169
g_pd3dDevice
->
SetRenderState(D3DRS_LIGHTING , FALSE);
170
g_pd3dDevice
->
SetStreamSource(
0
, g_pVB ,
0
,
sizeof
(CUSTOMVERTEX));
171
//
g_pd3dDevice->SetIndices(g_pIB);
172
g_pd3dDevice
->
SetFVF(D3DFVF_CUSTOMVERTEX);
173
g_pd3dDevice
->
DrawPrimitive(D3DPT_TRIANGLELIST ,
0
,
2
);
174
g_pd3dDevice
->
EndScene();
175
}
176
//
显示
177
g_pd3dDevice
->
Present(
0
,
0
,
0
,
0
);
178
}
179
}
180
181
//
初始化 D3D 设备
182
HRESULT InitD3D(HWND hWnd)
183
{
184
//
创建 D3D Driver
185
if
(NULL
==
(g_pD3D
=
Direct3DCreate9(D3D_SDK_VERSION)))
186
{
187
D3DErr(
"
无法创建Direct3D9设备
"
);
188
return
E_FAIL;
189
}
190
//
获取当前显示模式
191
D3DDISPLAYMODE d3ddm;
192
if
(FAILED(g_pD3D
->
GetAdapterDisplayMode(D3DADAPTER_DEFAULT ,
&
d3ddm)))
193
{
194
D3DErr(
"
无法获取D3D显示器模式
"
);
195
return
E_FAIL;
196
}
197
198
//
获取窗口的大小
199
RECT rect;
200
GetClientRect(hWnd ,
&
rect);
201
202
//
填充参数
203
D3DPRESENT_PARAMETERS d3dpp;
204
memset(
&
d3dpp ,
0
,
sizeof
(d3dpp));
205
d3dpp.BackBufferFormat
=
d3ddm.Format;
206
d3dpp.BackBufferWidth
=
rect.right
-
rect.left;
207
d3dpp.BackBufferHeight
=
rect.bottom
-
rect.top;
208
d3dpp.SwapEffect
=
D3DSWAPEFFECT_DISCARD;
209
d3dpp.Windowed
=
true
;
210
211
//
获取帽子
212
if
(FAILED(g_pD3D
->
GetDeviceCaps(D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL ,
&
g_Caps)))
213
{
214
D3DErr(
"
获取D3D 帽子时发生错误
"
);
215
return
E_FAIL;
216
}
217
218
//
创建D3D设备
219
if
(FAILED(g_pD3D
->
CreateDevice(D3DADAPTER_DEFAULT
220
, D3DDEVTYPE_HAL
221
, hWnd
222
//
检查是否支持硬件顶点处理
223
, g_Caps.DevCaps
&
D3DDEVCAPS_HWTRANSFORMANDLIGHT
?
D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING
224
,
&
d3dpp
225
,
&
g_pd3dDevice
226
)
227
))
228
{
229
D3DErr(
"
创建D3D设备时发生错误
"
);
230
return
E_FAIL;
231
}
232
233
if
(FAILED(InitGeometry()))
234
return
E_FAIL;
235
return
S_OK;
236
}
237
238
//
清空所有占用的资源
239
void
CleanUp()
240
{
241
SAFE_RELEASE(g_pIB);
242
SAFE_RELEASE(g_pVB);
243
SAFE_RELEASE(g_pd3dDevice);
244
SAFE_RELEASE(g_pD3D);
245
}
246
247
248
//
消息处理
249
LRESULT WINAPI MsgProc(HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
250
{
251
switch
(message)
252
{
253
case
WM_DESTROY:
254
CleanUp();
255
PostQuitMessage(
0
);
256
break
;
257
}
258
return
::DefWindowProc(hWnd, message , wParam , lParam);
259
}
260
261
//
Windows 入口
262
int
WINAPI WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN
int
nShowCmd )
263
{
264
WNDCLASS wndClass;
265
memset(
&
wndClass ,
0
,
sizeof
(wndClass));
266
wndClass.hInstance
=
hInstance;
267
wndClass.lpszClassName
=
"
Tutorial02
"
;
268
wndClass.lpfnWndProc
=
MsgProc;
269
RegisterClass(
&
wndClass);
270
271
//
创建窗口
272
HWND hWnd
=
CreateWindow(
"
Tutorial02
"
,
"
Tutorial02 Transform
"
273
, WS_OVERLAPPEDWINDOW ,
0
,
0
,
512
,
512
, GetDesktopWindow()
274
,
0
, wndClass.hInstance ,
0
);
275
//
显示窗口
276
ShowWindow(hWnd , SW_SHOWDEFAULT);
277
UpdateWindow(hWnd);
278
279
//
初始化 D3D 设备
280
if
(SUCCEEDED(InitD3D(hWnd)))
281
{
282
//
消息处理循环
283
MSG msg;
284
memset(
&
msg ,
0
,
sizeof
(msg));
285
while
(msg.message
!=
WM_QUIT)
286
{
287
if
(PeekMessage(
&
msg ,
0
,
0
,
0
, PM_REMOVE))
288
{
289
TranslateMessage(
&
msg);
290
DispatchMessage(
&
msg);
291
}
292
else
293
{
294
Render();
295
}
296
}
297
}
298
//
清空场景
299
CleanUp();
300
301
UnregisterClass(
"
Tutorial02
"
, wndClass.hInstance);
302
303
return
0
;
304
}
|