EXT_transform_feedback

Hi,

I’m working on porting my GPU particle systems from FBOs to transform feedback.

The “Transform Feedback Fractal” here seems to work correctly. I’m trying to get my code working with EXT_transform_feedback instead of NV_transform_feedback, and with GLee instead of GLew.

I found this thread, which seems to use GLew and EXT_transform_feedback. I tried porting it to use GLee. One of the differences, it seems, is that glTransformFeedbackVaryingsEXT takes a GLint* of locations instead of a GLchar** of names to variables. My rendition: http://pastebin.com/KTQyV2pZ. The output:

Beginning to test EXT_TRANSFORM_FEEDBACK
Initialization complete (current error: 0)

Loading shader
Compile vertex: ""
Link result: ""
Shader loaded (current error: 0)

Trying to get location of "gl_Position"
Got location 0 (current error: 0)

Preparing buffer
Buffer prepared (current error: 0)
Feedback assigned (current error: 0)

Beginning drawing
In data: 0.1 0.2 0.3 0.4
Drawing completed (current error: 0)

Reading (hopefully transformed) data
Out data: -0.0 -0.0 -0.0 -0.0
Readback complete (current error: 0)

It seems that if I specify the location of init (as in the GLew example), instead of NULL, then the out data is just init again. This tells me that transform feedback isn’t changing anything in the VBO!

Help!!!

Thanks,
-G

You need to relink program after specifying varyings to feed back.
NV extension doesnt have this requirement.

I added the following code after line 70

printf("Trying to relink shader
");
glLinkProgramARB(shid);
checkShader(shid, GL_OBJECT_LINK_STATUS_ARB, "Link result");
printf("Shader relinked (current error: %d)

", glGetError());

But the result is still the same.

Try setting the feedback information prior to linking. Also, you have no fragment shader? I recently converted a transform feedback tutorial, written by Shiben Bhattacharjee, which uses NV_transform_feedback to use EXT_transform_feedback.

This is the tutorial in particular. I added a vertex and fragment shaders to it, and made sure that I set up the transform buffer prior to linking.

Here are the modifications that I made for those interested in converting the said tutorial to use EXT_transform_feedback.


GLuint tfvbo,vs,fs,pg;
int count=2;
float t=0;
const char* vs1[]={
	"#version 130
"	
	"out vec4 color;"
	"void main(){"
	"gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
	"color = gl_Color;"
	"}"
};
const char* fs1[]={
	"#version 130
"
	"in vec4 color;"
	"void main(){"
	"gl_FragColor = color;"
	"}"
};
void setupTFvbo(void)
{
	const char* att[1]= {"gl_Position"};

	//generating the buffer, note that GL_TRANSFORM_FEEDBACK_BUFFER is NOT a buffer type
	glGenBuffers(1,&tfvbo);
	glBindBuffer(GL_ARRAY_BUFFER,tfvbo);
	glBufferData(GL_ARRAY_BUFFER,count*4*sizeof(float),0,GL_STATIC_DRAW);

	//bind the tfvbo to get the feedback
	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,0,tfvbo);

	glTransformFeedbackVaryings(pg,1,att,GL_INTERLEAVED_ATTRIBS);
}
void init(void)
{
	glClearColor(0.5,0.5,0.5,1);
	glPointSize(5);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1,1,-1,1,0.2,2);
	glMatrixMode(GL_MODELVIEW);

	vs = glCreateShader(GL_VERTEX_SHADER);
	fs = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(vs,1,vs1,0);
	glShaderSource(fs,1,fs1,0);
	glCompileShader(vs);
	glCompileShader(fs);
	
	pg = glCreateProgram();
	glAttachShader(pg,vs);
	glAttachShader(pg,fs);
	setupTFvbo(); //set up transform feedback
	glLinkProgram(pg);
	
	glUseProgram(pg);
}


        loc = glGetVaryingLocationNV(shid,"gl_Position");
        printf("Got location %d (current error: %d)

",loc,glGetError());
        //const char *vars[] = {"out_pos"};
        const GLint locations[] = {loc};
        glTransformFeedbackVaryingsEXT(shid, 1, locations, GL_SEPARATE_ATTRIBS_EXT); //for GLee?

This is wrong, glTransformFeedbackVaryingsEXT takes array of strings as parameter - not locations from NV extension.

Alright; I’ve got the NV extension working. I definitely like that tutorial; it’s good![quote=]This is wrong, glTransformFeedbackVaryingsEXT takes array of strings as parameter - not locations from NV extension.[/QUOTE]Yeah; I’m getting an error on that line. I don’t know what to do about it. Just using the NV extension feels less portable (I’m assuming NV extensions don’t run on ATI/Intel/etc. and vice versa? Or is that just wrong?)
Thanks!
G

Everyone supports EXT_transform_feedback, however only NVIDIA supports NV_transform_feedback. The NVIDIA extension supports transform feedback with assembly vertex/geometry programs and fixed-function vertex processing, however the EXT extension does not. Thus the reason I had to modify the tutorial to use GLSL shaders, as the initial version used fixed-function vertex processing.

In any case, I was unable to get “glTransformFeedbackVaryings(pg,1,att,GL_INTERLEAVED_ATTRIBS);” working with GLee.

That maybe a bug in Glee. Anyway, I’ve been using GLEW. Try adding the EXT suffix to the function and see if it works. The code is written under the assumption that the OpenGL driver and extension loading library fully support OpenGL 3.0+. As EXT_transform_feedback became a core extension of OpenGL 3, the EXT suffix is unnecessary.

Nope; didn’t.

I’ve really been avoiding using GLEW, but I guess if you need the functionality . . .

I managed to get GLEW set up and working, much less painlessly than I had remembered from trying before. The program works perfectly :stuck_out_tongue: I just wish GLee would work right.

It seems that the transform feedback cannot execute transformations on its source buffer; i.e., the source buffer cannot also be the target of the transform feedback.

I assume the solution here is to ping-pong, à la FBOs? And can someone confirm?

Thanks,

I’ve gotten it working in my main code successfully; I’m trying to make a GPU particle system. However, I’m having trouble getting more than one attribute to work simultaneously.

I go like this:

const char* variables[] = {"position_out","velocity_out"};
glTransformFeedbackVaryings(program,2,variables,GL_SEPARATE_ATTRIBS_EXT);

//...

glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,0,_vbo_position);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,1,_vbo_velocity);

