缓存对象——OpenGL ES Common/Common-Lite 规范(版本 1.1.12)

2.9缓存对象

之前提到的顶点数据数组都保存在客户端的内存中,而有时候理想保存使用频繁的客户端数据(例如顶点数组数据)的位置是高性能的服务器内存。GL缓存对象提供了一套机制,使客户端可以分配,初始化和渲染服务器端内存。

缓存对象的名字使用是无符号整数,0被GL保留。一个缓存对象通过绑定一个未使用的名字到ARRAY_BUFFER的来创建。绑定命令为:

void BindBuffer(enum target, uint buffer);

此时target被设置为ARRAY_BUFFER,buffer被设置为一个未使用的名字。命令执行的结果将会创建一个新的状态向量表示一个缓存对象,这个缓存对象的缓存区大小为0,表2.5中列出了该对象的状态值。

NameTypeInitial ValueLegal Values
BUFFER_SIZEinteger0any non-negative integer
BUFFER_USAGEenumSTATIC_DRAWSTATIC_DRAW,DYNAMIC_DRAW

表2.5 缓存对象的参数和它们的值

BindBuffer也可以用于绑定已存在的缓存对象。如果绑定成功,对于被绑定的缓存对象不会任何改变,之前的绑定目标将会被断开。

当一个缓存对象被绑定,GL对目标的操作将会影响被绑定的缓存对象,查询目标所绑定的缓存对象,将会返回被绑定对象的状态。

初始化时,0会被绑定到ARRAY_BBFFER。0表示没有任何缓存对象,所以客户端尝试修改或者查询ARRAY_BUFFER的缓存对象的状态将会产生GL错误。

删除缓存对象的命令为

void DeleteBuffers(sizei n, const uint *buffers);

buffers包含将n个将被删除的缓存对象的名字。命令执行后,缓存对象被删除,它的名字将重新设置为未使用。如果buffers中有未使用的名字,将会被忽略。

命令

void GenBuffers(sizei n, uint *buffers);

在buffers中返回 前n个未使用缓存对象的名字。使用了GenBuffers后,这些名字将被标识为已使用,但是,正如他们未被使用一样,只有当它们被第一次绑定后,它们才获得缓存状态。

当一个缓存对象被绑定,任何GL操作对该对象的操作,都会影响所有绑定它的对象。如果一个缓存对象被删除(在某个线程中,调用了DeleteBuffers命令),所有当前环境中绑定该缓存的对象的将被重置,其绑定的缓存对象为0。其他环境中的绑定缓存的对象和其他的线程不会受到影响。尝试在其他线程中使用一个被删除的缓存会产生未定义的结果,包括不局限在GL中的错误和渲染破坏。在其他线程或者环境中使用一个被删除的缓存可能不会报错,然而,结果可能导致程序被终止。

一个缓存对象通过调用一下命令来执行数据创建和初始化

void BufferData(enum target, sizeiptr size, const void *data, enum usage);

如果target设置为ARRAY_BUFFER,size设置数据的大小(按照基础机器单元计算),data指向客户端内存中的源数据。如果data是非空的,源数据将被拷贝到缓存对象的数据区中,如果data为空,则缓存对象的数据区内容将是未定义的。

usage定义了保存数据的使用类型,此枚举类型有2个值。

STATIC_DRAW 保存的数据内容只被程序定义一次,GL绘制命令可以使用多次。

DYNAMIC_DRAW 保存的数据内容将被程序重复定义,GL绘制命令可以使用多次。

usage仅仅提供了一个运行建议,定义的类型值不会强制实际的数据存储方式。

BufferData删除任何存在的保存数据,同时设置缓存对象的状态变量的值,这些值,列举在表2.6中。

NameValue
BUFFER_SIZEsize
BUFFER_USAGEusage

表 2.6:缓存对象初始化状态。

客户端必须按照客户端平台的需求对齐数据元素,一个额外的基本需求是一个N个基本机器单元组成的数据的缓存的实际偏移值,必须是N的倍数。

如果GL不能够创建一个请求大小的数据,将会产生OUT_OF_MEMORY错误。

去修改缓存对象数据区中的一些数据或者全部数据,客户端可以使用命令

void BufferSubData(enum target, intptr offset, sizeiptr size, const void *data);

target被设置为ARRAY_BUFFER.。offset和size指明将被替换的数据在缓存中的位置。data定义了size(按照基本机器单元计算)大小的一个客户端内存,该块内存保存的内容将替换缓存对象中指定范围数据。如果offset或者size小于0,或者offset+size比BUFF_SIZE的大,都会导致一个INVALID_VALUE错误。

2.9.1 缓存对象中的顶点数组

保存在缓存对象中的顶点数组数据块和客户端顶点数组使用同样的格式和布局选项。

客户端状态与每个顶点数组的类型相关,包括点的缓存对象。定义顶点数组位置和组织的命令 复制缓存对象的名字(绑定到ARRAY_BUFFER)到绑定点。例如,NormalPointer命令复制ARRAY_BUFFER_BINDING的值(绑定到ARRAY_BUFFER的缓存对象的名字)到客户端状态变量    NORMAL_ARRAY_BUFFER_BINDING。

如果数组绑定的缓存不为零,渲染命令DrawArrays和DrawElements将操作缓存区中的先前定义的顶点数组数据。当一个数组源自缓存对象,这个数组的指针值常用于计算缓存中数据区的偏移量。这个偏移通过指向数组的指针减去一个空指针来计算,所有的指针都是指向基本机器单元的指针。

在一个单独的渲染操作中,顶点数组可以使用客户端内存和各种缓存对象的任意组合。

当一个缓存对象绑定后,重新使用客户端顶点数组,可以调用命令BindBuffer(ARRAY_BUFFER, 0),然后可以使用先前的命令操作客户端的顶点数组指针。

2.9.2 缓存对象中的数组索引

保存在缓存对象中的数组索引块支持和客户端索引数组相同的操作格式。最初,0被绑定到ELEMENT_ARRAY_BUFFER, DrawElements命令需要indices参数指向数据源。

调用BindBuffer命令,并将target设置为ELEMENT_ARRAY_BUFFER,将绑定一个缓存对象到ELEMENT_ARRAY_BUFFER上。buffer将设置一个缓存对象的名字。如果没有一致的缓存对象存在,一个新缓存对象将被初始化。

命令BufferData和BufferSubData也可以设置target为ELEMENT_ARRAY_BUFFER。在这些情况下,和先前介绍的缓存对象的操作方式一样,只是buffer的被绑定的目标为ELEMENT_ARRAY_BUFFER。

当一个非0的缓存对象名被绑定到ELEMENT_ARRAY_BUFFER,DrawElements作用于缓存对象中的索引数组,并通过indices参数来计算缓存对象中的偏移,

缓存对象通过绑定一个未使用的名字到ARRAY_BUFFER或者ELEMENT_ARRAY_BUFFER创建,它们形式上相同的,但是GL可能使用不同方式的实现绑定的初始化。在某种情况下,通过在某些特殊的缓存对象中保存索引和数组对象和为绑定点创建这些缓存对象,可以优化性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值