1 //////////////////////////////////////////////////////////////////////////
2 //绘制一个立方体
3 #include<Windows.h>
4 #include <d3dx9.h>
5
6 #pragma comment(lib,"d3d9.lib")
7 #pragma comment(lib,"d3dx9.lib")
8 #pragma comment(lib,"winmm.lib")
9
10 //全局变量
11 LPDIRECT3D9 g_pD3D = NULL ;
12 LPDIRECT3DDEVICE9 g_pDevice = NULL;
13 const int width = 600;
14 const int height = 400;
15 //保存顶点缓存和索引缓存的指针
16 LPDIRECT3DVERTEXBUFFER9 g_pVB;
17 LPDIRECT3DINDEXBUFFER9 g_pIB;
18
19 //定义顶点结构和该结构的灵活定点格式
20 struct Vertex
21 {
22 float fx,fy,fz;
23
24 Vertex(){}
25 Vertex(float x,float y,float z)
26 {
27 fx = x;
28 fy = y;
29 fz = z;
30 }
31
32 static const DWORD FVF;
33 };
34
35 //初始化FVF
36 const DWORD Vertex::FVF = D3DFVF_XYZ;
37
38 //初始化d3d
39 HRESULT InitD3D( HWND hwnd )
40 {
41 g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
42 if ( !g_pD3D )
43 {
44 return S_FALSE;
45 }
46 D3DPRESENT_PARAMETERS d3dpp;
47 d3dpp.BackBufferWidth = width;
48 d3dpp.BackBufferHeight = height;
49 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
50 d3dpp.BackBufferCount = 1;
51 d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
52 d3dpp.MultiSampleQuality = 0;
53 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
54 d3dpp.hDeviceWindow = hwnd;
55 d3dpp.Windowed = TRUE; //FLASE 表示全屏
56 d3dpp.EnableAutoDepthStencil = true;
57 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
58 d3dpp.Flags = 0;
59 d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
60 d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
61
62 HRESULT result;
63 result = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&g_pDevice);
64
65 if (FAILED( result))
66 {
67 return S_FALSE;
68 }
69
70 return S_OK;
71 }
72
73 //初始化顶点缓存和索引缓存
74 bool InitVertexAndIndexBuf()
75 {
76 if ( !g_pDevice )
77 {
78 return false;
79 }
80 //创建顶点缓存
81 g_pDevice->CreateVertexBuffer(
82 8 * sizeof(Vertex), //立方体共有8个顶点 顶点缓存的大小
83 D3DUSAGE_WRITEONLY,
84 Vertex::FVF, //顶点缓存格式
85 D3DPOOL_MANAGED, //内存池
86 &g_pVB, //保存创建好的顶点缓存的指针
87 0
88 );
89
90 //创建索引缓存
91 g_pDevice->CreateIndexBuffer(
92 36*sizeof(WORD), //需要36个索引 (一个面 = 2个三角形 ,每个三角形有3个顶点)
93 D3DUSAGE_WRITEONLY, //对缓存的操作模式为只读
94 D3DFMT_INDEX16,
95 D3DPOOL_MANAGED,
96 &g_pIB, //保存创建好的索引缓存指针
97 0
98 );
99
100 //用立方体的数据填充这两个缓存
101 Vertex * pVertices = NULL; //保存顶点缓存地址
102 //获取顶点缓存的地址
103 g_pVB->Lock(0,0,(VOID **)&pVertices,0);
104
105 //填充顶点数据
106 if(pVertices )
107 {
108 pVertices[0] = Vertex(-1.0f, -1.0f, -1.0f);
109 pVertices[1] = Vertex(-1.0f, 1.0f, -1.0f);
110 pVertices[2] = Vertex( 1.0f, 1.0f, -1.0f);
111 pVertices[3] = Vertex( 1.0f, -1.0f, -1.0f);
112 pVertices[4] = Vertex(-1.0f, -1.0f, 1.0f);
113 pVertices[5] = Vertex(-1.0f, 1.0f, 1.0f);
114 pVertices[6] = Vertex( 1.0f, 1.0f, 1.0f);
115 pVertices[7] = Vertex( 1.0f, -1.0f, 1.0f);
116 }
117
118 g_pVB->Unlock();
119
120 //填充索引缓存
121 WORD *indices;
122 g_pIB->Lock(0,0,(VOID **)&indices,0);
123
124 // front side
125 indices[0] = 0; indices[1] = 1; indices[2] = 2;
126 indices[3] = 0; indices[4] = 2; indices[5] = 3;
127
128 // back side
129 indices[6] = 4; indices[7] = 6; indices[8] = 5;
130 indices[9] = 4; indices[10] = 7; indices[11] = 6;
131
132 // left side
133 indices[12] = 4; indices[13] = 5; indices[14] = 1;
134 indices[15] = 4; indices[16] = 1; indices[17] = 0;
135
136 // right side
137 indices[18] = 3; indices[19] = 2; indices[20] = 6;
138 indices[21] = 3; indices[22] = 6; indices[23] = 7;
139
140 // top
141 indices[24] = 1; indices[25] = 5; indices[26] = 6;
142 indices[27] = 1; indices[28] = 6; indices[29] = 2;
143
144 // bottom
145 indices[30] = 4; indices[31] = 0; indices[32] = 3;
146 indices[33] = 4; indices[34] = 3; indices[35] = 7;
147
148 g_pVB->Unlock();
149
150 //取景变换
151 D3DXVECTOR3 position(0.0f,0.0f,-5.0f); //定义摄像机在世界坐标系中的位置
152 D3DXVECTOR3 targetPosition(0.0f,0.0f,0.0f); //观察点坐标系
153 D3DXVECTOR3 worldUp(0.0f,1.0f,0.0f); //世界坐标系中表示向上方向的分量
154
155 //定义取景变换矩阵
156 D3DXMATRIX V;
157 //获取取景变换矩阵
158 D3DXMatrixLookAtLH(&V,&position,&targetPosition,&worldUp);
159 //设置取景变换
160 g_pDevice->SetTransform(D3DTS_VIEW,&V);
161
162 //投影变换
163 D3DXMATRIX ProjV;
164 //计算投影矩阵
165 D3DXMatrixPerspectiveFovLH(
166 &ProjV,
167 D3DX_PI *0.5, //视域体的视域角度(90')
168 (float)width/height,//纵横比
169 1.0f, //近裁剪面到坐标原点的距离1
170 1000.0f); //源裁剪面到坐标原点的距离1000
171 //设置投影变换
172 g_pDevice->SetTransform(D3DTS_PROJECTION,&ProjV);
173
174 //设置绘制状态
175 g_pDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); //设置线框模式
176 return true;
177 }
178
179 //释放资源
180 VOID CleanUp()
181 {
182 if (g_pIB) g_pIB->Release();
183 if (g_pVB) g_pVB->Release();
184 if (g_pDevice) g_pDevice->Release();
185 if (g_pD3D ) g_pD3D->Release();
186 }
187
188 //渲染图形
189 bool Render(float timeDelta)
190 {
191 if (g_pDevice)
192 {
193 //旋转立方体
194 //定义按x 、y方向上旋转的矩阵
195 D3DXMATRIX Rx,Ry;
196 D3DXMatrixRotationX(&Rx,D3DX_PI/4.0f); //创建按x轴旋转45度的矩阵
197 //D3DXMatrixRotationX(&Rx,0.0f);
198 //旋转立方体Y
199 static float IncreaseY = 0.0f; //Y轴旋转角度的增量
200 D3DXMatrixRotationY(&Ry,IncreaseY);
201 IncreaseY += timeDelta;
202
203 //超过360度增量为0
204 if( IncreaseY > D3DX_PI * 2)
205 {
206 IncreaseY = 0.0f;
207 }
208
209 //将x和y 轴上的矩阵变换组合为一个矩阵
210 D3DXMATRIX p = Rx * Ry;
211
212 //进行世界变换
213 g_pDevice->SetTransform(D3DTS_WORLD,&p);
214
215 //////////////////////////////////////////////////////////////////////////
216 //绘制屏幕
217 g_pDevice->Clear(0,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,255,0),1.0f,0);
218 if(SUCCEEDED(g_pDevice->BeginScene()))
219 {
220 g_pDevice->SetStreamSource(0,g_pVB,0,sizeof(Vertex));
221 g_pDevice->SetIndices(g_pIB);
222 g_pDevice->SetFVF(Vertex::FVF);
223
224 //绘制立方体
225 g_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
226
227 g_pDevice->EndScene();
228 g_pDevice->Present(0,0,0,0);
229 }
230 }
231 return true;
232 }
233
234 LRESULT WINAPI MgsProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam )
235 {
236 switch( msg )
237 {
238 case WM_DESTROY:
239 {
240 CleanUp();
241 PostQuitMessage(0);
242 return 0;
243 }
244 }
245
246 return DefWindowProc(hwnd,msg,wParam,lParam);
247 }
248
249 //WinMain
250 INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hInstPre,LPSTR lpcmdLine,INT nShow)
251 {
252 WNDCLASSEX wc =
253 {
254 sizeof( WNDCLASSEX ), CS_CLASSDC, MgsProc, 0L, 0L,
255 GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
256 "Cube", NULL
257 };
258 RegisterClassEx( &wc );
259
260 // Create the application's window
261 HWND hWnd = CreateWindow("Cube", "Cube",
262 WS_OVERLAPPEDWINDOW, 100, 100, width, height,
263 NULL, NULL, wc.hInstance, NULL );
264
265 //初始化d3d
266 if(SUCCEEDED(InitD3D(hWnd)))
267 {
268 //初始化顶点缓存和索引缓存
269 if(SUCCEEDED(InitVertexAndIndexBuf()))
270 {
271 //显示窗口
272 ShowWindow(hWnd,SW_SHOWDEFAULT);
273 UpdateWindow(hWnd);
274
275 //消息循环
276 MSG msg;
277 ZeroMemory(&msg,sizeof(msg));
278
279 while(msg.message != WM_QUIT )
280 {
281 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
282 {
283 TranslateMessage( &msg );
284 DispatchMessage( &msg );
285 }
286 else
287 {
288 static float lastTime = (float)timeGetTime();
289 float currTime = (float)timeGetTime();
290 float timeDelta = (currTime - lastTime)*0.001f;
291 Render(timeDelta);
292 lastTime = currTime;
293
294 }
295 }
296 }
297 }
298
299 UnregisterClass("D3D Tutorial", wc.hInstance );
300 return 0;
301 }