文章目錄
- 1. 不支援FBO
- 2. PC支援FBO
- 3. Mobile 上離線渲染
理論
OpenGLl離線渲染就是通過OpenGL將繪製結果渲染到顯存中的一張圖片上,通過gl介面函數可以從顯存讀取到記憶體中。基於OpenGL的離線渲染機制,可以快速實現一個渲染器:
輸入:映像,點,線。。。
輸出:映像
實現方案從一般到特殊:1. 不支援FBO主要介紹PC上,
行動裝置如果不支援FBO要實現離線渲染那就實在沒轍了。glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); 設定讀寫時後緩衝區。 一般pc都支援雙緩衝機制,
如果沒有GL_BACK就沒轍了。glDrawPixels 更新顏色緩衝區。調用opengl繪製函數在GL_BACK繪製。完成後glReadPixels將顏色緩衝區以從顯存調入記憶體。
該函數會導致gpu阻塞,效率不高。2. PC支援FBO
opengl支援多種緩衝區對象:緩衝區對象說白了就是 顯存中一塊緩衝區。OpenGL是業界渲染標準,具體介面功能由顯卡驅動實現,OpenGL用戶端是使用OpeGL的應用程式,OpenGL伺服器可以理解成GPU,如果沒有GPU就是OS核心中的一個模組,緩衝區對象定義在伺服器端,減少用戶端每次渲染時資料轉送開銷。每個緩衝區對象有唯一的ID,類似handle概念,用戶端通過BufferId管理緩衝區對象。1)紋理對象,最常見的從gl1.0就開始支援,基本操作指令:glGenTextures, glBindTextures, glDeleteTextures,後續有多重紋理增加新的指令。伺服器端的紋理資料,用戶端只有
寫入權限:glTexSubImage2D函數局部或者全部更新紋理緩衝區內容。2)VBO(vertex buffer object)和PBO(pixel buffer object) 原理完全一樣使用相同的gl指令:glGenBuffers,glBindBuffers,glDeleteBuffers。。。只不過buffer中存的資料內容不一致,前者存頂點後者存像素。VBO的出現 頂點列表逐漸淡出了人們的視野。伺服器端的VBO,PBO,用戶端有
讀寫權限:glMapBuffer 將伺服器端記憶體位址映射為用戶端地址,操作完成調用glUnMapBuffer;或者直接通過glBufferSubData 更新資料。3)VBO後又出現VAO(vertex array buffer),VAO的是GL3.0出來的東東,有點高處不甚寒 考慮行動裝置 考慮android行情木有研究,有志者請猛擊此處:http://www.zwqxin.com/archives/opengl/vao-and-vbo-stuff.html4)RBO(render buffer object),rbo並不能單獨使用,必須配合fbo,與opengl緩衝區對應,RBO可以存放顏色、深度、模板資料。指令集合:glGenRenderbuffers,glBindRenderbuffer,glDeleteRenderbuffers。5)FBO(frame buffer object) 有一套專門的指令集合:glGenFramebuffers, glBindFramebuffer, glDeleteFramebuffers.。FBO建立以後必須綁定緩衝區:顏色、深度必須,樣板緩衝區看需求而定。緩衝區對象並不局限於RBO,紋理對象也可以充當緩衝區對象:建立紋理是glTexImage2D最後一個參數為NULL,在顯存中只需要建立紋理對象,而並不需要傳紋理資料。紋理對象作為緩衝區對象的例子:http://www.songho.ca/opengl/gl_fbo.html採用RBO的例子:http://www.codesampler.com/source/ogl_fbo_pbo_readback.zip回到主題,
通過fbo實現離線渲染流程如下:
主渲染流程,使用系統預設的緩衝區對象
儲存OpenGL現場
—————————>> bind FBO
a) glClear 清空FBO對應的各種緩衝區內容
b) 在離線渲染之前,往顏色緩衝區中新增內容,如背景圖片
c) set projectionMatrix
d) set modelviewMatrix
e) all draw calls // draw some stuff
f) glReadPixels // 如果需要,渲染結果圖片從顯存調入記憶體,在後續主渲染流程中建立紋理對象使用。
glCopyTexImage2D使用框架緩衝區的資料定義紋理單元,像素直接從顏色緩衝區讀取,功能類似glCopyPixels
如果顏色緩衝區採用 紋理對象,後續在主渲染流程中 可以直接使用該紋理進行繪製
<<————————— unbind FBO
回到主渲染流程3. Mobile 上離線渲染行動裝置,明顯特點是受限,gles是opengl的縮減版,gles沒有glDrawBuffer和glReadBuffer介面,沒法直接操縱前後緩衝區,所以方案1失效 只能轉向FBO。gles1.1開始支援FBO,gl變數和指令加OES尾碼。手機上fbo離線渲染流程跟PC上基本類似,在此主要說兩點主要差別:1)關於
離線渲染的步驟b,pc上最常見的做法glDrawPixels直接往顏色緩衝區拷貝資料,但是gles不支援glDrawPixels。想到的第一種替代方案:正交投影模式下直接drawTextureQuad,走OpenGL標準流水線:紋理對象建立、資料轉送,頂點傳輸、幾何變換流程,光柵化、紋理座標定址取紋理單元,最終通過緩衝區各種測試將結果寫到顏色緩衝區中。
最佳化後的方案:紋理對象作為FBO的顏色緩衝區,可以通過glTexSubImage2D函數直接將映像資料更新到顏色緩衝區中,全部或者局部,功能跟glDrawPixels完全一致,避免走OpenGL流水線。2)在手機上效率優先,建議不要直接使用glReadPixels函數,可以參考ogl_fbo_pbo_readback樣本。