13行,#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)是使用变换过的顶点格式,意思是在执行渲染流水线的过程中,不作顶点变换。换言之,可以直接用屏幕象素的单位大小来定义顶点的坐标。再换言之,就是说用这种顶点格式,可以简单的实现Overlay(不知道怎么翻译这个单词)
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
12
//
顶点定义,使用变换过的顶点坐标格式
13
#define
D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
14
struct
CUSTOMVERTEX
15
{
16
D3DXVECTOR4 position;
17
D3DCOLOR color;
18
}
;
19
20
//
错误记录
21
void
D3DErr(String strMsg)
22
{
23
MessageBox(
0
, strMsg.c_str() ,
"
错误
"
, MB_OK);
24
}
25
26
//
初始化顶点缓冲区
27
HRESULT InitVB()
28
{
29
//
创建顶点缓冲区
30
if
(FAILED(g_pd3dDevice
->
CreateVertexBuffer(
3
*
sizeof
(CUSTOMVERTEX) ,
0
, D3DFVF_CUSTOMVERTEX , D3DPOOL_DEFAULT ,
&
g_pVB ,
0
)))
31
return
E_FAIL;
32
33
CUSTOMVERTEX
*
pVertecies;
34
//
锁定缓冲区
35
if
(SUCCEEDED(g_pVB
->
Lock(
0
,
3
*
sizeof
(CUSTOMVERTEX) , (
void
**
)
&
pVertecies ,
0
)))
36
{
37
pVertecies[
0
].position
=
D3DXVECTOR4(
0
,
0
,
0.5
,
1
);
38
pVertecies[
1
].position
=
D3DXVECTOR4(
512
,
0
,
0.5
,
1
);
39
pVertecies[
2
].position
=
D3DXVECTOR4(
0
,
512
,
0.5
,
1
);
40
41
pVertecies[
0
].color
=
D3DCOLOR_XRGB(
255
,
0
,
0
);
42
pVertecies[
1
].color
=
D3DCOLOR_XRGB(
0
,
255
,
0
);
43
pVertecies[
2
].color
=
D3DCOLOR_XRGB(
0
,
0
,
255
);
44
45
g_pVB
->
Unlock();
46
}
47
else
48
{
49
return
E_FAIL;
50
}
51
return
S_OK;
52
}
53
54
//
初始化 D3D 设备
55
HRESULT InitD3D(HWND hWnd)
56
{
57
//
创建 D3D Driver
58
if
(NULL
==
(g_pD3D
=
Direct3DCreate9(D3D_SDK_VERSION)))
59
{
60
D3DErr(
"
无法创建Direct3D9设备
"
);
61
return
E_FAIL;
62
}
63
//
获取当前显示模式
64
D3DDISPLAYMODE d3ddm;
65
if
(FAILED(g_pD3D
->
GetAdapterDisplayMode(D3DADAPTER_DEFAULT ,
&
d3ddm)))
66
{
67
D3DErr(
"
无法获取D3D显示器模式
"
);
68
return
E_FAIL;
69
}
70
71
//
获取窗口的大小
72
RECT rect;
73
GetClientRect(hWnd ,
&
rect);
74
75
//
填充参数
76
D3DPRESENT_PARAMETERS d3dpp;
77
memset(
&
d3dpp ,
0
,
sizeof
(d3dpp));
78
d3dpp.BackBufferFormat
=
d3ddm.Format;
79
d3dpp.BackBufferWidth
=
rect.right
-
rect.left;
80
d3dpp.BackBufferHeight
=
rect.bottom
-
rect.top;
81
d3dpp.SwapEffect
=
D3DSWAPEFFECT_DISCARD;
82
d3dpp.Windowed
=
true
;
83
84
//
获取帽子
85
if
(FAILED(g_pD3D
->
GetDeviceCaps(D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL ,
&
g_Caps)))
86
{
87
D3DErr(
"
获取D3D 帽子时发生错误
"
);
88
return
E_FAIL;
89
}
90
91
//
创建D3D设备
92
if
(FAILED(g_pD3D
->
CreateDevice(D3DADAPTER_DEFAULT
93
, D3DDEVTYPE_HAL
94
, hWnd
95
//
检查是否支持硬件顶点处理
96
, g_Caps.DevCaps
&
D3DDEVCAPS_HWTRANSFORMANDLIGHT
?
D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING
97
,
&
d3dpp
98
,
&
g_pd3dDevice
99
)
100
))
101
{
102
D3DErr(
"
创建D3D设备时发生错误
"
);
103
return
E_FAIL;
104
}
105
106
//
创建顶点缓冲区
107
if
(FAILED(InitVB()))
108
return
E_FAIL;
109
return
S_OK;
110
}
111
112
//
清空所有占用的资源
113
void
CleanUp()
114
{
115
SAFE_RELEASE(g_pVB);
116
SAFE_RELEASE(g_pd3dDevice);
117
SAFE_RELEASE(g_pD3D);
118
}
119
120
//
渲染场景
121
void
Render()
122
{
123
if
(g_pd3dDevice)
124
{
125
//
清空场景
126
g_pd3dDevice
->
Clear(
0
,
0
, D3DCLEAR_TARGET , D3DCOLOR_XRGB(
0
,
0
,
255
) ,
1
,
0
);
127
//
开始渲染
128
if
(SUCCEEDED(g_pd3dDevice
->
BeginScene()))
129
{
130
g_pd3dDevice
->
SetRenderState(D3DRS_LIGHTING , FALSE);
131
g_pd3dDevice
->
SetStreamSource(
0
, g_pVB ,
0
,
sizeof
(CUSTOMVERTEX));
132
g_pd3dDevice
->
SetFVF(D3DFVF_CUSTOMVERTEX);
133
g_pd3dDevice
->
DrawPrimitive(D3DPT_TRIANGLELIST ,
0
,
1
);
134
g_pd3dDevice
->
EndScene();
135
}
136
//
显示
137
g_pd3dDevice
->
Present(
0
,
0
,
0
,
0
);
138
}
139
}
140
141
//
消息处理
142
LRESULT WINAPI MsgProc(HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
143
{
144
switch
(message)
145
{
146
case
WM_DESTROY:
147
CleanUp();
148
PostQuitMessage(
0
);
149
break
;
150
}
151
return
::DefWindowProc(hWnd, message , wParam , lParam);
152
}
153
154
//
Windows 入口
155
int
WINAPI WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN
int
nShowCmd )
156
{
157
WNDCLASS wndClass;
158
memset(
&
wndClass ,
0
,
sizeof
(wndClass));
159
wndClass.hInstance
=
hInstance;
160
wndClass.lpszClassName
=
"
Tutorial02
"
;
161
wndClass.lpfnWndProc
=
MsgProc;
162
RegisterClass(
&
wndClass);
163
164
//
创建窗口
165
HWND hWnd
=
CreateWindow(
"
Tutorial02
"
,
"
Tutorial02 Vertex Buffer
"
166
, WS_OVERLAPPEDWINDOW ,
0
,
0
,
512
,
512
, GetDesktopWindow()
167
,
0
, wndClass.hInstance ,
0
);
168
//
显示窗口
169
ShowWindow(hWnd , SW_SHOWDEFAULT);
170
UpdateWindow(hWnd);
171
172
//
初始化 D3D 设备
173
if
(SUCCEEDED(InitD3D(hWnd)))
174
{
175
//
消息处理循环
176
MSG msg;
177
memset(
&
msg ,
0
,
sizeof
(msg));
178
while
(msg.message
!=
WM_QUIT)
179
{
180
if
(PeekMessage(
&
msg ,
0
,
0
,
0
, PM_REMOVE))
181
{
182
TranslateMessage(
&
msg);
183
DispatchMessage(
&
msg);
184
}
185
else
186
{
187
Render();
188
}
189
}
190
}
191
//
清空场景
192
CleanUp();
193
194
UnregisterClass(
"
Tutorial02
"
, wndClass.hInstance);
195
196
return
0
;
197
}
|