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()));
Другие вопросы по тегам