【问题标题】:Safe usage of glMapBufferRange() on Android/Java在 Android/Java 上安全使用 glMapBufferRange()
【发布时间】:2015-07-07 10:01:23
【问题描述】:

我在 Android 上使用来自 OpenGL-ES 3.0 的 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() 的结果向下转换为ByteBufferglMapBufferRange()declared to return a Buffer

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • +1 用于执行。但是,至少在理论上,实施可能会发生变化。有没有办法在不对实现做出假设的情况下实际使用glMapBufferRange()?还是这个函数指定不正确?
    • @rhashimoto 我添加了一些内容。但这部分你可能已经很清楚了。
    • 我猜大多数人没有选择使用 ES 3.0+ 或通过 JNI 执行 OpenGL 来解决任何严重问题。我开了一个赏金以获得更多曝光。
    • 你可能想设置byteBuf.order(ByteOrder.nativeOrder()),我花了一段时间才弄清楚。
    猜你喜欢
    • 2015-09-16
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    相关资源
    最近更新 更多