Graphics Reference
In-Depth Information
Example 14-10
Emit Particles with Transform Feedback
(continued)
// Emit particles using transform feedback
glBeginTransformFeedback(GL_POINTS);
glDrawArrays(GL_POINTS, 0, NUM_PARTICLES);
glEndTransformFeedback();
// Create a sync object to ensure transform feedback
// results are completed before the draw that uses them
userData−>emitSync = glFenceSync(
GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );
// Restore state
glDisable(GL_RASTERIZER_DISCARD);
glUseProgram(0);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
glBindTexture(GL_TEXTURE_3D, 0);
// Ping−pong the buffers
userData−>curSrcIndex = ( userData−>curSrcIndex + 1 ) % 2;
}
The destination buffer object is bound to the
GL_TRANSFORM_FEEDBACK_
BUFFER
target using
glBindBufferBase
. Rasterization is disabled
by enabling
GL_RASTERIZER_DISCARD
because we will not actually
draw any fragments; instead, we simply want to execute the vertex
shader and output to the transform feedback buffer. Finally, before
the
glDrawArrays
call, we enable transform feedback rendering by
calling
glBeginTransformFeedback(GL_POINTS)
. Subsequent calls to
glDrawArrays
using
GL_POINTS
will then be recorded in the transform
feedback buffer until
glEndTransformFeedback
is called. To ensure
transform feedback results are completed before the draw call that uses
them, we create a sync object and insert a fence command immediately
after the
glEndTransformFeedback
is called. Prior to the draw call
execution, we will wait on the sync object using the
glWaitSync
call.
After executing the draw call and restoring state, we ping-pong between
the buffers so that the next time
EmitShaders
is called, it will use the
previous frame's transform feedback output as the input.
After emitting the transform feedback buffer, that buffer is bound as
a vertex buffer object from which to render the particles. The vertex
shader used for particle rendering with point sprites is provided in
Example 14-11.