glMapBufferRange在Android中返回所有零

时间:2015-06-29 18:55:13

标签: java android opengl-es opengl-es-3.0

我无法从使用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并获得了相同的结果。

我正在测试支持OpenGL ES 3.1的Nexus 6,因此应该存在此功能。

这个question建议删除glfw中的OPENGL_FORWARD_COMPAT提示,是否有类似需要在MyGLSurfaceView中发生的事情?

2 个答案:

答案 0 :(得分:1)

当您回读数据时,这看起来像是一个字节顺序问题。数据将以本机字节顺序排列,而Java默认情况下假定缓冲区中的数据为big endian。由于现在大多数架构都是小端,这与你需要的相反。

要以适用于大端和小端架构的方式纠正此问题,您可以执行以下操作:

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

然后当您从floatBuf读取时,您应该获得正确的值。

答案 1 :(得分:0)

非常感谢Reto Koradi,如果有人想留下答案,我会将其标记为正确。

施法不正确。需要以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()));