Multiple Transform FeedBack

Hello,

I’m currently using Transform Feedback and it works very fine. But I’m not sure about my full understanding of it.

In fact, I meet a problem when I want to use 2 different Transform Feedback shaders. I explain: For instance, I would like to create 2 independant system of particles.

So I declare something like that:

// For the first system of particles
GLuint Program_1_ID = glCreateProgram();
glAttachShader(Program_1_ID, VertexShader_1_ID);
const char *varyings_1[] = {"lifetime_out"};
glTransformFeedbackVaryings(Program_1_ID, 1, varyings_1, GL_SEPARATE_ATTRIBS);
glLinkProgram(ProgramID);

// For the second system of particles
GLuint Program_2_ID = glCreateProgram();
glAttachShader(Program_2_ID, VertexShader_2_ID);
const char *varyings_2[] = {"lifetime_out", "velocity_out", "angle_out"};
glTransformFeedbackVaryings(Program_2_ID, 3, varyings_2, GL_SEPARATE_ATTRIBS);
glLinkProgram(ProgramID);

And to use these TFB:

// For the first one
glUseProgram(Program_1_ID );
glBindVertexArray(vao_1);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_0);
glEnable(GL_RASTERIZER_DISCARD);
glBeginTransformFeedback(GL_POINTS);
glDrawArrays(GL_POINTS, 0, nb_vertices);
glEndTransformFeedback();

// For the second one
glUseProgram(Program_2_ID );
glBindVertexArray(vao_2);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_1);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, vbo_2);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, vbo_3);
glEnable(GL_RASTERIZER_DISCARD);
glBeginTransformFeedback(GL_POINTS);
glDrawArrays(GL_POINTS, 0, nb_vertices);
glEndTransformFeedback();

But it dosen’t work and I’m not sure to understand why.
Is it because glTransformFeedbackVaryings affect the varyings at the same binding point to the GL_TRANSFORM_FEEDBACK target ?
In this case, how can I do ?

Regards
William

In what sense doesn’t it work? Are the buffers modified at all?

Have you checked for errors?

Do you need to add synchronisation? If you’re reading data back to client memory, this should automatically wait for the operation to complete (unless you use explicitly request an unsynchronised mapping). If you’re using the data as vertex attributes in subsequent commands, you need a memory barrier between the two.

Thank you for your reply.

In fact the two particles system are totaly separated. They have their own program shader, their own vbo, vao, vertex shader, fragment shader and vertex shader for TFB.
So I think I don’t need synchronisation.

When I declare only one of the 2 systems in my application, it works very well. The output buffers are correctly written. But when I declare in first, for instance:

GLuint Program_1_ID = glCreateProgram();
glAttachShader(Program_1_ID, VertexShader_1_ID);
const char *varyings_1[] = {"lifetime_out"};
glTransformFeedbackVaryings(Program_1_ID, 1, varyings_1, GL_SEPARATE_ATTRIBS);
glLinkProgram(ProgramID);
and then:
GLuint Program_2_ID = glCreateProgram();
glAttachShader(Program_2_ID, VertexShader_2_ID);
const char *varyings_2[] = {"lifetime_out", "velocity_out", "angle_out"};
glTransformFeedbackVaryings(Program_2_ID, 3, varyings_2, GL_SEPARATE_ATTRIBS);
glLinkProgram(ProgramID);

In this case, only the second one is working. And for the first one, the particles don’t move on the screen: I suppose the output buffer is not written (because this is the lifetime buffer of the particles),

So I supposed there is a confusion between the two declarations:

glTransformFeedbackVaryings(Program_1_ID, 1, varyings_1, GL_SEPARATE_ATTRIBS);

and

glTransformFeedbackVaryings(Program_2_ID, 3, varyings_2, GL_SEPARATE_ATTRIBS);

I thought the second command removes the first one…

But your reply seems to tell this is not a problem to proceed like that.
I checked for errors during compilation of shaders and the linking of the program, but no error appears.
Do you know where I could find an example with the using of 2 TFB ?

Regards
William

That wouldn’t be my first assumption. My first assumption would be that you’re doing something wrong when you’re actually invoking the transform feedback operation. Like maybe you’re not binding different buffers/ranges for the different operations or something.

Yes you are right.
If it is allowed to declare more than one TFB in the same time, so I’m probably doing something wrong.
i’m going to check my code.
Thank you !

The set of transform feedback varyings is a property of the program. With later versions of GLSL, that function is often unnecessary, as you can specify this information in the shader using the layout qualifiers xfb_buffer, xfb_offset and xfb_stride (the function is still useful to capture outputs for debugging without having to modify the shader).

All that glTransformFeedbackVaryings does is to store some information in the program object regarding where outputs should be stored if transform feedback is enabled when executing the program. Settings for different programs don’t interfere with each other.