Безопасное использование glMapBufferRange() на Android/Java
У меня есть рабочий код с помощью glMapBufferRange()
из OpenGL-ES 3.0 на Android, который выглядит следующим образом:
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
:
public static Buffer glMapBufferRange (int target, int offset, int length, int access)
На моей тестовой платформе функция возвращает подкласс ByteBuffer
, поэтому выполнение работ выполняется, но это предположение для всех платформ или версий Android, поддерживающих OpenGL-ES 3+, не кажется очень безопасным. Хотя это кажется разумным, я не нашел никакой документации, которая его гарантирует, и если бы это было гарантировано, кажется, что функция должна быть объявлена как возвращающая ByteBuffer
.
Каков правильный способ (желательно поддерживаемый документацией) использования Buffer
, возвращаемого glMapBufferRange()
?
Ответы
Ответ 1
Как вы уже нашли, документации не хватает. Но есть еще довольно убедительная ссылка: реализация привязок Java OpenGL является частью общедоступного исходного кода 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
. Это действительно единственный тип, который имеет для меня смысл.