You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 04:45:11