逐梦猎人

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

d3d绘制立方体Cube

View Code
  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 }

 

posted on 2012-11-28 00:02  让知识沉淀  阅读(456)  评论(0)    收藏  举报