//...

glBindBuffer(GL_ARRAY_BUFFER_ARB,_vbo_position);
glDrawArrays(GL_POINTS,0,count);

glBindBuffer(GL_ARRAY_BUFFER_ARB,_vbo_velocity);
glDrawArrays(GL_POINTS,0,count);

But the results are incorrect. The variables seem to be all mixed up. Is this basically the right idea?

Based on the snippets done by Groovounet, who made a post on his website about Transform Feedback, your snippet is incorrect. Maybe he can provide more insight (in this thread), or you can glean some info from his post to set you in the right direction.

I managed to get it working using vertex attributes:

glEnableVertexAttribArray(location_position);
if (_vbo_ping_pong==1) glBindBuffer(GL_ARRAY_BUFFER,_vbo_position1);
else                   glBindBuffer(GL_ARRAY_BUFFER,_vbo_position2);
glVertexAttribPointer(location_position,3,GL_FLOAT,GL_FALSE,0,NULL);

glEnableVertexAttribArray(location_velocity);
if (_vbo_ping_pong==1) glBindBuffer(GL_ARRAY_BUFFER,_vbo_velocity1);
else                   glBindBuffer(GL_ARRAY_BUFFER,_vbo_velocity2);
glVertexAttribPointer(location_velocity,3,GL_FLOAT,GL_FALSE,0,NULL);

glDrawArrays(GL_POINTS,0,numof_particles);

glDisableVertexAttribArray(location_position);
glDisableVertexAttribArray(location_velocity);

The particle system runs at ~40 fps with 1,048,576 particles, which is about quadruple that of my FBO-based implementation. Does this seem like a fairly reasonable speed for a (very simple) particle system to update at?