1
votes

I am currently trying out Transform Feedback with a Geometry Shader. The Geometry Shader takes a Triangle, makes a Prism out of it and also puts a tetraeder on top of it (Think of it like an Obelisk but only with 3 instead of 4 sides).

I get the right result using Transform Feedback once. However i wanted to create additional Geometry with Transform Feedback. I wanted to do the Geometry Shader Process for each of the Triangles of the Tetraeder.

Result after first Pass Result after first Pass

Result after second Pass Result after second Pass So instead of the black part going to infinity in the second pass, there should have been another of these branches that you can see left and right, but that one towards the camera.

What am i doing wrong here? I am not sure how to handle the always increasing size of data for the two Vertex Buffer Objects and i am probably doing something wrong there. Help would be appreciated.

Transform Feedback before the Main window Loop:

glUseProgram(transformShaderProgram);

glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TBO);
glBindVertexArray(transformVAO);
glEnable(GL_RASTERIZER_DISCARD);

glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, tfQuery);
glBeginTransformFeedback(GL_TRIANGLES);
glDrawArrays(GL_TRIANGLES, 0, 3);
glEndTransformFeedback();
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
glDisable(GL_RASTERIZER_DISCARD);

GLuint numPrimitivesWritten = 0;
glGetQueryObjectuiv(tfQuery, GL_QUERY_RESULT, &numPrimitivesWritten);
printf("Number of PrimitivesWritten %i\n", numPrimitivesWritten);

Transform Feedback during the main window Loop:

glUseProgram(feedbackShaderProgram);
while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();
    CalcDeltaTime();
    doMovement();

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (doTransformFeedback && (currentNumberOfTransformFeedback < maxNumberOfTransformFeedback)) {
        glUseProgram(transformShaderProgram);

        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TBO);
        glBindVertexArray(feedbackVAO);
        glEnable(GL_RASTERIZER_DISCARD);

        glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, tfQuery);
        glBeginTransformFeedback(GL_TRIANGLES);
        glDrawArrays(GL_TRIANGLES, 0, numPrimitivesWritten * 5);
        glEndTransformFeedback();
        glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
        glDisable(GL_RASTERIZER_DISCARD);

        GLuint numPrimitivesWritten2 = 0;
        glGetQueryObjectuiv(tfQuery, GL_QUERY_RESULT, &numPrimitivesWritten2);
        numPrimitivesWritten += numPrimitivesWritten2;

        doTransformFeedback = false;
        currentNumberOfTransformFeedback++;
        glUseProgram(feedbackShaderProgram);
    }
    glBindVertexArray(feedbackVAO);
    glDrawArrays(GL_TRIANGLES, 0, numPrimitivesWritten * 5 );
    glBindVertexArray(0);

    glfwSwapBuffers(window);
}
1

1 Answers

3
votes

It's OK to perform a transform feedback operation into the same buffer that you're reading vertex data from. It's not OK to perform a transform feedback operation on top of the vertex data you're reading from.

And that's essentially what you're doing in the second operation.

What you need to do is use glBindBufferBase to offset the feedback buffer in the second TF operation, so that it's writing to fresh vertex data.

The other thing you're doing wrong is that you're passing the wrong triangles to your feedback operation. From your description of what you want, you only want to execute the process on the topmost triangles of the obelisk. But you pass the whole thing in your TF rendering code. You need to isolate the specific triangles you want to expand and only render them.

Transform feedback will write triangles in the order that you output them. So you need to isolate those specific triangles and only perform feedback operations on them.