顶点缓存与索引缓存

一个顶点缓存是一个包含顶点数据的连续内存空间,一个索引缓存是一个包含索引数据的连续内存空间,之所以使用顶点缓存和索引缓存而非数组来存储数据,是因为顶点缓存和索引缓存可以被放置在显存中,进行绘制时,使用显存中的数据将获得比使用系统内存中的数据快的多的绘制速度。代码中顶点缓存使用接口IDirect3DVertexBuffer9表示,索引缓存使用接口IDirect3DIndexBuffer9表示。

  HRESULT IDirect3DDevice9::CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,         //存储在顶点缓存中顶点的灵活顶点格式    D3DPOOL Pool,    //容纳缓存的内存池IDirect3DVertexBuffer9** ppVertexBuffer, //用于接收所创建的顶点缓存的指针HANDLE* pSharedHandle //不使用,设置为0);HRESULT IDirect3DDevice9::CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format, D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer, //用于接收所创建的索引缓存的指针HANDLE* pSharedHandle);

Length:为缓存分配的字节数,如果想让顶点缓存足够存储8个顶点,改参数需设为8*sizeof(Vertex),Vertex是定义顶点的结构

Usage:指定关于如何使用缓存的一些附加属性,该值为可为0(表示无需附加属性)或是一下标记中的某一个或某种组合
D3DUSAGE_DYNAMIC:将缓存设为动态缓存
D3DUSAGE_POINTS:规定缓存将用于存储点图元
D3DUSAGE_SOFTWAREPROCESSING:指定软件顶点运算方式
D3DUSAGE_WRITEONLY:规定应用程序对缓存的操作模式为"只写",这样驱动程序就可以将缓存放在最适合写操作的内存地址中,对使用该标记创建的缓存进行读操作将会出错。

Format:指定索引大小,设置为D3DFMT_INDEX16表示16为索引,设为D3DFMT_INDEX32表示32位索引,并非所有图形设备都支持32位索引,如需使用请检查硬件性能

静态缓存:创建缓存时未使用标记D3DUSAGE_DYNAMIC,则为静态缓存,静态缓存一般被放置在显存中,以保证存储于其中的数据得到最高效的处理,静态缓存是以牺牲对静态缓存读写操作的速度为代价的,这是因为访问显存的速度本身就很慢,所以我们用静态缓存来存储静态数据(那些不需要经常修改或访问的数据)。例如地形和城市建筑数据就很适合存储在静态缓存中,这类数据在程序运行时通常不需要进行修改,静态缓存必须在应用程序初始化时用几何体的数据进行填充。

动态缓存:创建缓存时使用标记D3DUSAGE_DYNAMIC,则为动态缓存,动态缓存一般放置在AGP存储区中,其内容可被迅速更新,动态缓存中数据的处理速度不像静态缓存那样快,这是因为在绘制前数据必须传输到显存中,但动态缓存的突出优点是其更新速度相当快(快速的CPU写操作)。所以如果需要频繁更新缓存中的内容,该缓存应设置为动态的。粒子系统就是使用动态缓存的一个很好例子,因为粒子是活动的,所以需要对每帧图像中粒子的几何布局进行更新。另外,对显存和AGP存储区进行读操作非常慢,所以需要在程序运行时读取几何数据,最好再系统内存中保留一份副本,然后在需要时对其进行读操作

//创建一个可容纳8个Vertex类型的顶点静态顶点缓存IDirect3DVertexBuffer9* vb;Device->CreateVertexBuffer(8 * sizeof(Vertex),0,D3DFVF_XYZ,D3DPOOL_MANAGED,&vb,0);//创建可容纳36个16位索引的动态索引缓存IDirect3DIndexBuffer9* ib;Device->CreateIndexBuffer(36 * sizeof(WORD),D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&ib,0);

访问缓存内容

为了访问缓存中的数据,需要获得指向缓存内部存储区的指针,可以借助方法Lock来获取指向缓存内容的指针,对缓存访问完毕后,必须对缓存进行解锁unlock,只要获取了指向缓存内容的指针,就可以对其内容进行读写操作(如果使用了D3DUSAGE_WRITEONLY标记,则无法对该缓存进行读操作,否则会导致读取失败)。

 HRESULT IDirect3DVertexBuffer9::Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags);HRESULT IDirect3DIndexBuffer9::Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags);

