Direct基础学习系列3 绘制+实例

3.1.1顶点缓存 索引缓存

放置在显存中能够加快绘制速度

创建顶点缓存

HRESULT CreateVertexBuffer(
  UINT Length,    //为缓存分配的字节数
  DWORD Usage,    //缓存附加属性,可为0
  DWORD FVF,      //顶点格式
  D3DPOOL Pool,   //缓存的内存池
  IDirect3DVertexBuffer9** ppVertexBuffer, //返回的结构
  HANDLE* pSharedHandle  //不用 设置为0
);
创建索引缓存
HRESULT CreateIndexBuffer(
  UINT Length,
  DWORD Usage,
  D3DFORMAT Format,
  D3DPOOL Pool,
  IDirect3DIndexBuffer9** ppIndexBuffer,
  HANDLE* pSharedHandle
);
Usage != D3DUSAGE_DYNAMIC 放置在静态缓存中,适合处理运行中不需要修改的数据
Usage = D3DUSAGE_DYNAMIC 放置在动态缓存,适合频繁更新内容,如粒子系统,动态缓存放置在内存AGP区域,可以很快的被更新
3.1.2访问数据
HRESULT Lock( 
UINT OffsetToLock,   //缓存中的起始点
UINT SizeToLock,   //需要锁定的数目
VOID ** ppbData,     //返回的被锁定的缓存区起始位置
DWORD Flags          //锁定方式:
);
BOOL Unlock();
3.1.3获得顶点缓存信息
typedef struct D3DVERTEXBUFFER_DESC {
    D3DFORMAT Format;
    D3DRESOURCETYPE Type;
    DWORD Usage;
    D3DPOOL Pool;
    UINT Size;
    DWORD FVF;
} D3DVERTEXBUFFER_DESC, *LPD3DVERTEXBUFFER_DESC;
typedef struct D3DINDEXBUFFER_DESC {
    D3DFORMAT Format;
    D3DRESOURCETYPE Type;
    DWORD Usage;
    D3DPOOL Pool;
    UINT Size;
} D3DINDEXBUFFER_DESC, *LPD3DINDEXBUFFER_DESC;
IDirect3DIndexBuffer9::GetDesc();
3.2 绘制状态
HRESULT SetRenderState(
  [in]  D3DRENDERSTATETYPE State,
  [in]  DWORD Value
);
3.3绘制准备工作
(1)制定数据流输入源
HRESULT SetStreamSource(
  UINT StreamNumber,      //数据流 可以是多个
  IDirect3DVertexBuffer9 * pStreamData,//建立数据流的缓存
  UINT OffsetInBytes,  //被传送到绘制流水线顶点数据的起始位置
  UINT Stride   //顶点缓存的大小
);
(2)设置顶点格式
HRESULT SetFVF(  DWORD FVF); 顶点格式如下:
(3)设置使用的索引,任意时刻只能有一个索引缓存,如果不同索引绘制物体时,必须进行切换
HRESULT SetIndices(
  IDirect3DIndexBuffer9 * pIndexData
);
3.4 绘制方法
使用顶点绘制
HRESULT DrawPrimitive(  
D3DPRIMITIVETYPE PrimitiveType,  //绘制的图元类型,TRIANGLELIST 
UINT StartVertex,  //绘制起点索引
UINT PrimitiveCount  //绘制的图元数量
);
采用索引绘制
HRESULT DrawIndexedPrimitive(
  D3DPRIMITIVETYPE Type,
  INT BaseVertexIndex,  //物体顶点在全局缓存中的起始位置偏移
  UINT MinIndex,
  UINT NumVertices,
  UINT StartIndex,
  UINT PrimitiveCount
);
绘制在下列函数之间进行

IDirect3DDevice9::BeginScene()

IDirect3DDevice9::EndScene()

 

实例:看完代码之后 多的一层了解:

(1)世界变换矩阵,取景变换矩阵,投影变换矩阵设置后 在绘图中起作用

