【原创】《DirectX 9 3D 图形程序设计》 Tutorial 04 矩阵变换

【原创】《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 }

你可能感兴趣的:(【原创】《DirectX 9 3D 图形程序设计》 Tutorial 04 矩阵变换)