??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_NORMAL?)
?15
struct
?CUSTOMVERTEX
?16
{
?17
????D3DXVECTOR3?position;
?18
????D3DXVECTOR3?normal;
?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(
50
?
*
?
2
?
*
?
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
?,?
0
?,?(
void
**
)
&
pVertecies?,?
0
)))
?37
????
{
?38
????????
for
(
int
?i?
=
?
0
?;?i?
<
?
100
?;?i?
+=
?
2
)
?39
????????
{
?40
????????????
float
?theta?
=
?
2
?
*
?D3DX_PI?
*
?i?
/
?(
50
?
-
?
1
);
?41
????????????
//
?根據圓的方程?x?=?x'?+?r?*?sin(θ)
?42
????????????
//
??????????????y?=?y'?+?r?*?cos(θ)
?43
????????????
//
?求解圓
?44
????????????pVertecies[i].position?
=
?D3DXVECTOR3(sinf(theta)?,?
1
?,?cosf(theta));
?45
????????????pVertecies[i].normal?
=
?D3DXVECTOR3(sinf(theta)?,?
0
?,?cosf(theta));
?46
?47
????????????pVertecies[i?
+
?
1
].position?
=
?D3DXVECTOR3(sinf(theta)?,?
-
1
?,?cosf(theta));
?48
????????????pVertecies[i?
+
?
1
].normal?
=
?D3DXVECTOR3(sinf(theta)?,?
0
?,?cosf(theta));
?49
?50
????????}
?51
????????g_pVB
->
Unlock();
?52
????}
?53
????
else
?54
????
{
?55
????????
return
?E_FAIL;
?56
????}
?57
????
return
?S_OK;
?58
}
?59
?60
//
?初始化模型
?61
HRESULT?InitGeometry()
?62
{
?63
????
//
?創建頂點緩沖區
?64
????
if
(FAILED(InitVB()))
?65
????????
return
?E_FAIL;
?66
????
return
?S_OK;
?67
}
?68
?69
//
?設置矩陣變換
?70
void
?SetTransform()
?71
{
?72
?73
????
//
?世界變換
?74
????D3DXMATRIX?matWorld?,?matT1?,?matT2?,?matR;
?75
????D3DXMatrixIdentity(
&
matWorld);
?76
????DWORD?dwTime?
=
?timeGetTime();
?77
????
//
?角度
?78
????
float
?fAngle?
=
?
2
?
*
?D3DX_PI?
*
?(dwTime?
%
?
3000
)?
/
?
3000.0f
;
?79
?80
????
//
?平移到原點
?81
????D3DXMatrixTranslation(
&
matT1?,?
-
0.5
?,?
-
1
,?
0
);
?82
????
//
?Z旋轉
?83
????D3DXMatrixRotationZ(
&
matR?,?sin(fAngle));
?84
????
//
?移動到原來的位置
?85
????D3DXMatrixTranslation(
&
matT2?,?
0.5
/**/
/*
?-?3?*?(dwTime?%?5000)?/?5000.0f
*/
?,?
1
,?
0
);
?86
????
//
?平移到原點再旋轉
?87
????matWorld?
=
?matT1?
*
?matR;
?88
????
//
?平移回原來的位置
?89
????matWorld?
*=
?matT2;
?90
?91
????
?92
????
//
?放大縮小
?93
????D3DXMatrixScaling(
&
matWorld?,??abs(sin(
2
?
*
?D3DX_PI?
*
?(dwTime?
%
?
3000
)?
/
?
3000.0f
))?,?abs(sin(
2
?
*
?D3DX_PI?
*
?(dwTime?
%
?
3000
)?
/
?
3000.0f
))?,?abs(sin(
2
?
*
?D3DX_PI?
*
?(dwTime?
%
?
3000
)?
/
?
3000.0f
)));
?94
????
//
?設置縮放點
?95
????matWorld._41?
=
?(
1.0f
?
-
?matWorld._11)?
*
?
0.5
;????????
//
?x
?96
????matWorld._42?
=
?(
1.0f
?
-
?matWorld._22)?
*
?
0.5
;????????
//
?y
?97
????matWorld._43?
=
?(
1.0f
?
-
?matWorld._33)?
*
?
0
;????????
//
?z
?98
????
?99
100
????
//
?設置世界矩陣
101
????g_pd3dDevice
->
SetTransform(D3DTS_WORLD?,?
&
matWorld);
102
????
//
?Set?up?our?view?matrix.?A?view?matrix?can?be?defined?given?an?eye?point,
103
????
//
?a?point?to?lookat,?and?a?direction?for?which?way?is?up.?Here,?we?set?the
104
????
//
?eye?five?units?back?along?the?z-axis?and?up?three?units,?look?at?the
105
????
//
?origin,?and?define?"up"?to?be?in?the?y-direction.
106
????
//
?視口變換
107
????D3DXMATRIX?matView;
108
????D3DXMatrixLookAtLH(
&
matView?,?
&
D3DXVECTOR3(
0
?,?
3
?,?
-
5
)
109
????????,?
&
D3DXVECTOR3(
0
?,?
0
?,?
0
)?
110
????????,?
&
D3DXVECTOR3(
0
?,?
1
?,?
0
));
111
????g_pd3dDevice
->
SetTransform(D3DTS_VIEW?,?
&
matView);
112
????
//
?For?the?projection?matrix,?we?set?up?a?perspective?transform?(which
113
????
//
?transforms?geometry?from?3D?view?space?to?2D?viewport?space,?with
114
????
//
?a?perspective?divide?making?objects?smaller?in?the?distance).?To?build
115
????
//
?a?perpsective?transform,?we?need?the?field?of?view?(1/4?pi?is?common),
116
????
//
?the?aspect?ratio,?and?the?near?and?far?clipping?planes?(which?define?at
117
????
//
?what?distances?geometry?should?be?no?longer?be?rendered).
118
????D3DXMATRIXA16?matProj;
119
????D3DXMatrixPerspectiveFovLH(?
&
matProj,?D3DX_PI
/
4
,?
1.0f
,?
1.0f
,?
100.0f
?);
120
????g_pd3dDevice
->
SetTransform(?D3DTS_PROJECTION,?
&
matProj?);
121
}
122
123
//
?設置燈光
124
void
?SetupLight()
125
{
126
????
//
?Set?up?a?material.?The?material?here?just?has?the?diffuse?and?ambient
127
????
//
?colors?set?to?yellow.?Note?that?only?one?material?can?be?used?at?a?time.
128
????
//
set?up?lights
129
????D3DXVECTOR3?vecDir;
130
????
//
?創建一個平行光
131
????D3DLIGHT9?light;
132
????ZeroMemory(?
&
light,?
sizeof
(D3DLIGHT9)?);
133
????light.Type???????
=
?D3DLIGHT_DIRECTIONAL;????
//
?平行光
134
????light.Diffuse.r??
=
?
0.0f
;
135
????light.Diffuse.g??
=
?
1.0f
;????
//
?紅色
136
????light.Diffuse.b??
=
?
0.0f
;
137
????vecDir?
=
?D3DXVECTOR3(
10
,
10
,
-
10
);????
//
?方向是從0,0,0指向10,10,-10
138
139
????
//
?正規化向量,就是說把向量長度正規化成1,方向不變!好處是光照運算時的誤差會降到最小(純屬我的理解,不知道正確與否)
140
????D3DXVec3Normalize(?(D3DXVECTOR3
*
)
&
light.Direction,?
&
vecDir?);
141
????
//
?設置0號光照為此燈光參數
142
????g_pd3dDevice
->
SetLight(?
0
,?
&
light?);
143
????
144
????
//
?開啟0號光照
145
????g_pd3dDevice
->
LightEnable(?
0
,?TRUE?);
146
????
//
?開啟光照系統
147
????g_pd3dDevice
->
SetRenderState(?D3DRS_LIGHTING,?TRUE?);
148
149
????D3DXVECTOR3??vecPos2;
150
????
//
?一個點光源
151
????D3DLIGHT9?light2;
152
????ZeroMemory(?
&
light2,?
sizeof
(D3DLIGHT9)?);
153
????light2.Type???????
=
?D3DLIGHT_POINT;????
//
?點光源
154
????light2.Diffuse.r??
=
?
0.9f
;????????
//
?紅色
155
????light2.Diffuse.g??
=
?
0.0f
;
156
????light2.Diffuse.b??
=
?
0.0f
;
157
158
????
//
?位置,隨著時間的推移,圍繞Y軸周圍的圓圈旋轉,根據圓的方程來建立的sinf和cosf函數
159
????light2.Position?
=
?D3DXVECTOR3(
10
*
sinf(timeGetTime()
/
350.0f
)?,
160
????????
10
,
161
????????
10
*
cosf(timeGetTime()
/
350.0f
)?);
162
163
????light2.Range???????
=
?
15
;
164
????light2.Attenuation0?
=
?
1.0f
;
165
????g_pd3dDevice
->
SetLight(?
1
,?
&
light2?);
166
????g_pd3dDevice
->
LightEnable(?
1
,?TRUE?);
167
168
????
//
?開啟光照系統(純屬多余!開啟一次就行了!)
169
????g_pd3dDevice
->
SetRenderState(?D3DRS_LIGHTING,?TRUE?);
170
171
????
//
?最后,開啟環境光
172
????g_pd3dDevice
->
SetRenderState(?D3DRS_AMBIENT,?
0x00202020
?);
173
174
????D3DMATERIAL9?mtrl;
175
????ZeroMemory(?
&
mtrl,?
sizeof
(D3DMATERIAL9)?);
176
????mtrl.Diffuse.r?
=
?mtrl.Ambient.r?
=
?
1.0f
;
177
????mtrl.Diffuse.g?
=
?mtrl.Ambient.g?
=
?
1.0f
;
178
????mtrl.Diffuse.b?
=
?mtrl.Ambient.b?
=
?
0.0f
;
179
????mtrl.Diffuse.a?
=
?mtrl.Ambient.a?
=
?
1.0f
;
180
????
//
?設置物體的材質
181
????g_pd3dDevice
->
SetMaterial(?
&
mtrl?);
182
183
}
184
185
//
?渲染場景
186
void
?Render()
187
{
188
????
if
(g_pd3dDevice)
189
????
{
190
????????
//
?清空場景
191
????????g_pd3dDevice
->
Clear(
0
?,?
0
?,?D3DCLEAR_TARGET?
|
?D3DCLEAR_ZBUFFER?,?D3DCOLOR_XRGB(
0
?,?
0
?,?
0
)?,?
1
?,?
0
);
192
????????
//
?開始渲染
193
????????
if
(SUCCEEDED(g_pd3dDevice
->
BeginScene()))
194
????????
{
195
????????????SetTransform();
196
????????????SetupLight();
197
????????????g_pd3dDevice
->
SetRenderState(D3DRS_AMBIENT?,?D3DCOLOR_XRGB(
64
?,?
64
?,?
64
?));
198
????????????g_pd3dDevice
->
SetStreamSource(
0
?,?g_pVB?,?
0
?,?
sizeof
(CUSTOMVERTEX));
199
????????????g_pd3dDevice
->
SetFVF(D3DFVF_CUSTOMVERTEX);
200
????????????g_pd3dDevice
->
DrawPrimitive(D3DPT_TRIANGLESTRIP?,?
0
?,?
2
?
*
?
50
?
-
?
2
);
201
????????????g_pd3dDevice
->
EndScene();
202
????????}
203
????????
//
?顯示
204
????????g_pd3dDevice
->
Present(
0
?,?
0
?,?
0
?,?
0
);
205
????}
206
}
207
208
//
?初始化?D3D?設備
209
HRESULT?InitD3D(HWND?hWnd)
210
{
211
????
//
?創建?D3D?Driver
212
????
if
(NULL?
==
?(g_pD3D?
=
?Direct3DCreate9(D3D_SDK_VERSION)))
213
????
{
214
????????D3DErr(
"
無法創建Direct3D9設備
"
);
215
????????
return
?E_FAIL;
216
????}
217
????
//
?獲取當前顯示模式
218
????D3DDISPLAYMODE?d3ddm;
219
????
if
(FAILED(g_pD3D
->
GetAdapterDisplayMode(D3DADAPTER_DEFAULT?,?
&
d3ddm)))
220
????
{
221
????????D3DErr(
"
無法獲取D3D顯示器模式
"
);
222
????????
return
?E_FAIL;
223
????}
224
225
????
//
?獲取窗口的大小
226
????RECT?rect;
227
????GetClientRect(hWnd?,?
&
rect);
228
229
????
//
?填充參數
230
????D3DPRESENT_PARAMETERS?d3dpp;
231
????memset(
&
d3dpp?,?
0
?,?
sizeof
(d3dpp));
232
????d3dpp.BackBufferFormat?
=
?d3ddm.Format;
233
????d3dpp.BackBufferWidth?
=
?rect.right?
-
?rect.left;
234
????d3dpp.BackBufferHeight?
=
?rect.bottom?
-
?rect.top;
235
????d3dpp.SwapEffect?
=
?D3DSWAPEFFECT_DISCARD;
236
????d3dpp.Windowed?
=
?
true
;
237
????d3dpp.AutoDepthStencilFormat?
=
?D3DFMT_D16;
238
????d3dpp.EnableAutoDepthStencil?
=
?TRUE;
239
240
????
//
?獲取帽子
241
????
if
(FAILED(g_pD3D
->
GetDeviceCaps(D3DADAPTER_DEFAULT?,?D3DDEVTYPE_HAL?,?
&
g_Caps)))
242
????
{
243
????????D3DErr(
"
獲取D3D?帽子時發生錯誤
"
);
244
????????
return
?E_FAIL;
245
????}
246
247
????
//
?創建D3D設備
248
????
if
(FAILED(g_pD3D
->
CreateDevice(D3DADAPTER_DEFAULT
249
????????,?D3DDEVTYPE_HAL
250
????????,?hWnd
251
????????
//
?檢查是否支持硬件頂點處理
252
????????,?g_Caps.DevCaps?
&
?D3DDEVCAPS_HWTRANSFORMANDLIGHT?
?
?D3DCREATE_HARDWARE_VERTEXPROCESSING?:?D3DCREATE_SOFTWARE_VERTEXPROCESSING
253
????????,?
&
d3dpp
254
????????,?
&
g_pd3dDevice
255
????????)
256
????????))
257
????
{
258
????????D3DErr(
"
創建D3D設備時發生錯誤
"
);
259
????????
return
?E_FAIL;
260
????}
261
????g_pd3dDevice
->
SetRenderState(?D3DRS_CULLMODE,?D3DCULL_NONE?);
262
????g_pd3dDevice
->
SetRenderState(?D3DRS_ZENABLE,?TRUE?);
263
264
????
if
(FAILED(InitGeometry()))
265
????????
return
?E_FAIL;
266
????
return
?S_OK;
267
}
268
269
//
?清空所有占用的資源
270
void
?CleanUp()
271
{
272
????SAFE_RELEASE(g_pIB);
273
????SAFE_RELEASE(g_pVB);
274
????SAFE_RELEASE(g_pd3dDevice);
275
????SAFE_RELEASE(g_pD3D);
276
}
277
278
279
//
?消息處理
280
LRESULT?WINAPI?MsgProc(HWND?hWnd?,?UINT?message?,?WPARAM?wParam?,?LPARAM?lParam)
281
{
282
????
switch
(message)
283
????
{
284
????
case
?WM_DESTROY:
285
????????CleanUp();
286
????????PostQuitMessage(
0
);
287
????????
break
;
288
????}
289
????
return
?::DefWindowProc(hWnd,?message?,?wParam?,?lParam);
290
}
291
292
//
?Windows?入口
293
int
?WINAPI?WinMain(IN?HINSTANCE?hInstance,?IN?HINSTANCE?hPrevInstance,?IN?LPSTR?lpCmdLine,?IN?
int
?nShowCmd?)
294
{
295
????WNDCLASS?wndClass;
296
????memset(
&
wndClass?,?
0
?,?
sizeof
(wndClass));
297
????wndClass.hInstance?
=
?hInstance;
298
????wndClass.lpszClassName?
=
?
"
Tutorial02
"
;
299
????wndClass.lpfnWndProc?
=
?MsgProc;
300
????RegisterClass(
&
wndClass);
301
302
????
//
?創建窗口
303
????HWND?hWnd?
=
?CreateWindow(
"
Tutorial02
"
?,?
"
Tutorial02?Lighting
"
?
304
????????,?WS_OVERLAPPEDWINDOW?,?
0
?,?
0
?,?
512
?,
512
?,?GetDesktopWindow()
305
????????,?
0
?,?wndClass.hInstance?,?
0
);
306
????
//
?顯示窗口
307
????ShowWindow(hWnd?,?SW_SHOWDEFAULT);
308
????UpdateWindow(hWnd);
309
310
????
//
?初始化?D3D?設備
311
????
if
(SUCCEEDED(InitD3D(hWnd)))
312
????
{
313
????????
//
?消息處理循環
314
????????MSG?msg;
315
????????memset(
&
msg?,?
0
?,?
sizeof
(msg));
316
????????
while
(msg.message?
!=
?WM_QUIT)
317
????????
{
318
????????????
if
(PeekMessage(
&
msg?,?
0
?,?
0
?,?
0
?,?PM_REMOVE))
319
????????????
{
320
????????????????TranslateMessage(
&
msg);
321
????????????????DispatchMessage(
&
msg);
322
????????????}
323
????????????
else
324
????????????
{
325
????????????????Render();
326
????????????}
327
????????}
328
????}
329
????
//
?清空場景
330
????CleanUp();
331
332
????UnregisterClass(
"
Tutorial02
"
?,?wndClass.hInstance);
333
334
????
return
?
0
;
335
}
|