3D游戏编程入门(十五)索引缓存
呃,废话了,转回正题。
上次我们已经做了个三角形了,但是那仅仅是一个面,大家一定很不过瘾,哪儿象3D了?OK,今天我们来做个立方体,大家就会感觉到很有D3D的成就了,当然我们在三角形之上要加入一些新知识,那就是索引缓存。
现在我们抛弃计算机的任何想法来单纯从立体几何学想下,我们的一个正方体在空间上用几个点可以确定?恩,要没有算错的话应该是8个顶点信息就可以确定正方体了。
36?8?为什么会出现这种情况,理由很容易想到,我们很多的顶点实际上是重复了,我们若还是传36个顶点的话,将会占用更多的顶点缓存,这时我们会想如何有效的利用已有顶点。D3D给我们提供了一个方法来进行顶点的重复使用,就是顶点索引。
顶点索引,就是将我们的所有顶点进行标号索引,之后我们若再使用它的时候,调用它的索引就可以了,无需重新创建一个新的顶点,在的型项目中,这是绝对必须的。一般大型项目中的角色低摸应当是1300左右的三角面,若我们每个三角形给它三个点,则需要3900个点,而我们使用顶点索引的话,仅仅需要1400左右的点,就算顶点结构中仅有三维坐标+颜色+顶点法线+UV纹理+反光材质的信息来说,也省下2500X(8x4+32+8x3+8x2+8x3)=320000字节=312.5K=0.3M多的顶点缓存呢,再加上场景网格的,其他角色模型的。呼,使用顶点索引明显可以节省大量的内存空间,同时,D3D渲染流水线也避免了对相同顶点的重复运算,很大程度上提高了程序的整体性能。
我们知道了为什么必须用索引缓存之后,我们来说下顶点索引的相关概念。我们知道,顶点信息在缓存中存储时必须为它开辟一个空间,之后将它放置到顶点缓冲区中,再进行渲染,但我们在设置顶点缓存时已经为它设置好了相对的缓存区大小,那么我们的索引存放到哪儿呢,当然我们需要为它专门开辟一个索引缓存区(IndexBuffer),它是专门进行存储索引数组的内存缓冲区。这里值得说明的是,在我们索引缓冲时,必须是顺时针来定义三角形的顶点。这点在之后我会再次强调。下面说明下索引缓存的使用步骤。
1:当然,我们首先应该想到,我们设置顶点信息后,应该设置一个数组来记录整个顶点的索引。
// 自定义顶点结构
struct CUSTOMVERTEX
{ FLOAT x, y, z, rhw; // 经过坐标转换的顶点坐标
DWORD color; // 顶点漫反射颜色值
};
// 自定义顶点格式
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
CUSTOMVERTEX g_Vertices[] =
{ { 50.0f , 250.0f, 0.5f, 1.0f, 0xff00ffff, },
{ 50.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, },
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 250.0f, 50.0f, 0.5f, 1.0f, 0xffffffff, },
};
WORD g_Indices[] ={0,1,2,3,2,1};
最下面的g_Indices这个数组就是记录索引的数组,我们可以想想0,1,2三个点绘制的是怎么样的三角形,3,2,1又是如何的一个三角形,我为什么又要设置为3,2,1而不是1,2,3呢?
2:索引数组我们有了,接下来我们建立一个索引缓冲区来存储它,并且将此数组内容放置到开辟的索引缓冲区去。
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;
//创建索引缓冲区
if( FAILED( g_pd3dDevice->CreateIndexBuffer( 6*sizeof(WORD),
0, D3DFMT_INDEX16,
D3DPOOL_DEFAULT, &g_pIB,NULL ) ) )
{
return E_FAIL;
}
VOID* pIndices;
if( FAILED( g_pIB->Lock( 0, sizeof(g_Indices), (void**)&pIndices, 0 ) ) )//锁定索引缓存
return E_FAIL;
memcpy( pIndices, g_Indices, sizeof(g_Indices) );//复制数组内容到索引缓存
g_pIB->Unlock(); //解锁索引缓存区
其中创建索引缓存区的函数声明如下:
HRESULT CreateIndexBuffer(
UINT Length, //索引缓冲区大小,按字节数计算
DWORD Usage, //索引缓冲区属性,和顶点缓冲区相同
D3DFORMAT Format, //索引数组的元素格式,是16位或32位的格式
D3DPOOL Pool, //索引缓冲区内存位置
IDirect3DIndexBuffer9** ppIndexBuffer, //索引缓冲区指针地址
HANDLE* pHandle //保留参数,设为0
)
若看的还不理解,建议您看下上一节我们开辟顶点缓存时的说明,是完全一致的。这里仅仅多了一个Format索引缓存的格式,我们可以填写D3DFMT_INDEX16或D3DFMT_INDEX32,分别代表我们使用16位整数或是32位整数来表示我们的索引值。
3:我们也将设置好的索引数组放置到索引缓存中了,此时我们需要声明我们当前顶点是使用的哪一套索引。在上面的声明中,我们并没有说明这一点,该功能函数的声明如下:
HRESULT SetIndices(
IDirect3DIndexBuffer9 *pIndexData //使用的索引缓冲区指针
);
我们仅仅传一个指针就足够了,这还是相当容易的。
4:好了,告诉了系统我们使用哪套索引了,又设置好了顶点缓存和索引缓存。此时开始绘制了,你会问:上次我们画三角形时不是使用的DrawPrimitive()函数来画了三角形吗?很可惜的是在设置索引后,我们不能再使用DrawPrimitive()函数了,需要使用下面DrawIndexedPrimitive()函数来替代原函数,表示我们正在使用顶点索引的方式来绘制图象。此函数声明如下:
HRESULT DrawIndexedPrimitive(
转载于:https://www.cnblogs.com/Anzhongliu/p/6092050.html
3D游戏编程入门(十五)索引缓存相关推荐
- 游戏编程之十五 DirectDraw 的基本知识
视频课:[免费]跨平台APP JQuery Mobile开发-1-初探移动开发-张晨光的在线视频教程-CSDN程序员研修院 DirectDraw 游戏编程基础(2) 游戏使计算机的发展超越了晶体管时代 ...
- 3D游戏编程学习笔记(五):与游戏世界交互
一.前言 本次3D游戏编程我们将设计一个简单打飞碟(Hit UFO)有游戏. 二.游戏基本内容及规定 游戏基本内容 游戏有 n 个 round,每个 round 都包括10 次 trial: 每个 t ...
- 3d游戏编程(转帖)
3d游戏编程(转帖) 我先声明,我不是编程高手,我还只是个初学者,但我觉得我所知道的对刚入门3D游戏编程的新手,应该能让他们少走弯路,我也很想用朝语来写,但是朝语的词 汇库很久没有更新过了,有些专业的 ...
- 《Android4游戏编程入门经典》读后感
<Android4游戏编程入门经典>读后感 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 对于程序员来说,游戏编程并不是一件容易的事情.很多 ...
- Android 4游戏编程入门经典
<Android 4游戏编程入门经典> 基本信息 原书名:Beginning Android 4 Games evelopment 作者: (美)Mario Zechner Robert ...
- 3D游戏建模入门基础:3dmax常用功能详解
你收藏了那么多教程,却不知道3dmax怎么入门?掌握3dmax常用功能是3dmax入门的基础之一,所以呢小编今天就为您盘点了一些3dmax最常用到的功能和使用方法,快来和小编一起学习3dmax入门基础 ...
- 3D游戏编程与设计——游戏的本质章节作业与练习
3D游戏编程与设计--游戏的本质章节作业与练习 18342138 郑卓民 3D游戏编程与设计--游戏的本质章节作业与练习 作业与练习: 游戏名称及简介: 游戏的随机性 游戏的玩法与目标 游戏的冲突 游 ...
- .netframework游戏编程入门——模拟魔兽学院永远的羁绊
相信有很多和我一样摸索着编游戏的自学者,自学是辛苦的,一没明确的引导,二没正确的工具,我就谈一下自己的经验,也许可以让你少走一点弯路.3D 的先不谈,2D作为基础还是有必要研究,然后把地图模型一换(换 ...
- 3D游戏编程与设计-井字棋
3D游戏编程与设计-井字棋 目录 3D游戏编程与设计-井字棋 A. 简答题 1. 解释游戏对象(GameObjects)和资源(Assets)的区别与联系 ① 游戏对象 ② 资源 2. 下载几个游戏案 ...
最新文章
- faster rcnn第二阶段loss出现nan_利用Faster_Rcnn训练模型时出现的问题
- Rhel7 Ldap为本地用户认证方式,设置域、服务器位置和下载key
- 扫盲文章:AMF,RTMP,RTMPT,RTMPS
- C++vector容器-互换容器
- 网管日志-06.07.25
- LeetCode 1318. 或运算的最小翻转次数(位运算)
- JavaScript从入门到放弃 - ES6中的对象和类
- java activemq 断线_activemq 长时间没有消息client会断开吗?
- 面向接口的开发到面向对象的编程
- 蓝桥杯2019年第十届C/C++省赛B组第六题-特别数的和
- 史上最全的程序员常用英语词汇 珍藏版
- 如何将YouTube视频插入PowerPoint演示文稿
- 要么听我的,要么走开(摘自《代码之道》第8章)
- HTTP超文本传输协议详解
- 免费-进销存、Erp系统、、crm系统、oa系统推荐锦集
- 美妆科技:改变美容行业的未来
- APP测试的主要内容
- 忠实通物流信息管理系统
- 京东之鉴:兄弟是兄弟,员工是员工!-千氪
- Linux入门+环境搭建云服务器
热门文章
- 大连东软信息学院计算机专业19分数线,2021大连东软信息学院录取分数线_历年各专业分数线(2017-2020),各省投档线_一品高考网...
- 网站排名在首位后,为什么还要继续做SEO?
- 新老网站长时间无收录多半是站内出了问题
- python数据分析numpy_利用python进行数据分析-NumPy高级应用
- 趣谈网络协议笔记-二(第十二讲)
- 开发日记-20190828 关键词 读书笔记《Unix环境高级编程(第二版)》DAY 4
- python为什么要使用闭包
- 机器学习案例学习【每周一例】之 Titanic: Machine Learning from Disaster
- python3 aes 解密
- HDU 2149.Public Sale-巴什博奕