(2)缓存中其实就在准备数据

 

   1:   
   2:  #include "d3dUtility.h"
   3:   
   4:  IDirect3DDevice9* Device = 0; 
   5:   
   6:  const int Width  = 640;
   7:  const int Height = 480;
   8:   
   9:  IDirect3DVertexBuffer9* VB = 0;
  10:  IDirect3DIndexBuffer9*  IB = 0;
  11:   
  12:  //顶点格式定义
  13:  struct Vertex
  14:  {
  15:      Vertex(){}
  16:      Vertex(float x, float y, float z)
  17:      {
  18:          _x = x;  _y = y;  _z = z;
  19:      }
  20:      float _x, _y, _z;
  21:      static const DWORD FVF;
  22:  };
  23:  //全局定点格式
  24:  const DWORD Vertex::FVF = D3DFVF_XYZ;
  25:   
  26:  //
  27:  // Framework Functions
  28:  //
  29:  bool Setup()
  30:  {
  31:      // Create vertex and index buffers.
  32:      Device->CreateVertexBuffer(
  33:          8 * sizeof(Vertex), 
  34:          D3DUSAGE_WRITEONLY,
  35:          Vertex::FVF,
  36:          D3DPOOL_MANAGED,
  37:          &VB,
  38:          0);
  39:      Device->CreateIndexBuffer(
  40:          36 * sizeof(WORD),
  41:          D3DUSAGE_WRITEONLY,
  42:          D3DFMT_INDEX16,
  43:          D3DPOOL_MANAGED,
  44:          &IB,
  45:          0);
  46:   
  47:   
  48:      // 填充数据
  49:      Vertex* vertices;
  50:      VB->Lock(0, 0, (void**)&vertices, 0);
  51:   
  52:      // vertices of a unit cube
  53:      vertices[0] = Vertex(-1.0f, -1.0f, -1.0f);
  54:      vertices[1] = Vertex(-1.0f,  1.0f, -1.0f);
  55:      vertices[2] = Vertex( 1.0f,  1.0f, -1.0f);
  56:      vertices[3] = Vertex( 1.0f, -1.0f, -1.0f);
  57:      vertices[4] = Vertex(-1.0f, -1.0f,  1.0f);
  58:      vertices[5] = Vertex(-1.0f,  1.0f,  1.0f);
  59:      vertices[6] = Vertex( 1.0f,  1.0f,  1.0f);
  60:      vertices[7] = Vertex( 1.0f, -1.0f,  1.0f);
  61:   
  62:      VB->Unlock();
  63:   
  64:      // define the triangles of the cube:
  65:      WORD* indices = 0;
  66:      IB->Lock(0, 0, (void**)&indices, 0);
  67:   
  68:      // front side
  69:      indices[0]  = 0; indices[1]  = 1; indices[2]  = 2;
  70:      indices[3]  = 0; indices[4]  = 2; indices[5]  = 3;
  71:   
  72:      // back side
  73:      indices[6]  = 4; indices[7]  = 6; indices[8]  = 5;
  74:      indices[9]  = 4; indices[10] = 7; indices[11] = 6;
  75:   
  76:      // left side
  77:      indices[12] = 4; indices[13] = 5; indices[14] = 1;
  78:      indices[15] = 4; indices[16] = 1; indices[17] = 0;
  79:   
  80:      // right side
  81:      indices[18] = 3; indices[19] = 2; indices[20] = 6;
  82:      indices[21] = 3; indices[22] = 6; indices[23] = 7;
  83:   
  84:      // top
  85:      indices[24] = 1; indices[25] = 5; indices[26] = 6;
  86:      indices[27] = 1; indices[28] = 6; indices[29] = 2;
  87:   
  88:      // bottom
  89:      indices[30] = 4; indices[31] = 0; indices[32] = 3;
  90:      indices[33] = 4; indices[34] = 3; indices[35] = 7;
  91:   
  92:      IB->Unlock();
  93:   
  94:      D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
  95:      D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
  96:      D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
  97:      D3DXMATRIX V;
  98:   
  99:      D3DXMatrixLookAtLH(&V, &position, &target, &up);
 100:      //设置取景变换矩阵
 101:      Device->SetTransform(D3DTS_VIEW, &V);
 102:   
 103:      // Set the projection matrix.
 104:      D3DXMATRIX proj;
 105:      D3DXMatrixPerspectiveFovLH(
 106:              &proj,
 107:              D3DX_PI * 0.5f, // 90 - degree
 108:              (float)Width / (float)Height,
 109:              1.0f,
 110:              1000.0f);
 111:   
 112:      //设置投影变换矩阵
 113:      Device->SetTransform(D3DTS_PROJECTION, &proj);
 114:   
 115:      //设置绘图模式
 116:      Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
 117:   
 118:      return true;
 119:  }
 120:   
 121:  void Cleanup()
 122:  {
 123:      d3d::Release<IDirect3DVertexBuffer9*>(VB);
 124:      d3d::Release<IDirect3DIndexBuffer9*>(IB);
 125:  }
 126:   
 127:  bool Display(float timeDelta)
 128:  {
 129:      if( Device )
 130:      {
 131:          // spin the cube:
 132:          D3DXMATRIX Rx, Ry;
 133:   
 134:          // rotate 45 degrees on x-axis
 135:          D3DXMatrixRotationX(&Rx, 3.14f / 4.0f);
 136:   
 137:          // incremement y-rotation angle each frame
 138:          static float y = 0.0f;
 139:          D3DXMatrixRotationY(&Ry, y);
 140:          y += timeDelta;     // 每帧增加旋转量
 141:   
 142:          // reset angle to zero when angle reaches 2*PI
 143:          if( y >= 6.28f )
 144:              y = 0.0f;
 145:   
 146:          // combine x- and y-axis rotation transformations.
 147:          D3DXMATRIX p = Rx * Ry;
 148:   
 149:          //设置世界变换矩阵
 150:          Device->SetTransform(D3DTS_WORLD, &p);
 151:   
 152:          //
 153:          // draw the scene:
 154:   
 155:          //清除背景
 156:          Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
 157:          Device->BeginScene();
 158:   
 159:          //设置数据源
 160:          Device->SetStreamSource(0, VB, 0, sizeof(Vertex));
 161:   
 162:          //设置使用的索引
 163:          Device->SetIndices(IB);
 164:   
 165:          //
 166:          Device->SetFVF(Vertex::FVF);
 167:   
 168:          // Draw cube.
 169:          Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
 170:   
 171:          Device->EndScene();
 172:          Device->Present(0, 0, 0, 0);
 173:      }
 174:      return true;
 175:  }
 176:   
 177:   
 178:  //
 179:  // WndProc
 180:  //
 181:  LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 182:  {
 183:      switch( msg )
 184:      {
 185:      case WM_DESTROY:
 186:          ::PostQuitMessage(0);
 187:          break;
 188:          
 189:      case WM_KEYDOWN:
 190:          if( wParam == VK_ESCAPE )
 191:              ::DestroyWindow(hwnd);
 192:          break;
 193:      }
 194:      return ::DefWindowProc(hwnd, msg, wParam, lParam);
 195:  }
 196:   
 197:  //
 198:  // WinMain
 199:  //
 200:  int WINAPI WinMain(HINSTANCE hinstance,
 201:                     HINSTANCE prevInstance, 
 202:                     PSTR cmdLine,
 203:                     int showCmd)
 204:  {
 205:      if(!d3d::InitD3D(hinstance,
 206:          Width, Height, true, D3DDEVTYPE_HAL, &Device))
 207:      {
 208:          ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
 209:          return 0;
 210:      }
 211:          
 212:      if(!Setup())
 213:      {
 214:          ::MessageBox(0, "Setup() - FAILED", 0, 0);
 215:          return 0;
 216:      }
 217:   
 218:      d3d::EnterMsgLoop( Display );
 219:   
 220:      Cleanup();
 221:   
 222:      Device->Release();
 223:   
 224:      return 0;
 225:  }
posted @ 2013-10-22 01:23  RubbyZhang  阅读(573)  评论(0编辑  收藏  举报