DirectX 学习笔记 四、索引缓冲
时间:2011-03-16 来源:广阔之海
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
IDirect3D9* g_pD3D = NULL; // D3D接口指针
IDirect3DDevice9* g_pDevice = NULL; // D3D设备指针
IDirect3DVertexBuffer9* g_pVB = NULL; // 顶点缓冲区
IDirect3DIndexBuffer9* g_pIB = NULL; // 索引缓冲区
LPSTR szClassName = "dx"; // 窗口类名
LPSTR szWindowName = "dx_IndexBuffer"; // 窗口标题名
int nWidth = 300; // 窗口宽度
int nHeight = 300; // 窗口高度
// 声明顶点结构体
struct Vertex
{
float x, y, z;
DWORD color;
static const DWORD FVF;
};
// 顶点渲染格式
const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
//------------------------------------------------------------------------
// 初始化D3D
//------------------------------------------------------------------------
BOOL InitD3D(HWND hWnd)
{
// 取得D3D接口指针
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
{
MessageBox(NULL, "Direct3DCreate9 failed!", NULL, NULL);
return FALSE;
}
// 取得主设备显示模式
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
// 检测硬件顶点渲染
D3DCAPS9 caps;
g_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
int vp = 0;
if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
// 填充创建D3D设备的结构体
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
// 创建D3D设备
if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd, vp, &d3dpp, &g_pDevice)))
{
MessageBox(NULL, "CreateDevice failed!", NULL, NULL);
return FALSE;
}
// 禁用背面剔除,即正反面都渲染
g_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
// 禁用灯光
g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
return TRUE;
}
//------------------------------------------------------------------------
// 初始化几何信息
//------------------------------------------------------------------------
BOOL InitGeometry()
{
// 定义顶点数组
Vertex vertices[] =
{
{ -0.5f, -0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 0.5f, -0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ 0.0f, 0.5f, 0.5f, D3DCOLOR_XRGB(255, 0, 0), },
{ 0.0f, -0.5f, 0.0f, D3DCOLOR_XRGB(255, 255, 0), },
};
// 定义索引序列
WORD indices[] = { 0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 3 };
// 创建顶点缓冲区
g_pDevice->CreateVertexBuffer(sizeof(vertices),
0, Vertex::FVF, D3DPOOL_DEFAULT, &g_pVB, NULL);
// 把顶点数据存入顶点缓冲区
void* pVertices;
g_pVB->Lock(0, sizeof(vertices), (void**)&pVertices, 0);
memcpy(pVertices, vertices, sizeof(vertices));
g_pVB->Unlock();
// 创建索引缓冲区
g_pDevice->CreateIndexBuffer(sizeof(indices),
0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIB, NULL);
// 把索引数据存入索引缓冲区
void* pIndices;
g_pIB->Lock(0, sizeof(indices), (void**)&pIndices, 0);
memcpy(pIndices, indices, sizeof(indices));
g_pIB->Unlock();
return TRUE;
}
//------------------------------------------------------------------------
// 清除资源
//------------------------------------------------------------------------
void Cleanup()
{
if (g_pIB != NULL)
g_pIB->Release();
if (g_pVB != NULL)
g_pVB->Release();
if (g_pDevice != NULL)
g_pDevice->Release();
if (g_pD3D != NULL)
g_pD3D->Release();
}
//------------------------------------------------------------------------
// 渲染场景
//------------------------------------------------------------------------
void Render()
{
if (g_pDevice == NULL)
return;
// 清除后置缓冲区
g_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
// 开始渲染
g_pDevice->BeginScene();
// 渲染顶点
g_pDevice->SetFVF(Vertex::FVF);
g_pDevice->SetStreamSource(0, g_pVB, 0, sizeof(Vertex));
g_pDevice->SetIndices(g_pIB);
g_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 4);
// 结束渲染
g_pDevice->EndScene();
// 显示后置缓冲区的画面
g_pDevice->Present(NULL, NULL, NULL, NULL);
}
//------------------------------------------------------------------------
// 消息处理
//------------------------------------------------------------------------
LRESULT CALLBACK MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
Render();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
//------------------------------------------------------------------------
// Windows主函数
//------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
// 注册窗口类
WNDCLASS wc;
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpfnWndProc = MsgProc;
wc.lpszClassName = szClassName;
wc.lpszMenuName = NULL;
if (!RegisterClass(&wc))
{
MessageBox(NULL, "RegisterClass failed!", NULL, NULL);
return FALSE;
}
// 获取窗口居中位置
RECT rect;
GetWindowRect(GetDesktopWindow(), &rect);
int left = (rect.right - rect.left - nWidth)/2;
int top = (rect.bottom - rect.top - nHeight)/2;
// 创建窗口
HWND hWnd = CreateWindow(szClassName, szWindowName,
WS_OVERLAPPEDWINDOW, left, top, nWidth, nHeight,
NULL, NULL, wc.hInstance, NULL);
if(!hWnd)
{
MessageBox(NULL, "CreateWindow failed!", NULL, NULL);
return FALSE;
}
// 初始化D3D
if (InitD3D(hWnd))
{
// 初始化几何信息
if (InitGeometry())
{
// 显示窗口
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// 消息循环
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
Cleanup();
UnregisterClass(szClassName, wc.hInstance);
return 0;
} 相关阅读 更多 +
排行榜 更多 +










