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

旧时模样 提交于 2019-12-11 03:29:06

问题


UPDATE: This is working and up on gist now! Thanks Reto

I am working on an Android implementation of transform feedback following this example. runs pretty well without any errors, but I am getting all zeros out when reading the TransformFeedback buffer with glMapBufferRange()

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

The logcat output looks like this:

D/TransformFeedback﹕ 0.000000 0.000000 0.000000 0.000000 0.000000

according to this question you may cast the returned buffer to a bytebuffer, so I do not believe the casting is the problem. Even if the data is coming out backwards it shouldn't be all zeros if the shader code is computing the transform feedback variable correctly, and I am linking the transform feedback correctly.


回答1:


Figured it out, thanks to Reto on this question. The outputs are actually not zeros. They are floats in reversed byte order, i.e. 4.6006E-41. Simply set the mapped buffer to native order and whallah!

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

Complete working code is up on gist



来源:https://stackoverflow.com/questions/31095601/glmapbufferrange-returns-all-zeros-in-android-opengles-3-0-using-trasnformfeed

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