PDA

View Full Version : Correct size of BufferData for Transform Feedback



miroslav_karpis
06-23-2011, 06:43 AM
really can't figure out this one:

I'm using transform feedback with geometry shader. I'm sending GL_POINTs (glDrawArrays) and in geometry shader creating a billboards from them (adding 3 more vertices). So basically input is point and output triangle_strip with 4 vertices (billboard). After that I make some animations in geometry shader, where new values I want to get back via transform feedback.


//output buffer for storing values after animation
glBindBuffer(GL_ARRAY_BUFFER, vboBuffID_2);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*numOfParticles*3, 0, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, 0, vboBuffID_2);

//input buffer (points)
glBindBuffer(GL_ARRAY_BUFFER, vboBuffID_1);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*numOfParticles*3, vboBuff_1, GL_DYNAMIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, NULL);

//start transform feedback
glBeginTransformFeedback(GL_TRIANGLES);
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRIT TEN_EXT, query);
glDrawArrays(GL_POINTS, 0, numOfParticles);
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTE N_EXT);
glEndTransformFeedback();

glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
glBindBuffer(GL_ARRAY_BUFFER, 0);

//draw again what we have received
glEnableClientState( GL_VERTEX_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, vboBuffID_2);
glVertexPointer(3, GL_FLOAT, 0, 0 );
glDrawArrays(GL_POINTS, 0, numOfParticles);
glDisableClientState( GL_VERTEX_ARRAY );

For me this looks like it should work, but unfortunately it does not. When my input is 5 points I'm drawing only 7 billboards (5 from input and 2? from my transform feedback). Why only 2? It should be 5. Everything works if I multiply size of my output buffer x 4 and change the size of my last glVertexPointer call from 3 to 4. Please does anybody know why?

My glTransformFeedbackVaryings is set to get one variable 'vtxPosition':

const char *vars[1] = { "vtxPosition" };
glTransformFeedbackVaryings(glslRain, 1, vars, GL_INTERLEAVED_ATTRIBS_EXT);

Here is my geometry shader:


varying in vec3 vtxPositionIn[];
varying out vec3 vtxPosition;

void main(void)
{
//animate the particles
vtxPosition = vtxPositionIn[0];
vtxPosition.y = vtxPosition.y;// - 0.0005;

//------create billboard from one point
//vertex 1
gl_FrontColor = gl_FrontColorIn[0];
gl_Position = gl_PositionIn[0];
EmitVertex();

//vertex 2
gl_FrontColor = gl_FrontColorIn[0];
gl_Position = gl_PositionIn[0];
gl_Position.x = gl_Position.x + 1.0;
EmitVertex();

//vertex 3
gl_FrontColor = gl_FrontColorIn[0];
gl_Position = gl_PositionIn[0];
gl_Position.y = gl_Position.y + 1.0;;
EmitVertex();

//vertex 4
gl_FrontColor = gl_FrontColorIn[0];
gl_Position = gl_PositionIn[0];
gl_Position.y = gl_Position.y + 1.0;
gl_Position.x = gl_Position.x + 1.0;
EmitVertex();

EndPrimitive();
}

aqnuep
06-23-2011, 07:55 AM
I don't think you can tightly pack a vec3 when using transform feedback. Maybe it is automatically promoted to a vec4. I need to check the spec in order to be sure. Meanwhile, I suggest you to check http://www.opengl.org/registry/specs/EXT/transform_feedback.txt whether it says anything about this behavior.