18

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

  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()to的结果。声明返回一个:ByteBufferglMapBufferRange()Buffer

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

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

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

4

1 回答 1

6

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

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

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

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

或者您可以使用更精细的反射,从调用getClass()返回的缓冲区开始。下一个问题当然是如果返回的缓冲区不是ByteBuffer. 这真的是唯一对我有意义的类型。

于 2015-04-29T02:50:50.140 回答