渲染之前记得g_pd3dDevice->SetIndices(g_pIB); 而且要用g_pd3dDevice->DrawIndexedPrimitive来渲染索引缓冲区
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_XYZRHW | D3DFVF_DIFFUSE)
15
struct
CUSTOMVERTEX
16
{
17
D3DXVECTOR4 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(
4
*
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
,
4
*
sizeof
(CUSTOMVERTEX) , (
void
**
)
&
pVertecies ,
0
)))
37
{
38
pVertecies[
0
].position
=
D3DXVECTOR4(
50
,
50
,
0.5
,
1
);
39
pVertecies[
1
].position
=
D3DXVECTOR4(
250
,
250
,
0.5
,
1
);
40
pVertecies[
2
].position
=
D3DXVECTOR4(
50
,
250
,
0.5
,
1
);
41
pVertecies[
3
].position
=
D3DXVECTOR4(
250
,
50
,
0.5
,
1
);
42
43
44
pVertecies[
0
].color
=
D3DCOLOR_XRGB(
255
,
0
,
0
);
45
pVertecies[
1
].color
=
D3DCOLOR_XRGB(
0
,
255
,
0
);
46
pVertecies[
2
].color
=
D3DCOLOR_XRGB(
0
,
0
,
255
);
47
pVertecies[
3
].color
=
D3DCOLOR_XRGB(
255
,
255
,
255
);
48
49
g_pVB
->
Unlock();
50
}
51
else
52
{
53
return
E_FAIL;
54
}
55
return
S_OK;
56
}
57
58
59
//
初始化索引缓冲区
60
HRESULT InitIB()
61
{
62
//
创建顶点缓冲区
63
if
(FAILED(g_pd3dDevice
->
CreateIndexBuffer(
6
*
sizeof
(WORD) ,
0
, D3DFMT_INDEX16 , D3DPOOL_DEFAULT ,
&
g_pIB ,
0
)))
64
return
E_FAIL;
65
66
WORD
*
pIndices;
67
//
锁定缓冲区
68
if
(SUCCEEDED(g_pIB
->
Lock(
0
,
6
*
sizeof
(WORD) , (
void
**
)
&
pIndices ,
0
)))
69
{
70
pIndices[
0
]
=
0
;
71
pIndices[
1
]
=
1
;
72
pIndices[
2
]
=
2
;
73
pIndices[
3
]
=
0
;
74
pIndices[
4
]
=
3
;
75
pIndices[
5
]
=
1
;
76
g_pIB
->
Unlock();
77
}
78
else
79
{
80
return
E_FAIL;
81
}
82
return
S_OK;
83
}
84
85
//
渲染场景
86
void
Render()
87
{
88
if
(g_pd3dDevice)
89
{
90
//
清空场景
91
g_pd3dDevice
->
Clear(
0
,
0
, D3DCLEAR_TARGET , D3DCOLOR_XRGB(
0
,
0
,
255
) ,
1
,
0
);
92
//
开始渲染
93
if
(SUCCEEDED(g_pd3dDevice
->
BeginScene()))
94
{
95
g_pd3dDevice
->
SetStreamSource(
0
, g_pVB ,
0
,
sizeof
(CUSTOMVERTEX));
96
g_pd3dDevice
->
SetIndices(g_pIB);
97
g_pd3dDevice
->
SetFVF(D3DFVF_CUSTOMVERTEX);
98
g_pd3dDevice
->
DrawIndexedPrimitive(D3DPT_TRIANGLELIST ,
0
,
0
,
4
,
0
,
2
);
99
g_pd3dDevice
->
EndScene();
100
}
101
//
显示
102
g_pd3dDevice
->
Present(
0
,
0
,
0
,
0
);
103
}
104
}
105
106
//
初始化 D3D 设备
107
HRESULT InitD3D(HWND hWnd)
108
{
109
//
创建 D3D Driver
110
if
(NULL
==
(g_pD3D
=
Direct3DCreate9(D3D_SDK_VERSION)))
111
{
112
D3DErr(
"
无法创建Direct3D9设备
"
);
113
return
E_FAIL;
114
}
115
//
获取当前显示模式
116
D3DDISPLAYMODE d3ddm;
117
if
(FAILED(g_pD3D
->
GetAdapterDisplayMode(D3DADAPTER_DEFAULT ,
&
d3ddm)))
118
{
119
D3DErr(
"
无法获取D3D显示器模式
"
);
120
return
E_FAIL;
121
}
122
123
//
获取窗口的大小
124
RECT rect;
125
GetClientRect(hWnd ,
&
rect);
126
127
//
填充参数
128
D3DPRESENT_PARAMETERS d3dpp;
129
memset(
&
d3dpp ,
0
,
sizeof
(d3dpp));
130
d3dpp.BackBufferFormat
=
d3ddm.Format;
131
d3dpp.BackBufferWidth
=
rect.right
-
rect.left;
132
d3dpp.BackBufferHeight
=
rect.bottom
-
rect.top;
133
d3dpp.SwapEffect
=
D3DSWAPEFFECT_DISCARD;
134
d3dpp.Windowed
=
true
;
135
136
//
获取帽子
137
if
(FAILED(g_pD3D
->
GetDeviceCaps(D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL ,
&
g_Caps)))
138
{
139
D3DErr(
"
获取D3D 帽子时发生错误
"
);
140
return
E_FAIL;
141
}
142
143
//
创建D3D设备
144
if
(FAILED(g_pD3D
->
CreateDevice(D3DADAPTER_DEFAULT
145
, D3DDEVTYPE_HAL
146
, hWnd
147
//
检查是否支持硬件顶点处理
148
, g_Caps.DevCaps
&
D3DDEVCAPS_HWTRANSFORMANDLIGHT
?
D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING
149
,
&
d3dpp
150
,
&
g_pd3dDevice
151
)
152
))
153
{
154
D3DErr(
"
创建D3D设备时发生错误
"
);
155
return
E_FAIL;
156
}
157
158
//
创建顶点缓冲区
159
if
(FAILED(InitVB()))
160
return
E_FAIL;
161
//
创建索引缓冲区
162
if
(FAILED(InitIB()))
163
return
E_FAIL;
164
return
S_OK;
165
}
166
167
//
清空所有占用的资源
168
void
CleanUp()
169
{
170
SAFE_RELEASE(g_pIB);
171
SAFE_RELEASE(g_pVB);
172
SAFE_RELEASE(g_pd3dDevice);
173
SAFE_RELEASE(g_pD3D);
174
}
175
176
177
//
消息处理
178
LRESULT WINAPI MsgProc(HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
179
{
180
switch
(message)
181
{
182
case
WM_DESTROY:
183
CleanUp();
184
PostQuitMessage(
0
);
185
break
;
186
}
187
return
::DefWindowProc(hWnd, message , wParam , lParam);
188
}
189
190
//
Windows 入口
191
int
WINAPI WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN
int
nShowCmd )
192
{
193
WNDCLASS wndClass;
194
memset(
&
wndClass ,
0
,
sizeof
(wndClass));
195
wndClass.hInstance
=
hInstance;
196
wndClass.lpszClassName
=
"
Tutorial02
"
;
197
wndClass.lpfnWndProc
=
MsgProc;
198
RegisterClass(
&
wndClass);
199
200
//
创建窗口
201
HWND hWnd
=
CreateWindow(
"
Tutorial02
"
,
"
Tutorial02 Index Buffer
"
202
, WS_OVERLAPPEDWINDOW ,
0
,
0
,
512
,
512
, GetDesktopWindow()
203
,
0
, wndClass.hInstance ,
0
);
204
//
显示窗口
205
ShowWindow(hWnd , SW_SHOWDEFAULT);
206
UpdateWindow(hWnd);
207
208
//
初始化 D3D 设备
209
if
(SUCCEEDED(InitD3D(hWnd)))
210
{
211
//
消息处理循环
212
MSG msg;
213
memset(
&
msg ,
0
,
sizeof
(msg));
214
while
(msg.message
!=
WM_QUIT)
215
{
216
if
(PeekMessage(
&
msg ,
0
,
0
,
0
, PM_REMOVE))
217
{
218
TranslateMessage(
&
msg);
219
DispatchMessage(
&
msg);
220
}
221
else
222
{
223
Render();
224
}
225
}
226
}
227
//
清空场景
228
CleanUp();
229
230
UnregisterClass(
"
Tutorial02
"
, wndClass.hInstance);
231
232
return
0
;
233
}
|