I have an interesting problem regarding transform feedback (TFB).
Using a debugger, the following pseudo code runs sucessfully precisely once per frame, on the next and subsequent frames the transform feedback pass generates a general protection fault calling glDrawArrays (nVidia GF 8600GTm). I have also tested on Radeon 4850 - it does not crash but nothing gets rendered.
Pseudo code goes something like this:
pass #1
Bind TFB shader (Gemoetry and vertex shader)
bind VBO for TFB shader containing instance source data
setup and enable TFB
gldrawarrays (GL_POINTS, num instances)
disable TFB
disable VBO
#pass 2
Draw model using transformed VBO
Skipping pass #1 proves that the model does actually draw properly in pass #2 (albeit there is no instance data provided).
This is the code used for pass #1
AsteroidBelt.TransformFeedback.AsteroidCount := AsteroidBelt.NumInstances;
glPushClientAttrib (GL_CLIENT_VERTEX_ARRAY_BIT);
// ---- Pass #1 ----
//
// Transform feedback - visibility test --- render to vertex buffer
//
ShaderManager.enableProfile(FXlist[ 7 ].ShaderIndex); //asteroid belt shader Vertex/Gemoetry Shader.
ShaderManager.ApplyAllParameters(FXlist[ 7 ].ShaderIndex);
glBindBuffer(GL_ARRAY_BUFFER, AsteroidBelt.InstanceData.TBO);
glEnableVertexAttribArray(vertexAttribs [7] [vaModelView1]); //instance attribute slot
glVertexAttribPointer(vertexAttribs [7] [vaModelView1], 4, GL_FLOAT, GL_FALSE, 0, pointer(0));
glEnable(GL_RASTERIZER_DISCARD);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, AsteroidBelt.TransformFeedback.BO); //buffer to write into - stream #1
glBeginTransformFeedback(GL_POINTS);
glBeginQuery(GL_PRIMITIVES_GENERATED, AsteroidBelt.TransformFeedback.AsteroidQuery); // query for generated primitive count
glDrawArrays(GL_POINTS, 0, AsteroidBelt.NumInstances); // draw the instance data as points
glEndQuery(GL_PRIMITIVES_GENERATED);
glEndTransformFeedback();
glDisable(GL_RASTERIZER_DISCARD);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
glDisableVertexAttribArray(vertexAttribs [7] [vaModelView1]); //instance attribute slot
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGetQueryObjectiv(AsteroidBelt.TransformFeedback.AsteroidQuery, GL_QUERY_RESULT, @AsteroidBelt.TransformFeedback.AsteroidCount);
end;
As I said, what I don’t get is that if I put a flag in pass #1 to only fill the contents of the feedback VBO once, pass #2 sucessfully draws the asteroids. As soon as I remove the ‘once-only’ flag from pass #1 I get a general protecton fault.
Any ideas?