Transform feedback buffer binding

Hi

I am implementing RenderToVertexBuffer (transform feedback in opengl) support in the Ogre 3d engine.

I am now trying to take care of the output buffer binding part. That is - which elements of the vertices outputted by the vertex/geometry pipeline get written to the vertex buffer, and in what order.

I am using two sources :

  1. NV_transform_feedback spec : http://www.opengl.org/registry/specs/NV/transform_feedback.txt
  2. Nvidia’s transform_feedback_fractal sample from http://developer.download.nvidia.com/SDK/10/opengl/samples.html .

There is a big conflict between them :

The spec states :

Two methods exist to specify which transformed vertex attributes are streamed to one, or more, buffer objects in transform feedback mode. If an OpenGL Shading Language vertex and/or geometry shader is active, then the state set with the TransformFeedbackVaryingsNV() command determines which attributes to record. If neither a vertex nor geometry shader is active, the state set with the TransformFeedbackAttribsNV() command determines which attributes to record.

However, the sample uses the glTransformFeedbackAttribsNV call to state the attributes even though it uses a geometry shader. I would say, OK, the sample is wrong, but it works!

Why is this? Am I reading the spec wrong?
The only theory that I have, is that in the spec, there is a difference between a vertex/geometry “shader” and a vertex/geometry “program”. “shaders” are written in GLSL and “program” are written in assembly. Since cg (which is used in the sample) gets compiled to GL asm, it is actually a program, so glTransformFeedbackAttribsNV needs to be used instead of glTransformFeedbackVaryingsNV. Only if the shaders are written in GLSL, then is glTransformFeedbackVaryingsNV used.

Is this correct? Does anyone have any more references/samples to transform feedback that I can use?

Thanks!

For assembly programs and fixed function, you use glTransformFeedbackAttribsNV(). For GLSL shaders, you use glTransformFeedbackVaryingsNV(). :slight_smile:

I see… So its like I suspected. Thanks!

Another question : I haven’t been able to find a single usage example of glTransformFeedbackVaryingsNV, and the questioning of the program object that I can do before that.

In my scenario, I get a vertex declaration (in Ogre’s abstract format) of the output vertex buffer, and I have to generate the bindings.

I assume that the user gave me correct input (lets say for this sample, a position, a normal and two 2D texture coordinates). How would I interrogate the program object to get the required information to build the correct attribute array for the glTransformFeedbackVaryingsNV call?

Here is some code I am using right now:


glUseProgram(graph);

int loc[] =
{
    glGetVaryingLocationNV(graph, "data"),
    glGetVaryingLocationNV(graph, "gl_Position"),
};

glTransformFeedbackVaryingsNV(graph, 2, loc, GL_SEPARATE_ATTRIBS_NV);

Where “data” is a user-defined varying (and gl_Position is the built-in varying).

Hope this helps. :slight_smile:

That does help. A lot! Thanks!

Is there a documented list of the predefined attributes (like gl_Position) that I can use?

(Sorry, I’m not a GLSL expert, I personally use CG 99% of the time…)

this may help you.

Sweet! Thank you all!

So far so good. I’ve been able to write code that dynamically creates the data for these calls based on the abstract vertex declaration. I don’t support custom varying variables, and currently limit myself to rather basic variables (outputting positions, texture coordinates and colors) but it is enough for now.

The next problem is controlling the output. Ogre uses 32 bits ARGB (or ABGR, depending) for colors. However, when I set the transform feedback to give me a color, I get 4 floats (meaning 128 bits). I do not need this much accuracy and would much rather get the packed integer. I tried using both 1 and 4 as the ‘number of components’ variable for the color attribute, but both of them gave me 32 bit floating point results (when I used 1 i only got one channel…)

Is there a call that controls this?

I believe for this you are going to have to declare a custom varying and pack in the shader.

Fair enough.
By the way, the code (for the buffer) is pretty much finalized now :
OgreGLRenderToVertexBufferObject.cpp

If anyone wants to use it as a reference (for both modes of operation), have fun :slight_smile:

(but it is LGPL as its part of ogre)