繁体   English   中英

glMapBufferRange() 使用 TrasnformFeedback 在 Android OpenGLES 3.0 中返回全零

[英]glMapBufferRange() returns all zeros in Android OpenGLES 3.0 using TrasnformFeedback

更新:这是现在工作和要点 感谢雷托

我正在按照此示例开发转换反馈的 Android 实现。 运行得很好,没有任何错误,但是在使用glMapBufferRange()读取 TransformFeedback 缓冲区时,我得到了全零

import android.opengl.GLES30;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

/**
 * Created by izzy on 6/24/15.
 */
public class TransformFeedback {
    private final String TAG = "TransformFeedback";


// Vertex shader
private final String vertexShaderSrc =
        "#version 300 es \n" +
        "in float inValue;\n" +
        "out float outValue;\n" +

        "void main() {\n" +
        "    outValue = sqrt(inValue);\n" +
        "}";

private final String fragmentShaderCode =
        "#version 300 es \n" +
        "precision mediump float;\n" +
        "in float outValue;\n" +
        "out vec4 fragColor;\n" +
        "void main() {\n" +
        "  fragColor = vec4(outValue,outValue,outValue,1.0);\n" +
        "}";

private final int mProgram;


public TransformFeedback(){

    // Compile shader
    int vertexShader = MyGLRenderer.loadShader(GLES30.GL_VERTEX_SHADER,
            vertexShaderSrc);

    int fragmentShader =  MyGLRenderer.loadShader(GLES30.GL_FRAGMENT_SHADER,
            fragmentShaderCode);

    // Create program and specify transform feedback variables
    mProgram = GLES30.glCreateProgram();
    GLES30.glAttachShader(mProgram, vertexShader);
    GLES30.glAttachShader(mProgram, fragmentShader);

    final String[] feedbackVaryings = { "outValue" };
    GLES30.glTransformFeedbackVaryings(mProgram, feedbackVaryings, GLES30.GL_INTERLEAVED_ATTRIBS);
    MyGLRenderer.checkGlError("glTransformFeedbackVaryings");

    GLES30.glLinkProgram(mProgram);
    int[] linkSuccessful = new int[1];
    GLES30.glGetProgramiv(mProgram, GLES30.GL_LINK_STATUS, linkSuccessful, 0);

    if (linkSuccessful[0] != 1){
        Log.d(TAG, "glLinkProgram failed");
    }
    MyGLRenderer.checkGlError(TAG + "glLinkProgram");



    GLES30.glUseProgram(mProgram);
    MyGLRenderer.checkGlError(TAG + "glUseProgram");


    // Create VAO
    int[] vao = new int[1];
    GLES30.glGenVertexArrays(1, vao, 0);
    GLES30.glBindVertexArray(vao[0]);
    MyGLRenderer.checkGlError(TAG + "glBindVertexArray");

    // Create input VBO and vertex format
    int bufferLength = 5 * 4; //5 floats 4 bytes each
    ByteBuffer bb = ByteBuffer.allocateDirect(bufferLength);
    FloatBuffer data = bb.asFloatBuffer();
    float[] floatData = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
    data.put(floatData);
    data.position(0);


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

    int inputAttrib = GLES30.glGetAttribLocation(mProgram, "inValue");
    GLES30.glEnableVertexAttribArray(inputAttrib);
    GLES30.glVertexAttribPointer(inputAttrib, 1, GLES30.GL_FLOAT, false, 0, 0);
    MyGLRenderer.checkGlError(TAG + "glVertexAttribPointer");


    // Create transform feedback buffer
    int[] tbo = new int[1];
    GLES30.glGenBuffers(1, tbo, 0);
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, tbo[0]);
    GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, bufferLength, null, GLES30.GL_STATIC_READ);

    // Perform feedback transform
    GLES30.glEnable(GLES30.GL_RASTERIZER_DISCARD);

    GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo[0]);
    MyGLRenderer.checkGlError(TAG + "glBindBufferBase");

    GLES30.glBeginTransformFeedback(GLES30.GL_POINTS);
    GLES30.glDrawArrays(GLES30.GL_POINTS, 0, 5);
    GLES30.glEndTransformFeedback();

    GLES30.glDisable(GLES30.GL_RASTERIZER_DISCARD);

    GLES30.glFlush();
    MyGLRenderer.checkGlError(TAG + "pre glMapBufferRange ");

    // Fetch and print results
    FloatBuffer transformedBuffer = ((ByteBuffer) GLES30.glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER,
            0, bufferLength, GLES30.GL_MAP_READ_BIT)).asFloatBuffer();
    MyGLRenderer.checkGlError(TAG + "glMapBufferRange");

    transformedBuffer.position(0);
    Log.d(TAG, String.format("%f %f %f %f %f\n", transformedBuffer.get(),
            transformedBuffer.get(), transformedBuffer.get(), transformedBuffer.get(), transformedBuffer.get()));
    transformedBuffer.position(0);
}
}

logcat 输出如下所示:

D/TransformFeedback﹕ 0.000000 0.000000 0.000000 0.000000 0.000000

根据这个问题,您可以将返回的缓冲区转换为字节缓冲区,所以我不相信转换是问题所在。 即使数据向后输出,如果着色器代码正确计算变换反馈变量,并且我正确链接变换反馈,它也不应该全为零。

弄清楚了,感谢Reto在这个问题上 输出实际上不是零。 它们是字节顺序相反的浮点数,即 4.6006E-41。 只需将映射缓冲区设置为本地顺序即可!

ByteBuffer bb = ((ByteBuffer) mappedBuffer);
bb.order(ByteOrder.nativeOrder());
FloatBuffer transformedData = bb.asFloatBuffer();

Log.d(TAG, String.format("output values = %f %f %f %f %f\n", transformedData.get(),
                transformedData.get(), transformedData.get(),
                transformedData.get(), transformedData.get()));

完整的工作代码在要点上

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM