小学的时候我们知道3个顶点组成一个三角形,那么四个顶点我们会说有4个三角形.这就是一个顶点同时参与了四次绘制三角形的结果. 在程序中也一样,比如我们绘制的两个三角形是挨着一起的,总有几个顶点是重合的. 这个顶点是可以重复使用,可以使用顶点缓存来记录如何绘制顶点的顺序,多次使用同一个顶点.到达内存的节省. 下面我们就是用四个顶点绘制出2个三角形


创建索引缓存:

LPDIRECT3DINDEXBUFFER9 g_pIndexBuffer = NULL;            //索引缓存
//创建索引缓存
if(FAILED(g_pd3dDevice->CreateIndexBuffer(6 * sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&g_pIndexBuffer,0)))
{
return E_FAIL;
}

访问索引缓存: 

WORD * indices = 0;
g_pIndexBuffer->Lock(0,0,(void**)&indices,0); //第一个三角形由0,1,3顶点组成
indices[0] = 0;
indices[1] = 1;
indices[2] = 3; //第二个三角形由1,2,3顶点组成
indices[3] = 1;
indices[4] = 2;
indices[5] = 3; g_pIndexBuffer->Unlock();

绘制图形:

g_pd3dDevice->SetStreamSource(0,g_pVertexBuffer,0,sizeof(CUSTOMVERTEX));        //设置绘制的顶点数据
g_pd3dDevice->SetIndices(g_pIndexBuffer); //设置索引缓存
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); //设置灵活顶点格式
g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2); //根据索引绘制图形,4代表使用4个顶点,2代表两个三角形,其他查询API了解吧

 

效果图:

全部代码:

#include <d3d9.h>
#include <d3dx9.h>
#include <tchar.h> #pragma comment(lib,"winmm.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib") #define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define WINDOW_TITLE L"盘子脸的程序"
#define SAFE_RELEASE(p) { if(p) { (p) -> Release();(p)=NULL;} } struct CUSTOMVERTEX
{
float x,y,z,rhw;
DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) //声明变量
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
ID3DXFont* g_pFont = NULL;
float g_FPS = 0.0f;
wchar_t g_strFPS[50]; //包含帧速率的字符
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL; //顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9 g_pIndexBuffer = NULL; //索引缓存 //全局函数声明部分
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
HRESULT Direct3DInit(HWND hwnd);
HRESULT ObjectsInit(HWND hwnd);
VOID Direct3DRender(HWND hwnd);
VOID Direct3DCleanUp(); //主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
//设置一个完整的窗口类,没有设置图标
WNDCLASSEX wndClass = {0};
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = CS_HREDRAW | CS_VREDRAW; //设置窗口样式
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = L"GameDevelop"; //注册窗口类
if(!RegisterClassEx(&wndClass))
{
return -1;
} //正式创建窗口
HWND hwnd = CreateWindow(L"GameDevelop",WINDOW_TITLE,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,WINDOW_WIDTH,
WINDOW_HEIGHT,NULL,NULL,hInstance,NULL); //初始化Direct3D资源
if(!(S_OK == Direct3DInit(hwnd)))
{
MessageBox(hwnd,_T("初始化Direct3D失败"),_T("盘子脸的消息窗口"),0);
} MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd); //消息循环过程
MSG msg = {0};
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg,0,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}else
{
Direct3DRender(hwnd);
}
} //窗口类的注销
UnregisterClass(L"GameDevelop",wndClass.hInstance); return 0;
} //消息处理函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
Direct3DRender(hwnd);
ValidateRect(hwnd,NULL);
break;
case WM_KEYDOWN:
if(wParam == VK_ESCAPE)
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
Direct3DCleanUp(); //失败Direct3D资源
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
} return 0;
} HRESULT Direct3DInit(HWND hwnd)
{
//创建Direct3D接口对象
LPDIRECT3D9 pD3D = NULL;
if(NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
{
return E_FAIL;
} //获取硬件消息
D3DCAPS9 caps;
int vp = 0;
if(FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps)))
{
return E_FAIL;
} if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
//支出硬件顶点运算
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
}
else
{
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
} //填充Direct3Dpresent参数
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = true;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //创建Direct3D设备接口
if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,vp,&d3dpp,&g_pd3dDevice)))
{
return E_FAIL;
} SAFE_RELEASE(pD3D); if(!(S_OK == ObjectsInit(hwnd)))
{
return E_FAIL;
} return S_OK;
} HRESULT ObjectsInit(HWND hwnd)
{
//创建字体
if(FAILED(D3DXCreateFont(g_pd3dDevice,36,0,0,1,false,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,DEFAULT_QUALITY,0,_T("微软雅黑"),&g_pFont)))
{
return E_FAIL;
} //创建顶点缓存
if(FAILED(g_pd3dDevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVertexBuffer,NULL)))
{
return E_FAIL;
} //创建索引缓存
if(FAILED(g_pd3dDevice->CreateIndexBuffer(6 * sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&g_pIndexBuffer,0)))
{
return E_FAIL;
} //创建顶点数据
CUSTOMVERTEX vertices [] =
{
{ 100.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(36, 45,0), },
{ 300.0f, 400.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255, 255, 255), },
{ 500.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0,44,0), },
{ 300.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0,0,0), },
}; //填充顶点缓冲区
VOID *pVertices;
if(FAILED(g_pVertexBuffer->Lock(0,sizeof(vertices),(void**)&pVertices,0))) //加锁
{
return E_FAIL;
} memcpy(pVertices,vertices,sizeof(vertices)); //把顶点数据保存到顶点缓存中
g_pVertexBuffer->Unlock(); //解锁 //这是索引缓存数据
WORD * indices = 0;
g_pIndexBuffer->Lock(0,0,(void**)&indices,0); indices[0] = 0;
indices[1] = 1;
indices[2] = 3; indices[3] = 1;
indices[4] = 2;
indices[5] = 3; g_pIndexBuffer->Unlock(); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,false);
return S_OK; } void Direct3DRender(HWND hwnd)
{
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0); //定义一个矩形
RECT formatRect;
GetClientRect(hwnd,&formatRect); g_pd3dDevice->BeginScene();
g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_GOURAUD); //绘制图形
g_pd3dDevice->SetStreamSource(0,g_pVertexBuffer,0,sizeof(CUSTOMVERTEX)); //设置绘制的顶点数据
g_pd3dDevice->SetIndices(g_pIndexBuffer);
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); //设置灵活顶点格式
//g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1); g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2); //绘制文本信息
g_pFont->DrawTextW(NULL,L"盘子脸",3,&formatRect,DT_TOP | DT_RIGHT , D3DCOLOR_XRGB(255,39,136)); g_pd3dDevice->EndScene();
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
} void Direct3DCleanUp()
{
SAFE_RELEASE(g_pVertexBuffer);
SAFE_RELEASE(g_pFont);
SAFE_RELEASE(g_pd3dDevice);
}

Direct3D 索引缓存的更多相关文章

  1. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记5——Direct3D中的顶点缓存和索引缓存

    第12章 Direct3D绘制基础 1. 顶点缓存 计算机所描绘的3D图形是通过多边形网格来构成的,网网格勾勒出轮廓,然后在网格轮廓的表面上贴上相应的图片,这样就构成了一个3D模型.三角形网格是构建物 ...

  2. DX9 DirectX 索引缓存(IndexBuffer) 代码

    // @time: 2012.3.22 // @author: jadeshu // des: 索引缓存 //包含头文件 #include <Windows.h> #include < ...

  3. [WebGL入门]十八,利用索引缓存来画图

    注:文章译自http://wgld.org/.原作者杉本雅広(doxas),文章中假设有我的额外说明.我会加上[lufy:].另外,鄙人webgl研究还不够深入,一些专业词语,假设翻译有误,欢迎大家指 ...

  4. mysql数据库性能优化(包括SQL,表结构,索引,缓存)

    优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...

  5. 【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)

    原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_ ...

  6. Direct3D 顶点缓存

    今天我们来学习下Direct3D的顶点和顶点缓存,首先我们需要在场景中绘制一些物体,物体都是由多个三角形组成,每一个三角形由三个顶点组成,我们来看下面一个NPC的模型 左图:正常的模型         ...

  7. Windows游戏编程之从零开始d

    Windows游戏编程之从零开始d I'm back~~恩,几个月不见,大家还好吗? 这段时间真的好多童鞋在博客里留言说或者发邮件说浅墨你回来继续更新博客吧. woxiangnifrr童鞋说每天都在来 ...

  8. 总结:如何使用redis缓存加索引处理数据库百万级并发

    前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1000万条数据,可以参考我之前的文章插入数据, ...

  9. 使用redis缓存加索引处理数据库百万级并发

    使用redis缓存加索引处理数据库百万级并发 前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1 ...

随机推荐

  1. pyqt一个小例子

    # -*- coding: utf-8 -*- __author__ = 'Administrator' from PyQt4 import Qt,QtCore,QtGui import sys,ra ...

  2. 让你不再纠结GitHub:Git起步

    一.关于版本控制 版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统.我们通常仅对保存着软件源代码的文本文件做版本控制,但实际上,你可以对任何类型的文件进行版本控制. 采用版本控制 ...

  3. wp8模拟器操作键盘

    当前焦点在模拟器上的某一个输入控件上时候, 按pagedown/pageup可以切换是用pc键盘还是模拟器键盘

  4. Java数据输入

    以下是数据输入实例: //以下是数据输入实例 import java.util.Scanner;//导入java.util.Scanner,Scanner首字母大写 public class Test ...

  5. 多种下载文件方式 Response.BinaryWrite(byte[] DocContent);Response.WriteFile(System.IO.FileInfo DownloadFile .FullName);Response.Write(string html2Excel);

    通过html给xls赋值,并下载xls文件 一.this.Response.Write(sw.ToString());System.IO.StringWriter sw = new System.IO ...

  6. (二)原生JS实现 - 事件类方法

    事件处理 - 添加事件 var addEventHandler = function (oTarget, sEventType, fnHandler) { if (oTarget.addEventLi ...

  7. 使用Flex 和 Red5开发简单视频直播功能

    Flex 是一个高效.免费的开源框架,可用于构建具有表现力的 Web应用程序,这些应用程序利用Adobe Flash Player和Adobe AIR, 可以实现跨浏览器.桌面和操作系统.虽然只能使用 ...

  8. win8 Pro 64位在 UEFI模式下Ghost系统 备份 恢复

    一:在win8 安装U 盘中  1. 新建 “Ghost” 文件夹 2. 将下载的Ghost64.exe 文件拷贝到文件夹  二: 启动的时候 按下F12 选择 HDDUSB 1.Windows 安装 ...

  9. js 按元素向数组中最佳删除元素

    追加::: var a = [];// 创建数组 a.push(1); // 添加到最后 a.unshift(); // 添加到第一个位置 删除:::如果你没有使用第三方框架,有类似的扩展功能可以根据 ...

  10. windows安装Apache HTTP服务器报错:无法启动,因为应用程序的并行配置不正确

    Apache HTTP服务器安装后报:无法启动,因为应用程序的并行配置不正确-(已解决)   0条评论 [摘要:本创做品,出自 “深蓝的blog” 专客,迎接转载,转载时请务必说明出处,不然有权穷究版 ...