Opengl Transform feedback made correctly on Android

372 Views Asked by At

I have been struggling to create a working transform feedback on android. So far, the closest I have gotten had a similar issue to this downvoted question: https://stackoverflow.com/questions/41066101/transform-feedback-altering-render-result

What I want to create:

Render from a vertex buffer object into a transform feedback. Then render from the transform feedback's buffer with a final drawing shader.

How I understand this whole concept:

I understand the way the program is linked with the varyings (I have followed this example: https://gist.github.com/hpp/d2d26adc5987002eb520) On Android, you have to provide a 'dummy' fragment shader, otherwise the program linking will fail without message.

After having a linked program, these are the steps: (code is in java)

  1. Create a VBO to read data from

    int[] vbo = new int[1];
    glGenBuffers(1, vbo, 0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, bufferLength, data, GL_STATIC_READ);
    
  2. Create the transform feedback buffer

    int[] tbo = new int[1];
    glGenBuffers(1, tbo, 0);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo[0]);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferLength, null, GL_DYNAMIC_COPY);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo[0]);
    
  3. Every time I would like to make my calculations, I call something like this:

    glUseProgram(calculationShaderProgram);
    // For all input variables:
    glEnableVertexAttribArray(inputAttrib);
    glVertexAttribPointer(...
    
    // To bind the transform feedback buffer as the destination
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfo[0]);
    
    glEnable(GL_RASTERIZER_DISCARD);
    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, vertexCount);
    glEndTransformFeedback();
    glDisable(GL_RASTERIZER_DISCARD);
    
    glFinish(); // I know this is slow to call, but for simplicity's sake
    
  4. After that, I should be able to draw the content of the buffer:

    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo[0]);
    
    glUseProgram(drawShaderProgram);
    // For all input variables:
    glEnableVertexAttribArray(inputAttrib);
    glVertexAttribPointer(...
    
    // Set uniforms ...
    glDrawArrays(GL_POINTS, 0, vertexCount); // There is no glDrawTransformFeedback on android
    

Now, my questions are:

  • Is there something inherently wrong in the process?
  • Is there any reason why the calculation part messes up my device's screen, even if I don't draw anything? ( It shows random colors or icons updated by android like battery and network)
  • Is using a vertex array object the same with GL_TRANSFORM_FEEDBACK_BUFFER as it is with GL_ARRAY_BUFFER?
1

There are 1 best solutions below

0
On

It took some time, but here is the solution. I'll leave this here because these parts were not explained properly on any OpenGL related books that is available.

  1. When drawing from a transform feedback buffer (step 4 above), it does not matter if it works as transform feedback buffer or not, you have to bind it as GL_ARRAY_BUFFER, just like you would draw from a vertex buffer object.

    glBindBuffer(GL_ARRAY_BUFFER, tbo[0]);
    
  2. When using the default Framebuffer,

    glBindFrameBuffer(GL_FRAMEBUFFER, 0);
    

    or no setup at all, you are not allowed to use

    glEnable(GL_RASTERIZER_DISCARD);
    // Draw to Transform feedback
    // ...
    glDisable(GL_RASTERIZER_DISCARD);
    

    (in step 3) without calling first

    glClear(GL_COLOR_BUFFER_BIT);
    

    otherwise you will see random patterns as the background. One glClear before each draw cycle is not enough.