设置着色器
在shader链接之前,需要指定shader中将被缓存到buffer的变量
void glTransformFeedbackVaryings(GLuint program, GLsizei count, //变量个数 const char **varyings, //变量名or控制变量 GLenum bufferMode);
bufferMode可以是
GL_INTERLEAVED_ATTRIBS //多个变量输出到任意个buffer绑定点 GL_SEPARATE_ATTRIBS //一个变量输出到一个buffer绑定点
当bufferMode是GL_ INTERLEAVED_ATTRIBS时,varying中可以存放控制变量,用于控制输出变量路由到buffer的方式,控制变量可以是
gl_NextBuffer //接下来的输出变量将被路由到下一个buffer绑定点 gl_SkipComponents# //用于手动填充以对齐双精度浮点数或向量
绑定顶点
和vao类似,transform feedback object用于管理多组buffer的绑定和解绑定
void glGenTransformFeedbacks(GLsizei n,GLuint *ids); void glBindTransformFeedback(GLenum target,GLuint id); //target必须是GL_TRANSFORM_FEEDBACK
初始化内存后的buffer object需要绑定到当前变换反馈对象的某个索引点后才能作为变换反馈缓冲区使用(虽然glBindBuffer的target参数可以是GL_ TRANSFORM _FEEDBACK _BUFFER,但使用该函数进行绑定是没有效果的)
void glBindBufferBase(GLenum target, GLuint index, GLuint buffer); void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
渲染变换反馈缓冲区的内容
- glDrawTransformFeedback和glDrawArrays的唯一区别在于前者从变换反馈缓冲区中提取数据,后者从顶点缓冲区中提取数据
实例
GLuint query;
glGenQueries(1, &query);
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
glBeginTransformFeedback(GL_POINTS);
glEnable(GL_RASTERIZER_DISCARD);
...
draw calls
...
glEndTransformFeedback();
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
GLuint primWritten;
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &primWritten);
glDrawTransformFeedback
* 当gs没有激活时,begin transform和draw call的primitive mode有对应关系。当gs激活时,begin transform和gs输出的primitive mode有对应关系