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

我的工作代码使用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()的结果转换为ByteBuffer。 glMapBufferRange()是declared to return a Buffer

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

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

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

正如您已经找到的,文档不足。但仍然有一个相当确定的参考:OpenGL Java绑定的实现是公共Android源代码的一部分。

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

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

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

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

http://stackoverflow.com/questions/29921348/safe-usage-of-glmapbufferrange-on-android-java

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在Android / Java上安全使用glMapBufferRange()