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

时间:2022-11-07
本文介绍了在 Android/Java 上安全使用 glMapBufferRange()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我在 Android 上使用来自 OpenGL-ES 3.0 的 glMapBufferRange() 的工作代码如下所示:

I have working code using glMapBufferRange() from OpenGL-ES 3.0 on Android that looks like this:

  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() 是 声明返回一个Buffer:

My question is about downcasting the result of glMapBufferRange() to ByteBuffer on the third line. glMapBufferRange() is declared to return a Buffer:

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

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

On my test platform the function returns a subclass of ByteBuffer so the cast works, but making this assumption for all platforms or Android versions supporting OpenGL-ES 3+ doesn't seem very safe. Although it seems reasonable, I haven't found any documentation that guarantees it, and if it were guaranteed it seems like the function should be declared as returning ByteBuffer.

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

What is the correct way (preferably supported by documentation) of using the Buffer returned by glMapBufferRange()?

推荐答案

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

As you already found, the documentation is lacking. But there is still a fairly conclusive reference: The implementation of the OpenGL Java bindings is part of the public Android source code.

如果您查看 glMapBufferRange() 的 JNI 包装器的实现,它位于文件 glMapBufferRange.cpp,可以看到调用NewDirectByteBuffer()函数分配了缓冲区.基于此,假设缓冲区确实是一个 ByteBuffer 似乎是安全的.

If you look at the implementation of the JNI wrapper for glMapBufferRange(), which is in the file glMapBufferRange.cpp, you can see that the buffer is allocated by calling a function named NewDirectByteBuffer(). Based on this, it seems safe to assume that the buffer is indeed a ByteBuffer.

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

While vendors can change the Android code, it seems very unlikely that anybody would change the behavior of the Java bindings (except maybe to fix bugs). If you are concerned that the implementation could change in later Android versions, you can certainly use a standard Java type check:

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

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

Or you could use more elaborate reflection, starting with calling getClass() on the returned buffer. The next question is of course what you do if the returned buffer is not a ByteBuffer. It's really the only type that makes sense to me.

这篇关于在 Android/Java 上安全使用 glMapBufferRange()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一条:使用片段着色器和 GL_LINE_STRIP 在 OpenGL GLES20 android 中绘制简单的虚线或虚线 下一条:浮点运算不能产生精确的结果

相关文章

最新文章