在Android glMapBufferRange()/ Java的
我一直在使用glMapBufferRange()
从Android上的OpenGL-ES 3.0,看起来像这样的工作代码的安全使用:在Android glMapBufferRange()/ Java的
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
所以剧组工作的子类,但做这种假设适用于所有平台和Android版本支持OpenGL-ES 3+没有按看起来很安全。虽然看起来合理,但我还没有找到任何保证它的文档,并且如果它被保证,似乎函数应该被声明为返回ByteBuffer
。
什么是使用由glMapBufferRange()
返回的Buffer
的正确方法(最好由文档支持)?
正如您已经发现的那样,文档缺乏。但是仍然有一个相当确凿的参考:OpenGL Java绑定的实现是公共Android源代码的一部分。
如果你看一下JNI包装器glMapBufferRange()
,这是文件glMapBufferRange.cpp在执行中,可以看到的是,缓冲区通过调用一个名为NewDirectByteBuffer()
功能分配。基于此,假设缓冲区确实是ByteBuffer
似乎是安全的。
虽然供应商可以更改Android代码,但似乎很少有人会改变Java绑定的行为(除了可能修复错误)。如果您关注的是,实现可以在改变后的Android版本,你当然可以使用标准的Java类型检查:
Buffer buf = glMapBufferRange(...);
ByteBuffer byteBuf = null;
if (buf instanceof ByteBuffer) {
byteBuf = (ByteBuffer)buf;
}
或者你可以使用更复杂的反射,开始调用返回的缓冲区getClass()
。下一个问题当然是你如果返回的缓冲区不是ByteBuffer
。这真的是唯一对我有意义的类型。
+1即将实施。然而,至少在理论上实施可能会改变。有没有一种方法可以实际使用'glMapBufferRange()'而不用假设实现?或者这个函数是错误地指定的? – rhashimoto
@rhashimoto我添加了一些内容。但那一部分已经很清楚了。 –
我想大多数人没有选择使用ES 3.0+或通过JNI做任何严肃的OpenGL。我为更多曝光开了奖金。 – rhashimoto