2015-04-28 63 views
18

我一直在使用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的正确方法(最好由文档支持)?

回答

6

正如您已经发现的那样,文档缺乏。但是仍然有一个相当确凿的参考: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。这真的是唯一对我有意义的类型。

+0

+1即将实施。然而,至少在理论上实施可能会改变。有没有一种方法可以实际使用'glMapBufferRange()'而不用假设实现?或者这个函数是错误地指定的? – rhashimoto

+0

@rhashimoto我添加了一些内容。但那一部分已经很清楚了。 –

+0

我想大多数人没有选择使用ES 3.0+或通过JNI做任何严肃的OpenGL。我为更多曝光开了奖金。 – rhashimoto