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)
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);
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]);
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
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?
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.
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.
When using the default Framebuffer,
or no setup at all, you are not allowed to use
(in step 3) without calling first
otherwise you will see random patterns as the background. One glClear before each draw cycle is not enough.