利用Vertex绘制三角型
玩家对输入内容的反映速度要求很高,一旦反映慢了就会影响视觉感受。
消息处之后直接调用Render()函数, 充分利用闲置CPU进行图形绘制。 
 
while (msg.message != WM_QUIT)
{
  if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
 {
    TranslateMessage(&msg);
     DispatchMessage(&msg);
   }
  else
   Render();
}
使用FVF(自由顶点格式)绘制三角。其实格式就是D3D的顺序格式定义
struct CUSTOMVERTEX
{
  FLOAT x, y, z, rhw;
  DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
如果把把顺序换位个回出现问题

struct CUSTOMVERTEX
{
  FLOAT rhw, x, y, z;
  DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

创建顶点缓冲 Code
  1
/**//**-----------------------------------------------------------------------------
  2
 * \brief 创建顶点缓冲
  3
 * 文件: Vertices.cpp
  4
 *
  5
 * 说明: 下面讲解顶点渲染的内容。这里我们可以看到顶点缓冲(vertex buffer)的概念.
  6
 *       所谓顶点缓冲是指储存顶点的D3D对象, 用户可以使用FVF(Flexible Vertex Format) 
  7
 *       随意定义格式. 这里将要使用的顶点是完成变换和光源处理的顶点.
  8
 *       
  9
 *-----------------------------------------------------------------------------*/
 10
#include <d3d9.h>
 11
#pragma comment(lib, "d3d9.lib")
 12
 13
 14
LPDIRECT3D9             g_pD3D        = NULL;
 15
LPDIRECT3DDEVICE9       g_pd3dDevice  = NULL;
 16
LPDIRECT3DVERTEXBUFFER9 g_pVB         = NULL;
 17
 18
struct CUSTOMVERTEX
 19

{
 20
  FLOAT  x, y, z, rhw;
 21
  DWORD  color;
 22
};
 23
 24
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
 25
 26
HRESULT InitD3D(HWND);
 27
HRESULT InitVB();
 28
void Cleanup();
 29
VOID Render();
 30
LRESULT WINAPI MsgProc(HWND, UINT, WPARAM, LPARAM);
 31
 32
 33
 34
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
 35

{
 36
  WNDCLASSEX wc = 
{sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
 37
                       GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "D3D Tutorial", NULL};
 38
 39
  RegisterClassEx(&wc);
 40
  HWND hWnd = CreateWindow("D3D Tutorial", "D3D Tutorail 02: Vertices",
 41
                           WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
 42
                           GetDesktopWindow(), NULL, wc.hInstance, NULL);
 43
 44
  if (SUCCEEDED(InitD3D(hWnd)))
 45
  
{
 46
    if (SUCCEEDED(InitVB()))
 47
    
{
 48
      ShowWindow(hWnd, SW_SHOWDEFAULT);
 49
      UpdateWindow(hWnd);
 50
 51
      MSG msg;
 52
      ZeroMemory(&msg, sizeof(msg));
 53
      while (msg.message != WM_QUIT)
 54
      
{
 55
        /**//// 消息队列中有消息时,调用相应的处理过程
 56
        if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
 57
        
{
 58
          TranslateMessage(&msg);
 59
          DispatchMessage(&msg);
 60
        }
 61
        else
 62
      /**//// 如果没有需要处理的消息,调用Render()函数
 63
          Render();
 64
      }
 65
    }
 66
  }
 67
}
 68
 69
 70
HRESULT InitD3D(HWND hWnd)
 71

{
 72
  if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
 73
    return E_FAIL;
 74
 75
  D3DPRESENT_PARAMETERS d3dpp;
 76
  ZeroMemory(&d3dpp, sizeof(d3dpp));
 77
  d3dpp.Windowed = TRUE;
 78
  d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
 79
  d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
 80
 81
  if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
 82
            D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice)))
 83
    return E_FAIL;
 84
 85
  return S_OK;
 86
}
 87
 88
 89
/**//**-----------------------------------------------------------------------------
 90
 * 创建顶点缓冲,设置顶点值.
 91
 * 顶点缓冲就是基本包含顶点数据的存储器块.
 92
 * 创建顶点缓冲之后,必须调用Lock()函数和Unlock()函数来定义指针 
 93
 * 将顶点数据写入顶点缓冲.
 94
 * D3D可以使用索引缓冲.
 95
 * 基本系统存储器之外,顶点缓冲和索引缓冲也可以在设备存储器(显卡存储器)创建,
 96
 * 不过,这种情况下,大部分显卡的速度会受到很大的影响.
 97
 * 
 98
 *------------------------------------------------------------------------------
 99
 */
100
HRESULT InitVB()
101

{
102
  CUSTOMVERTEX vertices[] = 
103
  
{
104
    
{ 150.0f,   50.0f, 0.5f, 1.0f, 0xffff0000,},
105
    
{ 250.0f,  250.0f, 0.5f, 1.0f, 0xff00ff00,},
106
    
{  25.0f,  250.0f, 0.5f, 1.0f, 0xff00ffff,},
107
  };
108
109
  if (FAILED(g_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX,
110
        D3DPOOL_DEFAULT, &g_pVB, NULL)))
111
    return E_FAIL;
112
  
113
  VOID* pVertices;
114
  if (FAILED(g_pVB->Lock(0, sizeof(vertices), (void**)&pVertices, 0)))
115
    return E_FAIL;
116
117
  memcpy(pVertices, vertices, sizeof(vertices));
118
  g_pVB->Unlock();
119
120
  return S_OK;
121
    
122
}
123
124
void Cleanup()
125

{
126
  if (g_pVB != NULL)
127
    g_pVB->Release();
128
  if (g_pd3dDevice != NULL)
129
    g_pd3dDevice->Release();
130
  if (g_pD3D != NULL)
131
    g_pD3D->Release();
132
}
133
134
VOID Render()
135

{
136
  /**//// 清除缓冲
137
  g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1, 0);
138
  
139
  if (SUCCEEDED(g_pd3dDevice->BeginScene()))
140
  
{
141
    /**//// 绘制顶点三角形
142
    /// 1、设置绘制缓冲数据数据流
143
    g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
144
    /**//// 2、设置缓冲格式
145
    g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
146
    /**//// 3、
147
    g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
148
149
    g_pd3dDevice->EndScene();
150
  }
151
152
  /**//// 显示缓冲画面
153
  g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
154
}
155
156
LRESULT WINAPI MsgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
157

{
158
  switch(Msg)
159
  
{
160
  case WM_DESTROY:
161
      Cleanup();
162
      PostQuitMessage(0);
163
      return 0;
164
  }
165
166
  return DefWindowProc(hWnd, Msg, wParam, lParam);
167
}