【原创】《DirectX 9 3D 图形程序设计》 Tutorial 02 创建顶点缓冲区容易犯错的地方

【原创】《DirectX 9 3D 图形程序设计》 Tutorial 02 创建顶点缓冲区容易犯错的地方

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 }

 

你可能感兴趣的:(【原创】《DirectX 9 3D 图形程序设计》 Tutorial 02 创建顶点缓冲区容易犯错的地方)