Android平台OpenGL ES 3.1下GL_MAP_PERSISTENT_BIT的使用方法
Android OpenGL ES 3.1 持久映射缓冲区使用指南
1 缺失常量的解决方法
你提到的扩展名称是正确的,即GL_EXT_buffer_storage。Android SDK 内置的GLES31、GLES31Ext类未包含GL_MAP_PERSISTENT_BIT的定义,是因为该常量属于扩展专属字段,你可以手动定义该常量及关联的常用扩展常量:
// EXT_buffer_storage 扩展相关常量定义 private static final int GL_MAP_PERSISTENT_BIT_EXT = 0x0040; private static final int GL_MAP_COHERENT_BIT_EXT = 0x0080; private static final int GL_DYNAMIC_STORAGE_BIT_EXT = 0x0100;
2 完整使用步骤
- 步骤1:提前确认设备支持
GL_EXT_buffer_storage扩展,你已经通过glGetString(GL_EXTENSIONS)查询确认,可跳过该步。 - 步骤2:创建持久化缓冲区,不要使用传统的
glBufferData,改用扩展提供的glBufferStorageEXT接口分配不可变存储的缓冲区:
// 绑定目标缓冲区 glBindBuffer(GL_ARRAY_BUFFER, yourBufferId); // 分配不可变存储,标志位需包含后续映射需要的权限 GLES31Ext.glBufferStorageEXT( GL_ARRAY_BUFFER, bufferSize, // 缓冲区总大小 null, // 初始数据为空,后续通过映射写入 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT );
- 步骤3:一次映射获取持久指针,该操作仅需执行一次,不需要每帧调用映射/解除映射:
// 全局存储该缓冲区对象,后续每帧直接写入 ByteBuffer persistentBuffer = (ByteBuffer) glMapBufferRange( GL_ARRAY_BUFFER, 0, bufferSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT );
- 步骤4:每帧更新逻辑,直接向
persistentBuffer中写入数据即可,写入完成后可直接发起绘制调用,无需额外操作:
注意:如果创建缓冲区时未添加
GL_MAP_COHERENT_BIT_EXT标志,每次写入完成后需要调用glFlushMappedBufferRange指定修改的区间,保证GPU能读取到最新数据。
3 注意事项
- 持久映射的缓冲区存储是不可变的,使用期间不能调用
glBufferData、glBufferStorageEXT修改缓冲区的大小或属性,否则已映射的指针会失效。 - 需注意CPU/GPU同步问题,避免CPU写入某段数据的同时GPU读取该段数据,可采用多缓冲机制或同步栅栏(Fence)规避读写冲突。
内容的提问来源于stack exchange,提问作者user1300214
相关产品推荐
相关产品推荐

