簡述
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章