【原创】《DirectX 9 3D 图形程序设计》 Tutorial 04 矩阵变换
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
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304