CS 455 Presentation – Transform Feedback

[youtube http://www.youtube.com/watch?v=fDGc87Ik_PU&w=420&h=315]

Hello Everyone! We are Alex Ecker and Aaron Emmert and our presentation is on OpenGL’s Transform Feedback ability. Hopefully the video covered everything you need to know. If you want a copy of the slideshow in the video, you can grab a copy here!

We did plan an in-class exercise for everyone too! We know that by this time everyone’s code will be a little different so we decided to do a small coding project involving Java and OpenGL that everyone could follow easily. This small lab is based off of the tutorial here OpenGL Transform Feedback, we wanted to help everyone get this project set up while giving a real-life example of Transform Feedback.

This project is in Java as opposed to what we’ve been using with Visual Studio or Linux. We will set up this project to run on Windows systems using Eclipse.

The first step is to download our TransformFeedbackTest starter code. Unzip the files and import the existing project in to Eclipse and you will have code to work on. This Java code is using an external library called Lightweight Java Game Library (LWJGL). Everything you need should be set up, but if not you can find all the files you need in the starter code zip.

Now we will walk you through the steps to make this a full-blown Transform Feedback machine.

First:

In the initShader() method after the line “glAttachShader(shaderProgram, geometryShader);” enter the following

      glTransformFeedbackVaryings(shaderProgram, new CharSequence[]{"outPosition"}, GL_INTERLEAVED_ATTRIBS);

What this command does is it tells the transform feedback output what we want to save from the geometry shader. It is all stored in array of names that are followed by an enum. This controls how the data is going to be stored. This needs to be called before linking the program.

Second:

In the renderOutput() method insert this code above anything that is in there.

      glBindBuffer(GL_ARRAY_BUFFER, outputVBO);
      glEnableClientState(GL_VERTEX_ARRAY);
      glVertexPointer(2, GL_FLOAT, 0, 0);
      glDrawTransformFeedback(GL_POINTS, feedbackObject);
      glDisableClientState(GL_VERTEX_ARRAY);
      glBindBuffer(GL_ARRAY_BUFFER, 0);

What all of this does is prepare the points to be rendered.
First, it binds the Vertex Buffer Object.
After that, we set up the read positions from the output. Finally, we use a draw call (glDrawTransformFeedback) to draw all of our points.
This call is like the “glDrawArrays” call except it doesn’t involve the CPU to determine how many points we are using.

 

Third:

In the processPoints() method insert this code.

      glEnable(GL_RASTERIZER_DISCARD);

        glUseProgram(shaderProgram);

        glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, feedbackObject);
        glBeginTransformFeedback(GL_POINTS);
        {
            glBindBuffer(GL_ARRAY_BUFFER, inputVBO);
            glBufferData(GL_ARRAY_BUFFER, inputData, GL_STREAM_DRAW);

            glEnableVertexAttribArray(positionLocation);
            glVertexAttribPointer(positionLocation, 2, GL_FLOAT, false, 0, 0);

            glDrawTransformFeedback(GL_POINTS, feedbackObject);

            glDisableVertexAttribArray(positionLocation);
            glBindBuffer(GL_ARRAY_BUFFER, 0);

        }
        glEndTransformFeedback();

        glUseProgram(0);

        glDisable(GL_RASTERIZER_DISCARD);

Firstly and lastly, we enable and then disable pixel rendering. This is opposed to using Transform Feedback
We set up our binds for the shader and also the feedback object.
Then we update the buffers with our input data (random points) and enable the shader attribute “positionLocation”
Now we draw the points.

 

Fourth:

In the initTransformFeedback() method insert this code.

        inputData = BufferUtils.createFloatBuffer(NUM_POINTS * 2);
        inputVBO = glGenBuffers();

        outputVBO = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, outputVBO);
        glBufferData(GL_ARRAY_BUFFER, NUM_POINTS * 2 * 4, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        feedbackObject = glGenTransformFeedbacks();
        glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, feedbackObject);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, outputVBO);
        glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);

This code is what initializes all of the transform feedback options.
The inputData variable is the buffer that we will fill with our random points that we are rendering, and the inputVBO is where we will store our VBO that we load data in to.

Now we make a new buffer where we store all of our points. We do account for if the buffer has ALL of the potential points in, so we make it big enough to store all of them.
Then we finally create the Transform Feedback Object which we bind to store its output in to the buffer we just created

Lastly:

In the initShader() method insert this code.

        shaderProgram = glCreateProgram();        
        int vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, loadFileSource("shaders/test.vert"));
        glCompileShader(vertexShader);
        glAttachShader(shaderProgram, vertexShader);

        int geometryShader = glCreateShader(GL_GEOMETRY_SHADER);
        glShaderSource(geometryShader, loadFileSource("shaders/test.geom"));
        glCompileShader(geometryShader);
        glAttachShader(shaderProgram, geometryShader);

        glTransformFeedbackVaryings(shaderProgram, new CharSequence[] { "outPosition" }, GL_INTERLEAVED_ATTRIBS);

        glLinkProgram(shaderProgram);

        // Save the input variable location
        positionLocation = glGetAttribLocation(shaderProgram, "position");

What this code does is load in the separate shaders, and then it tells the shader that we want output from the transform feedback output.

 

Once you have completed all of the steps above, you should be able to get it to run! It should show up with a black box with a bunch of alternating points. They get more random when you click the mouse. It really isn’t much to look at, but it is a really good exercise to get familiar with Transform Feedback.

Hopefully you enjoyed this presentation! Thanks!

 

 

Also, in case you wanted, here are all the links in the slideshow:

http://www.youtube.com/watch?v=SiCq8ETTqRk

  • Good example, uses transform feedback to render a particle smoke system with fire spreading.

http://www.youtube.com/watch?v=1YLPtr_BtiM

  • Example shows another possible usage for TF, it passes vertex information with Transform feedback which allows for seamless facial expressions.

http://www.youtube.com/watch?v=E636tYOxoVI

  • Another good example that shows how good performance can be by using TF. It controls all of the particles in this on the GPU.

 

http://www.java-gaming.org/index.php?topic=27786.0

  • •A java based tutorial that we used for the in class lab exercise. It is a very simple version of implementing Transform Feedback and is very helpful to learn the basics of how it works.

http://ogldev.atspace.co.uk/www/tutorial28/tutorial28.html

  • •Very informative, pretty long to follow. Goes over all of the basics of Transform feedback and has code samples to back it up.

 

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *