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; }
相关阅读 更多 +