Подтвердить что ты не робот

Безопасное использование 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()?

4b9b3361

Ответ 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. Это действительно единственный тип, который имеет для меня смысл.