java - 在 Android/Java 上安全使用 glMapBufferRange()

标签 java android opengl-es opengl-es-3.0

我在 Android 上使用来自 OpenGL-ES 3.0 的 glMapBufferRange() 的工作代码如下所示:

  glBindBuffer(GL_ARRAY_BUFFER, myVertexBufferName);
  glBufferData(GL_ARRAY_BUFFER, myVertexBufferSize, null, GL_STATIC_DRAW);
  ByteBuffer mappedBuffer = (ByteBuffer)glMapBufferRange(
    GL_ARRAY_BUFFER,
    0, myVertexBufferSize,
    GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

  // [fill buffer...]

  glUnmapBuffer(GL_ARRAY_BUFFER);

我的问题是关于在第三行将 glMapBufferRange() 的结果向下转换为 ByteBufferglMapBufferRange()declared to return a Buffer :

public static Buffer glMapBufferRange (int target, int offset, int length, int access)

在我的测试平台上,该函数返回 ByteBuffer 的子类,因此该转换可以工作,但对支持 OpenGL-ES 3+ 的所有平台或 Android 版本做出此假设似乎并不安全。虽然看起来很合理,但我还没有找到任何保证它的文档,如果它得到保证,似乎该函数应该被声明为返回 ByteBuffer

使用 glMapBufferRange() 返回的 Buffer 的正确方法是什么(最好有文档支持)?

最佳答案

正如您已经发现的那样,缺少文档。但仍然有一个相当确凿的引用资料:OpenGL Java 绑定(bind)的实现是公共(public) Android 源代码的一部分。

如果您查看 glMapBufferRange() 的 JNI 包装器的实现,它位于文件 glMapBufferRange.cpp 中。 ,可以看到缓冲区是通过调用一个名为NewDirectByteBuffer()的函数来分配的。基于此,假设缓冲区确实是一个 ByteBuffer 似乎是安全的。

虽然供应商可以更改 Android 代码,但似乎任何人都不太可能更改 Java 绑定(bind)的行为(可能修复错误除外)。如果您担心在以后的 Android 版本中实现可能会发生变化,您当然可以使用标准的 Java 类型检查:

Buffer buf = glMapBufferRange(...);
ByteBuffer byteBuf = null;
if (buf instanceof ByteBuffer) {
    byteBuf = (ByteBuffer)buf;
}

或者您可以使用更精细的反射,首先在返回的缓冲区上调用 getClass()。下一个问题当然是如果返回的缓冲区不是 ByteBuffer 该怎么办。它真的是唯一对我有意义的类型。

关于java - 在 Android/Java 上安全使用 glMapBufferRange(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29921348/

相关文章:

android - 在 ContentValues 中查询

Android - 使用 Theme.AppCompat 不显示操作栏

android - glDrawElements 在设备上崩溃,在模拟器上运行良好

javascript - WebGL 片段着色器构造函数错误 - 参数太多

java - HQL:如何通过id查找子集合中的项目

java - facebook webhook 验证失败

java - 使用 Jackson 解析 ElasticSearch 输出

android - 在收到 Firebase 通知时打开应用 (FCM)

java - 用于在着色器 OpenGL ES 2.0/3.0 中存储常量值的统一值

java - 每台计算机的独特之处是什么