歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> OpenGL離線渲染和緩沖區對象

OpenGL離線渲染和緩沖區對象

日期:2017/3/1 9:46:47   编辑:Linux編程

理論

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行情木有研究。 4)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://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /2014年資料/3月/25日/OpenGL離線渲染和緩沖區對象

下載方法見 http://www.linuxidc.com/Linux/2013-07/87684.htm

回到主題,通過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示例。
Copyright © Linux教程網 All Rights Reserved