OffsetToLock:自缓存的起始点开始锁定的位置的偏移量,单位为字节
SizeToLock:所要锁定的字节数
ppbData:指向被锁定的存储区起始位置的指针
Flags:该标记描述了锁定的方式,可以是0,也可是下列标记之一或某种组合
D3DLOCK_DISCARD:该标记仅用于动态缓存它指示硬件将缓存内容丢弃,并返回一个指向重新分配的缓存的指针,该标记十分有用,因为这允许在我们访问新分配的内存时,硬件能够继续使用被丢弃的缓存中的数据进行绘制,这样硬件的绘制就不会中止。
D3DLOCK_NOOVERWRITE:该标记仅用于动态缓存,使用该标记后,数据只能以追加方式写入缓存,即不能覆盖当前用于绘制的存储区中任何内容,这十分有用,因为它可保证在往缓存中增加数据时,硬件仍可持续进行绘制。
D3DLOCK_READONLY:该标记表示对于锁定的缓存只可读而不可写,利用这一点可以作一些内部优化。

标记D3DLOCK_DISCARDD3DLOCK_NOOVERWRITE表明缓存区的某一部分在锁定之后可以使用(用于绘制),如果环境(硬件配置)允许使用这些标记,在对缓存进行锁定时,其他操作就不会中断

获取顶点缓存和索引缓存的信息

 D3DVERTEXBUFFER_DESC vbDescription;vertexBuffer->GetDesc(&vbDescription);  //get vb infoD3DINDEXBUFFER_DESC ibDescription;indexBuffer->GetDesc(&ibDescription);   //get ib info
/* Vertex Buffer Description */
typedef struct _D3DVERTEXBUFFER_DESC
{D3DFORMAT           Format;D3DRESOURCETYPE     Type;DWORD               Usage;D3DPOOL             Pool;UINT                Size;DWORD               FVF;} D3DVERTEXBUFFER_DESC;/* Index Buffer Description */
typedef struct _D3DINDEXBUFFER_DESC
{D3DFORMAT           Format;D3DRESOURCETYPE     Type;DWORD               Usage;D3DPOOL             Pool;UINT                Size;
} D3DINDEXBUFFER_DESC;

绘制状态

Direct3D封装了多种绘制状态,这些绘制状态将影响几何体的绘制方式,各种绘制状态都有默认值,自指定某种绘制状态起,直至该状态被修改,该状态始终有效。

 HRESULT IDirect3DDevice9::SetRenderState(D3DRENDERSTATETYPE State,  //绘制状态枚举DWORD Value                 //状态对应的具体枚举值);

绘制的准备工作

一旦我们创建了顶点缓存以及索引缓存(可选),基本上已经可以准备对其所存储的内容进行绘制了,在绘制前还有3个步骤需要完成。

1.指定数据流输入源:将顶点缓存和数据流进行链接,实质上是将几何体的信息传输到绘制流水线中。

 HRESULT IDirect3DDevice9::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride);

StreamNumber:标识与顶点缓存建立链接的数据流,如果不使用多个流,则设置为0即可
pStreamData:指向我们希望与给定数据流建立链接的顶点缓存的指针
OffsetInBytes:自数据流的起始点算起的一个偏移量,单位为字节,指定了将被传输至绘制流水线的顶点数据的起始位置,如果想将该参数设为某一个非0值,请务必检查D3DCAPS9结构中的D3DDEVCAPS2_STREAMOFFSET标记,已判断设备是否支持该功能(顶点运算功能校验)。
Stride:将要链接到数据流的顶点缓存中每个元素的大小,单位为字节

Device->SetStreamSource(0, vb, 0, sizeof(Vertex));

2.设置顶点格式:在这里指定后续绘制调用中使用的顶点格式

Device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);

3.设置顶点缓存:如果我们想使用索引缓存,必须对后续绘制操作中所要使用的索引缓存进行设置,任意时刻只允许使用一个索引缓存,如果要使用一个不同的索引缓存绘制物体时,必须进行切换

Device->SetIndices(_ib); //参数为IDirect3DIndexBuffer9指针

使用顶点缓存和索引缓存进行绘制

缓存创建完毕且准备工作完成后,便可对几何体进行绘制,也就是使用DrawPrimitiveDrawIndexedPrimitive方法将待绘制几何体的信息通过绘制流水线传输,这两个方法从顶点顶点数据流中获取顶点信息,并从当前设定的索引缓存中提取索引信息。

HRESULT IDirect3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);

