Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

glMapBufferRange returning all zeros in Android

I am having trouble reading out from a buffer mapped with glMapBufferRange

If I simply put some data in a buffer

    // 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);

Generate a Array Buffer in GL and fill it with the data

    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");

When I map the buffer using glMapBufferRange and read the results

    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);

The logcat reads all zeros

D/TransformFeedback﹕ pre-run input values = 0.000000 0.000000 0.000000 0.000000 0.000000

No other errors are generated and I am not really sure what else to check. I have tried GLES30.glCopyBufferSubData(GLES30.GL_ARRAY_BUFFER, GLES30.GL_COPY_READ_BUFFER, 0, 0, bufferLength); and mapping GL_COPY_READ_BUFFER and gotten the same results.

I am testing on a Nexus 6 which supports OpenGL ES 3.1 so this functionality should be present.

This question suggests removing the OPENGL_FORWARD_COMPAT hint in glfw, could there be something similar that needs to happen in MyGLSurfaceView?

like image 890
HPP Avatar asked Jan 22 '26 11:01

HPP


1 Answers

This looks like a byte order problem when you read back the data. The data will be in native byte order, while Java assumes by default that data in buffers is big endian. Since most architectures are little endian these days, that's the opposite of what you need.

To correct for this in a way that will work for both big and little endian architectures, you can do the following:

ByteBuffer byteBuf = (ByteBuffer)mappedBuffer;
byteBuf.order(ByteOrder.nativeOrder());
FloatBuffer floatBuf = byteBuf.asFloatBuffer();

Then when you read from floatBuf, you should get the correct values.

like image 89
Reto Koradi Avatar answered Jan 25 '26 00:01

Reto Koradi