OGRE 硬件缓冲区(硬件缓存) .
来源:互联网 发布:淘宝上哪家埙好 编辑:程序博客网 时间:2024/06/05 19:27
http://blog.csdn.net/miao6664659/article/details/8075552
·定义
实际上这个缓冲区就是一块malloc出来的存储区域,不过它不如malloc是在内存中申请的区域,而这个缓冲区是在gpu/agp中,它的写读速度更快。通常硬件缓冲区作用有拿来做顶点缓冲区,索引缓冲区,和象素缓冲区。
·使用
硬件缓冲区的管理是交由一个硬件缓存管理器负责的HardwareBufferManager,他负责缓冲区的创建和释放,它是几何体创建工厂,单键在Root初始化时就会被创建,所以,当我们需要一块内存的时候,一定不要直接New或malloc操作,而应当是这样
VerBuf = HardwareBufferManager::GetSingleton().CreateVertexBuffer()
·类型
我们在分配一块硬件缓冲区时,需要传一个参数,来指明这块缓冲区的类型,是否需要频繁读写?这样对底层的硬件缓存区域分配管理提供很大的便利。我们来看一下硬件缓冲区的类型有哪些,我们分配它的时候应该做何选择。(HBU是HarewareBufferUsage简写)
HBU_STATIC 静态硬件缓冲区,它意味着我们很少写入更新缓冲区,偶尔会从中进行数据读取。
HBU_STATIC_WRITE_ONLY 只写静态硬件缓冲区。它意味着我们很少更新缓冲区,并且绝对不从该缓冲区进行数据读取。但是,当我们创建了一个备份缓冲的话,我们依旧可以对其读取。
HBU_DYNAMIC 动态硬件缓冲区。它意味着我们会经常性的更新缓冲区中的数据,并且也希望能从其中读取数据,这一个效率最低的缓冲区使用方法。
HBU_DYNAMIC_WRITE_ONLY 只写动态硬件缓冲区,这个是个只许写入的硬件缓冲区,但当我们创建了一个备份缓冲的话,还是允许读取的。
HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE 这个参数指明这个硬件缓冲区是一个需要频繁更新的缓冲区,大多数是每桢更新的数据存放在这里。但是需要注意的是,向该数据缓冲写入数据时记得加缓存锁。
建议:多使用WRITE_ONLY为后缀的缓冲区类型。即使必须进行读取,也建议使用备份缓冲,而非时刻可写的缓冲。
·备份缓冲
当我们创建一个WRITE_ONLY的硬件缓冲区后,我们有些时候假若非要从中读取数据,我们可以在创建缓冲区时传参,这样我们在内存中就会创建一个备份的缓冲区。每当我们向显存中写入一份数据的时候,Ogre会自动的先将这份数据拷贝到内存缓冲区后,再将其更新到显存中的硬件缓冲区。当然,这个技术会带来更多的开销,所以,非必要时不要用它。
·缓存锁
当我们更新写入缓冲或者在读取缓冲的时候,都应该先“锁”住它,以免它被修改。当然,之后记得解锁。pBuffer->Lock(begin , length , lockType)一般来说,锁的范围越小越便捷快速。但是锁的类型lockType也可以对读取的效率产生影响。
锁的类型包括:
·HBL_NORMAL 这种锁支持从缓冲区读取数据,但是效率很低下,因为它允许我们从硬件缓冲区进行数据读取。但是,当我们使用备份缓冲的话,这种影响会得到一些改善。
·HBL_READ_ONLY 这种锁意味着我们只能从缓冲区中进行内容的读取,禁止写入。此时建议我们使用备份缓冲,会提高我们效率。而且,此时我们实际上读取到的并非硬件缓冲区,而是内存中的数据。
·HBL_DISCARD 这种锁意味着我们每次操作都会将硬件缓冲区中的所有内容丢弃,一般这种操作也是会在每桢都处理的环境下才会使用,它是禁止读出的。但是一旦我们如此声明,也就基本上是向引擎宣称我们不会对硬件缓冲区的内容感兴趣,那么就不应当创建备份缓冲区。在我们没有使用备份缓冲区时尽量使用这种锁,它的效率很高,但若有了内存备份缓冲区的话,它就没有必要了。
·HBL_NO_OVERWRITE 当我们有些时候需要更新部分缓冲区而非全部缓冲区时,使用HBL_DISCARD就显的不适合了。此时我们就需要使用这种锁了,它的效率依旧很高,但是也仅是没有备份缓冲的时候才有作用。
·硬件缓冲区和缓冲锁使用经验
1:因为最快最优秀的缓冲自然是通过 HBU_STATIC_WRITE_ONLY类型创建,不创建备份缓存,并且仅进行一次HBL_DISCARD的锁操作永不再额外处理的缓冲。
2:当我们需要频繁更新的缓冲,可以用HBU_DYNAMIC_WRITE_ONLY来创建,不创建备份缓存,之后使用HBL_DISCARD加锁,若不想全部更新,则使用HBL_NO_OVERWRITE进行锁操作。
3:若我们必须从缓冲区中读取数据的话,那么我们可以创建一个备份缓冲,用HBL_READ_ONLY将其锁住。可能的话,尽量声明缓冲区为静态的。
4:在我们对顶点的不同元素需要使用不同模式的时候,我们不要通过指针大量更新缓冲区的全部顶点结构,应该分块更新。例如,我们假设只需要经常更新纹理坐标信息,那么我们应当将纹理坐标信息保存在一个单独的缓冲区区域,而其他的不经常更新的元素拆分保存在HBU_STATIC_WRITE_ONLY缓冲区中。
·顶点缓冲区
VertexData中有几个重要成员:
·VertexStart 顶点起始位置信息
·VertexCount 顶点个数
·VertexDeclaration 一个指向顶点数据个数的指针
·VertexBufferBinding 一个指向顶点缓冲区绑定的指针
其中顶点类型描述中我们需要强调一个顺序问题,为了支持DX9以前的版本,我们有必要按如下顺序声明和数据保存:
1:顶点位置信息
2:顶点绑定权重
3:顶点法线信息
4:顶点环境光颜色信息
5:顶点镜面光颜色信息
6:顶点纹理坐标信息
除了上面的顺序需要注意以外,我们还需要注意的是顶点缓冲区中,是绝对不允许有空隙存在的。
我们创建了一个顶点缓冲区后,我们还需要将起和指定的资源进行绑定。
格式如下 verterBufferBinding->setBinding(0, vertexBuffer);
之后,我们在运行时将顶点缓冲区绑定起来,循环的将其信息更新填充进入,Ogre提供了临接点与点之间的间隔长度和起始点信息,以便我们进行数据更新。
·索引缓冲区
与顶点缓冲区基本都是一致的。创建后更新。唯一的区别就是创建时有些属性不同而已。
·象素缓冲区
这里是保存纹理象素信息的。但是和顶点缓冲和索引缓冲不同的是,我们不能手动创建象素缓冲区,只有在我们创建一个纹理的时候,象素缓冲会自动被创建出来。
象素缓冲区中支持的纹理类型:
TEX_TYPE_1D 一维的纹理,通过1D纹理坐标来索引
TEX_TYPE_2D 二维的纹理,通过2D文理坐标来索引
TEX_TYPE_3D 三维的纹理,通过3D文理坐标来索引
TEX_TYPE_CUBE_MAP 一个立方体的六个表面纹理,通过3D纹理进行索引。
象素缓冲区的内存分配格式
Ogre中的图象数据的信息都被封装在一个个的PixelBox对象之中,我们需要注意的是PixelBox本身是保存在GPU中,但是真正的纹理都是保存在内存中,并非读到GPU中。GPU中的 PixelBox保存着内存中象素的格式位置内容信息的描述,但是PixelBox并没有内存管理的功能,它只能通过保存的内存指针来操作数据。象素盒中提供了通过深度,高度,宽度来索引象素的方法,若一维纹理没有高度和深度时,就将其参数补1。如下:(width, 1, 1),二维的纹理(width, height, 1)
象素缓冲区的更新
Ogre提供了两种更新象素缓冲区的方法。
1:手动建立一个纹理并将一个图片放入这个纹理中。我们可以如下代码Image img; img.load(“xxx.jpg”, “General”); Texture pTex = Texture::getSingleton().createManual( …. ); pTex->GetBuffer(0,0)->blitFromMemory( );
2:对一个象素缓冲区加锁之后对其进行读取和写入。
Buffer->Lock(HarewareBuffer::HBL_DISCARD);
const PixelBox &pb = buffer->getCurrentLock(); // 锁好了之后进行处理
for (int I = 0; I < pb.GetWindth(); ++I)
{
For( int j = 0; j < GetHeight(); ++j)
{
Static_cast<unit32*>(pb.data) // 数据获得,随便处理
}
}
Buffer->unlock(); //最后记得解锁。
- OGRE 硬件缓冲区(硬件缓存)
- OGRE 硬件缓冲区(硬件缓存)
- OGRE 硬件缓冲区(硬件缓存)
- OGRE 硬件缓冲区(硬件缓存) .
- Ogre中通过操作硬件缓存来设置透明度
- 【转】硬件像素缓存
- Android帧缓冲区(Frame Buffer)硬件抽象层
- 硬件
- 硬件
- 硬件
- 硬件
- 硬件
- 硬件
- 硬件知识——CPU缓存
- Ogre中将法线贴图和硬件蒙皮结合
- Ogre中将法线贴图和硬件蒙皮结合
- 硬件电路设计(转载)
- 硬件工程师(转)
- shell中变量
- android-修改TextView中部分文字的颜色
- adb shell退出
- crontab 里面这个居然是每分钟一次,无法理解 * */1 * * *
- 科学创造四阶段
- OGRE 硬件缓冲区(硬件缓存) .
- 繁杂小知识点
- 省市县三级联动(第三种方法)
- 北邮Google大牛本科研究生总结~
- html学习
- POJ 1088 滑雪
- 个人对Web前端的理解
- c#网页开发学习(一)
- java.lang.UnsatisfiedLinkError: no XXX in java.library.path .