Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/198.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java glMapBufferRange在Android中返回所有零_Java_Android_Opengl Es_Opengl Es 3.0 - Fatal编程技术网

Java glMapBufferRange在Android中返回所有零

Java glMapBufferRange在Android中返回所有零,java,android,opengl-es,opengl-es-3.0,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(

我无法从使用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_数组_BUFFER,GLES30.GL_COPY_读取_BUFFER,0,0,bufferLength)和映射GL\u COPY\u READ\u BUFFER并得到相同的结果

我正在测试支持OpenGLES3.1的Nexus6,所以应该有这个功能


这建议删除glfw中的OPENGL\u FORWARD\u COMPAT提示,MyGLSurfaceView中是否需要发生类似的事情?

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

铸造不正确。需要按小的顺序排列:

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

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

要以适用于大端和小端体系结构的方式对此进行纠正,可以执行以下操作:

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

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

您可以检查这些值是否完全为零,或者在打印时它们是否看起来像零吗?例如,记录比较值
==0.0f
的结果。我有一个理论…没错,先生,你是个天才!我假设您的理论是缓冲区需要翻转(或设置为大/小edian),欢迎您提供如何翻转的建议,我现在正在尝试解决这个问题
mappedBuffer.flip()
在尝试转换为浮动缓冲区(下溢)时导致崩溃。第一个元素的值为4.6006E-41与genius无关,我几周前碰巧遇到了同样的问题。在我的例子中,缓冲区包含整数。所以在一些最初的困惑之后,我很快就明白了我得到的是字节交换数据。是的,浮点数很奇怪,因为它们都是零。我想他们可能在某个时候顺序不对,但没有跟进检查。有了OpenGL,我可以做很多事情,但我不知道我在搜索错误的地方。我真的很想吻你,我已经处理这件事好几天了,本来打算放弃,去做其他的事情,但是如果我这么做,这个功能要到下一个周期才能进入我的应用程序,可能是一年或两年。我认为使用
nativeOrder()
而不是
LITTLE\u ENDIAN
更干净。然后它将在所有体系结构上工作。看看我的答案。