OPenGL--Transform feedback基础

简述

TransformFeedback是OpenGL管线中,顶点处理(如果有几何着色器,那么就在几何着色器后)之后,图元装配之前的一个步骤。它可以重新捕获即将装配为图元(点,线段,三角形)的顶点,然后将部分或全部属性传递到缓存对象上来。每当一个顶点传递到图元装配阶段时,将所有需要捕获的属性记录到一个或多个缓存对象上,用户程序可以回读这些缓存对象的内容。

根据这个特性,它和顶点着色器可以组合成一个小的渲染管线,而不用后续的光栅化处理,这样就能利用GPU强大的计算能力做一些通用的计算。当然,如果当前OpenGL版本在OpenGL4.3及以上的话,可以使用了计算着色器。


transform feedback对象

transform feedback状态封装在一个transform feedback对象中,这个状态中包括所有记录顶点数据的缓存对象等,transform feedback对象的创建和其他的缓存对象类似,首先要创建一个对象名称,然后绑定到OpenGL环境中。

1创建对象名

GLuint glGenTransformFeedbacks(GLenum target,  GLuint *id);

返回值:返回Uniforms的缓冲索引

参  数:program  着色器程序ID

        uniformBlockName  Uniforms块名

 

2绑定到OpenGL环境

GLuint glBindTransformFeedback(GLenum target,  GLuint id);

返回值:返回Uniforms的缓冲索引

参  数:program  着色器程序ID

        uniformBlockName  Uniforms块名

 

3删除对象

GLuint glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids);

返回值:返回Uniforms的缓冲索引

参  数:program  着色器程序ID

        uniformBlockName  Uniforms块名

 

transform feedback缓存

transform feedback对象主要用于管理将顶点捕捉到缓存对象的相关状态,这个状态中包含了链接到transform feedback缓存绑定点的缓存对象,transform feedback对象必须和一个缓存对象链接才能输出数据,它本身是不存储输出数据的(与帧缓存对线和附加到它上的纹理缓存类似)。

如果想要将整个缓存绑定到transform feedback上,可以使用函数glBindBufferBase()。

voidglBindBufferBase(GLenum target, GLint index, GLuint buffer)

功  能:将缓存绑定到transform feedback上

返回值:void

参  数:target 绑定目标必须设为GL_TRANSFORM_FEEDBACK_BUFFER

index  缓存绑定点索引

buffer 绑定的缓存对象

 

如果想要将缓存的部分绑定到transform feedback上,可以使用函数glBindBufferRange()。

void  glBindBufferRange(GLenum target, GLuint index, GLuint buffer,

GLintptr offset, GLsizeiptr size)

功  能:将缓存绑定到transform feedback上

返回值:void

参  数:target 绑定目标必须设为GL_TRANSFORM_FEEDBACK_BUFFER

index  缓存绑定点索引

buffer 绑定的缓存对象

offset  起始地址

size   绑定的缓存大小

 

transform feedback缓存初始化示例

//生成缓存对象

Gluint buffer;

glGenBuffers(1, &buffer);

//绑定到GL_TRANSFORM_FEEDBACK_BUFFER,创建缓存对象

glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER,  buffer);

 

//调用glBufferData并分配空间

glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,   //目标

1024 * 1024,   //分配空间

NULL,   //数据为空

GL_DYNAMIC_COPY); //用途

 

//绑定到带有索引的缓存绑定点

glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER,  //目标

0, //索引为0

buffer, //缓存名称

0, //数据起始地址

512 * 1024); //缓存的前半部分

glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER,  //目标

0,//索引为0

buffer,//缓存名称

512 * 1024),//数据起始地址

512 * 1024);//缓存的前半部分

 

配置transform feedback变量

再transform feedback过程中顶点着色器可能会输出多个变量。与transform feedback对象所绑定的缓存需要记录那些变量,这些都需要在应用程序中设置,我们需要调用函数glTransformFeedbackVaryings()来设定。

void  glTransformFeedbackVaryings(GLuint program,  GLsizei count,

const GLchar **varyings, GLenum bufferMode)

功  能:设置缓存记录的变量

返回值:void

参  数:program     着色器程序

count       变量的总数

varyings     变量名数组

bufferMode  捕获变量的模式,可以是分量模式(GL_SEPARATE_ATTRIBS)

或交叉模式(GL_INTERLEAVED_ATTRIBS)

注意:函数glTransformFeedbackVaryings()所指定的变量,只有再一次链接的时候才会起效,换句话说,glTransformFeedbackVaryings()必须再着色器程序链接之前调用。


transform feedback变量设置的示例

//创建一个记录变量名称的数组

static  const char *const  vars[] =

{

"foo", "var", "vaz"

};

 

//调用函数glTransformFeedbackVaryings

glTransformFeedbackVaryings(program,

sizeof(vars)/sizeof(vars[0]),

vars,

  GL_INTERLEAVED_ATTRIBS);

//现在(非常重要),需要链接程序对象

glLinkProgram(program);

 

transform feedback的启动和停止

transform feedback可以随时启动或停止,甚至暂停,如果启动transform feedback时,它并没有处于暂停的状态,它会重新开始将数据记录到当前绑定的ransform feedback缓存中,不过如果transform feedback正处于暂停的状态,那么再次启动它将会从之前暂停的位置开始记录。如果需要将厂家中的某些部分记录到transform feedback当中,这个特效是比较有用的。

 

启动

void glBeginTransformFeedback(GLenum primitiveMode);

暂停

void glPauseTransformFeedback(void);

如果当前的ransform feedback没有启用,或者处于暂停状态,

调用glPauseTransformFeedback会产生一个错误

重新启动

void glResumeTransformFeedback(void);

要重新启动一个暂停的ransform feedback,必须使用glResumeTransformFeedback。

如果使用glBeginTransformFeedback同样会产生一个错误。

停止

void glEndTransformFeedback(void);

如果已经完成了transform feedback图元的渲染,直接调用glEndTransformFeedback(),就可以重新切换到正常的渲染模式。


这章主要写了一些transform feedback的简要流程和API,不太容易理解和使用,可以参考下章

OPenGL--Transform feedback示例解析,有详细的示例。


参见:《OpenGL编程指南》第八版第5章

猜你喜欢

转载自blog.csdn.net/niu2212035673/article/details/79037236