問題描述
我在 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()的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!