glMapBufferRange возвращает все нули в Android
У меня проблемы с чтением из буфера, сопоставленного с glMapBufferRange
Если я просто положу некоторые данные в буфер
// Create input VBO and vertex format
int bufferLength = 5 * 4; //5 floats 4 bytes each
FloatBuffer data = ByteBuffer.allocateDirect(bufferLength)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
float[] floatData = { 1.0f, 4.0f, 9.0f, 16.0f, 25.0f };
data.put(floatData).position(0);
Создайте массив массивов в GL и заполните его данными
int[] vbo = new int[1];
GLES30.glGenBuffers(1, vbo, 0);
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[0]);
GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, bufferLength, data, GLES30.GL_STATIC_DRAW);
MyGLRenderer.checkGlError(TAG + " glBufferData GL_ARRAY_BUFFER");
Когда я сопоставляю буфер с помощью glMapBufferRange
и прочитайте результаты
Buffer mappedBuffer = GLES30.glMapBufferRange(GLES30 .GL_ARRAY_BUFFER,
0, bufferLength, GLES30.GL_MAP_READ_BIT);
if (mappedBuffer!=null){
FloatBuffer transformedBuffer = ((ByteBuffer) mappedBuffer).asFloatBuffer();
MyGLRenderer.checkGlError(TAG + " glMapBufferRange");
Log.d(TAG, String.format("pre-run input values = %f %f %f %f %f\n", transformedBuffer.get(),
transformedBuffer.get(), transformedBuffer.get(), transformedBuffer.get(), transformedBuffer.get()));
transformedBuffer.position(0);
}
GLES30.glUnmapBuffer(GLES30.GL_ARRAY_BUFFER);
LogCat читает все нули
D/TransformFeedback﹕ pre-run input values = 0.000000 0.000000 0.000000 0.000000 0.000000
Другие ошибки не генерируются, и я не совсем уверен, что еще нужно проверить. я пытался GLES30.glCopyBufferSubData(GLES30.GL_ARRAY_BUFFER, GLES30.GL_COPY_READ_BUFFER, 0, 0, bufferLength);
и отображение GL_COPY_READ_BUFFER и получил те же результаты.
Я тестирую на Nexus 6, который поддерживает OpenGL ES 3.1, поэтому эта функциональность должна присутствовать.
Этот вопрос предлагает удалить подсказку OPENGL_FORWARD_COMPAT в glfw, может ли быть что-то похожее, что должно произойти в MyGLSurfaceView?
2 ответа
Это выглядит как проблема порядка байтов, когда вы читаете данные обратно. Данные будут в собственном байтовом порядке, в то время как Java по умолчанию предполагает, что данные в буферах имеют порядок байтов. Поскольку в наши дни большинство архитектур не имеют порядкового номера, это противоположно тому, что вам нужно.
Чтобы исправить это способом, который будет работать как для больших, так и для младших порядковых архитектур, вы можете сделать следующее:
ByteBuffer byteBuf = (ByteBuffer)mappedBuffer;
byteBuf.order(ByteOrder.nativeOrder());
FloatBuffer floatBuf = byteBuf.asFloatBuffer();
Затем, когда вы читаете из floatBuf
, вы должны получить правильные значения.
Большое спасибо Рето Коради, если кто-то захочет оставить ответ, я отмечу его как правильный.
Кастинг был неверным. Должен быть в порядке LITTLE_ENDIAN:
ByteBuffer transformedBuffer = ((ByteBuffer) mappedBuffer);
transformedBuffer.order(ByteOrder.LITTLE_ENDIAN);
Log.d(TAG, String.format("pre-run input values = %f %f %f %f %f\n", transformedBuffer.getFloat(),
transformedBuffer.getFloat(), transformedBuffer.getFloat(),
transformedBuffer.getFloat(), transformedBuffer.getFloat()));