TFO 可以用来获取顶点着色器的输出属性组的缓冲,基本步骤如下。
1.设置需要输出的属性组
GLchar const * Strings[] = {"gl_Position", "vColor"};
glTransformFeedbackVaryings(Program, 2, Strings, GL_INTERLEAVED_ATTRIBS);
2. 创建TFO,设置输出缓冲。
void InitTransformFeedback()
{
glGenTransformFeedbacks(1, &g_FeedbackObj);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, g_FeedbackObj);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, g_FeedbackBuffer);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
}
void InitVBO()
{
// Generate a buffer object
glGenBuffers(1, &g_TransformBuffer);
glBindBuffer(GL_ARRAY_BUFFER, g_TransformBuffer);
glBufferData(GL_ARRAY_BUFFER, g_PositionSize, g_Triangle, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &g_FeedbackBuffer);
glBindBuffer(GL_ARRAY_BUFFER, g_FeedbackBuffer);
glBufferData(GL_ARRAY_BUFFER, g_PositionSize, NULL, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
3. 绘制源图象,求反馈数据
glUseProgram(g_TransformProgram);
glEnable(GL_RASTERIZER_DISCARD);
CHECK_GL_ERROR
glUniformMatrix4fv(g_TransformUniformMVP, 1, GL_FALSE, matModelView);
CHECK_GL_ERROR
glEnableVertexAttribArray(g_TransformPositionLoc);
CHECK_GL_ERROR
glEnableVertexAttribArray(g_TransformColorLoc);
CHECK_GL_ERROR
glBindBuffer(GL_ARRAY_BUFFER, g_TransformBuffer);
glVertexAttribPointer(g_TransformPositionLoc, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 8, 0);
CHECK_GL_ERROR
glVertexAttribPointer(g_TransformColorLoc, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 8, BUFFER_OFFSET(sizeof(float)*4));
CHECK_GL_ERROR
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, g_FeedbackObj);
glBeginTransformFeedback(GL_TRIANGLES);
glDrawArrays(GL_TRIANGLES, 0, 3);
CHECK_GL_ERROR
glEndTransformFeedback();
CHECK_GL_ERROR
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
CHECK_GL_ERROR
glDisable(GL_RASTERIZER_DISCARD);
4. 影射到内存空间
glBindBuffer(GL_ARRAY_BUFFER, g_FeedbackBuffer);
void* rawdata = glMapBufferRange( GL_ARRAY_BUFFER, 0, g_PositionSize, GL_MAP_READ_BIT);
float *p = (float*)rawdata;
for(int i=0; i<6; i++)
{
float a = p[i*3+0];
float b = p[i*3+1];
float c = p[i*3+2];
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);