前略好幾章都沒放上來,以後再補上吧。
之前一直使用gltools的glbatch來填充資料傳給shader,現在直接用自己的buffer來傳資料了。
不外乎幾步:
弄乙個buffer指標,其實弄乙個buffer陣列也可以了,陣列可以記得個數,指標可不能,容易出事兒
就這麼著吧,算是上一步弄了個buffer陣列,那陣列名就是乙個指標了,現在把指標傳給opengl來分配乙個buffer
unsigned
int n =1;
gluint buffers[n]
;glgenbuffer
(n, buffers)
;
接下來就是針對某乙個buffer來bind了,bind的時候要說明用處,比如
glbindbuffer
(gl_array_buffer, buffers[0]
);// 當然想寫成*buffers也可以
上面提及這種型別就是可以拿來放頂點啊,顏色啊,紋理座標啥的。
迄今為止見過的還有gl_texture_buffer,gl_uniform_buffer用完之後不想要了就要刪除,但是要保證buffer沒有被繫結為任何用途。
gldeletebuffers(1
, buffers)
;
另外,怎麼傳輸資料是個問題。
glbufferdata
(gl_pixel_pack_buffer, datasize, data, gl_dynamic_copy)
;
第乙個引數是繫結點(what?),第二個引數是用途。
不知道用啥的時候就用gl_dynamic_draw。
使用glbufferdata之後原來緩衝區的所有東西會被刪除,重新進行填充。
如只想更新部分資料而不清空舊有,可以使用
void
glbuffersubdata
(glenum target, intptr offset, sizeiptr size,
const
void data*
);
為啥使用緩衝區。
在使用緩衝區的時代之前,要向opengl傳遞紋理需要通過cpu先把內容複製到ram,再在需要的時候,命令cpu把內容從ram傳給opengl。壞處有二:
使用緩衝區之後,這一過程變成了:cpu把內容交給pbo,而pbo是opengl管理的(也即是gpu管理),在需要的時候opengl直接通過dma(直接訪問)來讀取pbo,不需要經過cpu。這就是非同步過程,不影響cpu週期。
圖如下:
以上均整理自:
關於pack和unpack。
在gl_pixel_pack_buffer模式下時,使用glreadpixels可以從幀快取讀取畫素寫到pbo。
在gl_pixel_unpack_buffer模式下,使用gldrawpixels把畫素從pbo寫入幀快取。
使用void* glmapbuffer(target, access)
可以獲得位址,如果找不到會返回nullptr。
target可能的值有:
access可能的值:
如果gpu正在操作這個buffer,glmapbuffer就會一直等待直到gpu同步完buffer資訊。為了避免這個無用的等待,最好就是使用空指標來呼叫glbufferdata,這會讓這塊空記憶體上啥都沒有,然後馬上呼叫glmapbuffer。這時,opengl會丟棄老的buffer,然後重新分配一塊新的記憶體給它。
注意:
在使用完pbo之後,必須呼叫glunmapbuffer(),如果成功了,會返回乙個gl_true。
在分配的時候沒啥要注意的,如果是為紋理分配,那分配的空間就是長*寬*畫素大小。
從當前幀獲取畫素資料,使用glreadpixels。
不使用pbo:
void
*data =
(void*)
malloc
(pixeldatasize)
;glreadbuffer
(gl_back_left)
;glreadpixels(0
,0,getwidth()
,getheight()
, gl_rgb, gl_unsigned_btye, pixeldata)
;
使用pbo:
glreadbuffer
(gl_back_left)
;glbindbuffer
(gl_pixel_pack_buffer, pixbuffobjs[0]
);glreadpixels(0
,0,getwidth()
,getheight()
, gl_rgb, gl_unsigned_byte,
null
);
這就把資料讀入了pbo。
使用pbo來做模糊效果。思路是儲存前面五幀來和當前幀做混合。
說一下主要套路:
setup階段
從硬碟讀出bmp紋理
申請6個texture,全都用bmp紋理初始化
申請乙個buffer並初始化,初始化的內容可以是空指標,但大小一定要指定
// 這個時候啥功能都可以,pack或者unpack都行
glbindbuffer
(gl_pixel_pack_buffer, g_bufferobjs[0]
);glbufferdata
(gl_pixel_pack_buffer, size, dataptr, gl_dynamic_draw)
;// 解綁
glbindbuffer
(gl_pixel_pack_buffer,0)
;
render階段
從螢幕把畫素打包到buffer
glbindbuffer
(gl_pixel_pack_buffer, g_bufferobjs[0]
);glreadpixels(0
,0, screenwidth, screenheight, gl_rgb, gl_unsigned_byte,
nullptr);
glbindbuffer
(gl_pixel_pack_buffer,
*g_bufferobjs)
;
這個時候buffer裡面已經是慢慢的螢幕資訊啦!接下來要從buffer裡面把資訊寫入到texture。先把buffer先切到解包模式,才能寫入到texture或者螢幕,然後切換到目標texture,寫入,最後解綁buffer。
glbindbuffer
(gl_pixel_unpack_buffer,
*g_bufferobjs)
;glactivetexture
(gl_texture0 +
getblurtarget0()
);// 當資料是nullptr的時候,就讀緩衝區~
glteximage2d
(gl_texture_2d,
0, gl_rgb, screenwidth, screenheight,
0, gl_unsigned_byte,
null
);
最後一步是改寫shader。片段shader要去讀0~5號sampler,然後把結果疊加起來! 讀書筆記 OpenGL超級寶典
對於某些函式的理解 glclear和glclearcolor glclearcolor指定glclear清除特定緩衝區時使用的值。glflush 讓所有已傳送的命令盡快的由實際的繪製引擎執行。glviewport 前兩個引數指的是左下角。glpushmatrix glrotatef glbegin和...
OpenGL 3D 超級寶典學習筆記
2d笛卡兒座標 由乙個x座標和乙個y座標構成,x座標測量水平方向的位置,而y座標則測試垂直方向的位置,原點 x 0,y 0 兩根軸從負無窮擴充套件到正無窮,兩軸垂直相交。視口viewport 裁剪區域的高度與寬度一般不與視窗的寬度與高度相匹配,因此座標系統從邏輯笛卡兒座標對映到物理螢幕畫素座標,這種...
openGL超級寶典 筆記 8 1緩衝區
特性 緩衝區儲存在gpu視訊記憶體中,可提供高速高效的訪問視訊記憶體的方式。作用 可以將資料從乙個渲染管線移動到另乙個渲染管線 gpu視訊記憶體中 可以從乙個物件繫結到另乙個物件.可以將gpu中資料移動到合適位置,不需cpu介入。如pbo移動資料到texture中 緩衝區的建立,binding,刪除...