PrimitiveType:所要绘制的图元类型,绘制三角形则使用D3DPT_TRIANGLELIST,除此之外还可以绘制点和线。
StartVertex:顶点数据流中标识顶点数据读取起点的元素索引,该参数赋予了我们一定自由度,使得我们可以只对顶点缓存中的某一部分进行绘制
PrimitiveCount:所要绘制的图元数量

Direct3D中的绘制相关推荐

  1. Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(一)

    顶点和顶点布局 在Direct3D中,顶点由空间位置和各种附加属性组成,Direct3D可以让我们灵活地建立属于我们自己的顶点格式:换句话说,它允许我们定义顶点的分量.要创建一个自定义的顶点格式,我们 ...

  2. Direct3D中的绘制(3)

    立方体--只比三角形稍微复杂一点,这个程序渲染一个线框立方体. 这个简单的绘制和渲染立方体的程序的运行结果如下图所示: 源程序: /********************************** ...

  3. Direct3D中的纹理映射

    一.概要           为了使渲染的图形看起来更真实,Direct3D提供了在物体表面绘制纹理的功能.一般来说,纹理是表示物体表面细节的一幅或几幅二维图形,也称纹理贴图.借助纹理映射技术,我们可 ...

  4. Direct3D中的四大变换

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8408723 作者:毛星云(浅墨 ...

  5. python使用matplotlib可视化折线图、在可视化图像中同时绘制多条折线图

    python使用matplotlib可视化折线图.在可视化图像中同时绘制多条折线图 目录 python使用matplotlib可视化折线图.在可视化图像中同时绘制多条折线图

  6. Android中View绘制流程以及invalidate()等相关方法分析

                                                                                                        ...

  7. 成功解决利用matplotlib.pyplot进行绘图的时候整个画布中的绘制曲线只显示一部分

    成功解决利用matplotlib.pyplot进行绘图的时候整个画布中的绘制曲线只显示一部分 目录 解决问题 解决思路 解决方法 解决问题 利用matplotlib.pyplot进行绘图的时候整个画布 ...

  8. OpenCV 中的绘制功能

    本文主要内容来自于 OpenCV-Python 教程 的 OpenCV 中的 GUI 功能 部分,这个部分的主要内容如下: 图像操作入门 学习加载一幅图像,显示它,并保存它 视频入门 学习播放视频,从 ...

  9. qt中实现绘制图形与截图

    引言 实现可以选择线型,线宽,颜色,是否填充图形来绘制各种常见的图形,同时可以选择矩形区域来实现截图. 效果 绘图的效果如上,截图的效果: 实现 项目使用的qt5.13.2,编译器为MSVC2017_ ...

最新文章

  1. 面试90%都会翻车的高可用+高并发+负载均衡架构设计 !
  2. 以后教育孩子学好数学的方法 多思动漫数学
  3. windows 7作为微软对抗Google的秘密武器
  4. 解决python时间戳最大为3001年1月1日15时59分59秒的问题
  5. int 为什么是2147483647_2147483647代表什么
  6. “压扁数组”技巧(flattening the array)
  7. TableView详解
  8. 对C#未来的一点感悟
  9. 寻找性能更优秀的动态 Getter 和 Setter 方案
  10. jQuery菜鸟总结
  11. 比较两个字符串相同的个数,并输出
  12. jmeter笔记02
  13. chrome浏览器历史版本
  14. 可以检测手机帧率和温度的软件_手机帧数测试教学,含免费软件下载,使用方法,数据分析方法详解...
  15. java爬虫爬取京东_java爬虫练习|爬取京东上的手机商品数据
  16. Flutter气泡框实现
  17. Axure 制作过滤筛选栏
  18. Linux 系统配置信息查询 各种查看Linux配置的方法
  19. 【HTML】HTML自定义网页头部小图标
  20. java 网格包,一个网格包的问题

热门文章

  1. 秒杀小程序 php后台,基于ThinkPhp6.0+Vue 开发实现微信小程序、公众号、商城、拼团、秒杀、后台管理等功能...
  2. MySQL间隙锁(幻读解决原理)
  3. verilog实现有符号数求绝对值
  4. 机器学习之K近邻(KNN)模型
  5. 信丰二中2021高考成绩查询,信丰二中
  6. SM2256K AB主控固态硬盘开卡经验,SM2259XT2可以参考
  7. Tableau数据分析笔记-Chapter13雷达图和凹凸图
  8. 使用Dreamweaver MX制作基础简易6行8列个人简历表格。
  9. linux设备驱动归纳总结(九):1.platform设备驱动
  10. RabbitMQ:Consumers的介绍和使用