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章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章