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

时间:2015-04-28 13:46:23

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

我使用Android上的OpenGL-ES 3.0中的template <typename T> typename MyClass<T>::FunctionType MyClass<T>::funcObj = []{return new T();}; 工作代码,如下所示:

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()的结果。 ByteBufferdeclared to return a Buffer

  

glMapBufferRange()

在我的测试平台上,该函数返回public static Buffer glMapBufferRange (int target, int offset, int length, int access)的子类,因此转换工作正常,但对支持OpenGL-ES 3+的所有平台或Android版本进行此假设似乎不太安全。虽然看起来很合理,但我没有找到任何保证它的文档,如果保证它似乎应该声明函数返回ByteBuffer

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

1 个答案:

答案 0 :(得分:6)

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

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

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

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

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