1. iOS操作系統不會不會讓應用向前幀緩存和后幀緩存繪圖,也不會讓應用直接控制前幀緩存和后幀緩存之間的切換。操作系統為自己保留了這些操作,以便它可以隨時使用Core Animation合成器來控制顯示的最終外觀。
2.Core Animation 合成器使用OpenGLES來盡可能高效地控制GPU、混合層和切換幀緩存。圖形程序員經常使用術語混合(composite)來描述混合圖像以形成一個合成結果的過程。所有顯示的動畫都是通過Core Animation合成器來完成的,因此最終都設計OpenGLES。
3.幀緩存會保存OpenGLES的渲染結果,因此為了渲染到一個Core Animation層上,程序需要一個連接到某個層的幀緩存。簡言之,每個程序用足夠的內存配置一個層來保存像素顏色數據,之后創建一個使用層的內存來保存渲染的圖像的幀緩存。
以上內容為閱讀OpenGLES 應用開發實踐指南iOS卷第二章起始部分的總結。
渲染各個步驟函數解釋:
VBO:vertex buffer object
1.
GLuintvertexBufferID;
//step1
glGenBuffers(1, &vertexBufferID);
voidglGenBuffers(GLsizei n, GLuint* buffers)
為緩存生成一個標識符,第一個參數為要生成的標識符的數量,第二個參數為一個指針指向要存儲標識符的地址。
2.
//step2
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
voidglBindBuffer(GLenum target, GLuint buffer)
綁定用于指定標識符的緩存到當前緩存。OpenGLES 保存不同類型的緩存標識符到當前上下文的不同部位。但是在任意時刻每種類型都只能綁定一個緩存。
第一個參數是常量,用于指定哪一種類型的緩存。openGLES2.0在這個函數中只支持兩種:GL_ARRAY_BUFFER和GL_ELEMENT_ARRAY_BUFFER。第二個參數是要綁定的緩存的標識符。
3.
//step3
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
voidglBufferData(GLenum target,GLsizeiptr size,constGLvoid*? data, GLenum usage);
第一個參數target可以為GL_ARRAY_BUFFER或GL_ELEMENT_ARRAY。第二個參數size為待傳遞數據字節數量。第三個參數為源數據數組指針,如data為NULL,則VBO僅僅預留給定數據大小的內存空間。最后一個參數usage標志位VBO的另一個性能提示,它提供緩存對象將如何使用:static、dynamic或stream、與read、copy或draw。
VBO為usage標志指定9個枚舉值:
(1)GL_STATIC_DRAW
(2)GL_STATIC_READ
(3)GL_STATIC_COPY
(4)GL_DYNAMIC_DRAW
(5)GL_DYNAMIC_READ
(6)GL_DYNAMIC_COPY
(7)GL_STREAM_DRAW
(8)GL_STREAM_READ
(9)GL_STREAM_COPY
”static“表示VBO中的數據將不會被改動(一次指定多次使用),”dynamic“表示數據將會被頻繁改動(反復指定與使用),”stream“表示每幀數據都要改變(一次指定一次使用)。”draw“表示數據將被發送到GPU以待繪制(應用程序到GL),”read“表示數據將被客戶端程序讀取(GL到應用程序),”copy“表示數據可用于繪制與讀取(GL到GL)。
注意,僅僅draw標志對VBO有用,copy與read標志對頂點/幀緩存對象(PBO或FBO)更有意義,如GL_STATIC_DRAW與GL_STREAM_DRAW使用顯卡內存,GL_DYNAMIC使用AGP內存。_READ_相關緩存更適合在系統內存或AGP內存,因為這樣數據更易訪問。
4.
//step4
glEnableVertexAttribArray(GLKVertexAttribPosition);
void glEnableVertexAttribArray (GLuint index);
啟動頂點緩存渲染操作。OpenGLES所支持的每一個渲染操作都可以單獨地使用保存在當前OpenGLES的上下文中的設置來開啟和關閉。
默認情況下,出于性能考慮,所有頂點著色器的屬性(Attribute)變量都是關閉的,意味著數據在著色器端是不可見的,哪怕數據已經上傳到GPU,由glEnableVertexAttribArray啟用指定屬性,才可在頂點著色器中訪問逐頂點的屬性數據。glVertexAttribPointer或VBO只是建立CPU和GPU之間的邏輯連接,從而實現了CPU數據上傳至GPU。但是,數據在GPU端是否可見,即,著色器能否讀取到數據,由是否啟用了對應的屬性決定,這就是glEnableVertexAttribArray的功能,允許頂點著色器讀取GPU(服務器端)數據。
那么,glEnableVertexAttribArray應該在glVertexAttribPointer之前還是之后調用?答案是都可以,只要在繪圖調用(glDraw*系列函數)前調用即可。
5.
//step5
glVertexAttribPointer(GLKVertexAttribPosition,3,GL_FLOAT,GL_FALSE,sizeof(SceneVertex),NULL);
void glVertexAttribPointer (GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid* ptr);
告訴OpenGLES在接下來的渲染中是否使用緩存中的數據。
參數:
index
指示當前綁定的緩存包含每個頂點的位置信息。
size
指定每個頂點屬性的組件數量。必須為1、2、3或者4。初始值為4。(如position是由3個(x,y,z)組成,而顏色是4個(r,g,b,a))
type
指定數組中每個組件的數據類型。可用的符號常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值為GL_FLOAT。
normalized
告訴OpenGLES小數點固定數據是否可以被改變。
指定當被訪問時,固定點數據值是否應該被歸一化(GL_TRUE)或者直接轉換為固定點值(GL_FALSE)。
stride
指定每個頂點的保存需要多少字節。換句話,步幅指定了GPU從一個頂點的內存開始位置轉移到下一個頂點的內存開始位置需要跳過多少字節。
指定連續頂點屬性之間的偏移量。如果為0,那么頂點屬性會被理解為:它們是緊密排列在一起的。初始值為0。
pointer
指定第一個組件在數組的第一個頂點屬性中的偏移量。該數組與GL_ARRAY_BUFFER綁定,儲存于緩沖區中。初始值為0;
6.
//step6
glDrawArrays(GL_TRIANGLES,0,3);
void glDrawArrays (GLenum mode,GLint first,GLsizei count);
第一個參數會告訴GPU怎么處理在綁定的頂點緩存內的頂點數據。第二個參數指定緩存內需要渲染的第一個頂點的位置。第三個參數指定需要渲染的緩存數量。
告訴OpenGLES使用當前綁定并啟用的緩存中的數據渲染整個場景或某個場景的一部分。
參數說明:
mode,繪制方式,OpenGL2.0以后提供以下參數:GL_POINTS、GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN。
first,從數組緩存中的哪一位開始繪制,一般為0。
count,數組中頂點的數量。
其他函數解釋:
glClearColor(0.0f,0.0f,0.0f,1.0f);
void glClearColor (GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha);
清除顏色緩沖區的,并且都被歸一化在(0,1)之間的值,其實就是清空當前的所有顏色。設置當前上下文顏色(清除顏色)。