glMapBufferRange returning all zeros in Android

房东的猫 提交于 2019-12-11 03:09:02

问题


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?


回答1:


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.




回答2:


Big thanks to Reto Koradi, if anyone wants to leave an answer I will mark it as correct.

The casting was incorrect. Needs to be in LITTLE_ENDIAN order:

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


来源:https://stackoverflow.com/questions/31123376/glmapbufferrange-returning-all-zeros-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!