關於VBO的一些東西

2021-06-22 17:45:34 字數 2610 閱讀 6274

有時候你不得不承認,opengl的開發真的不如directx,特別對於入門的人來說,乙個簡單的概念可以讓我嚼上幾天不得騎姐。

vbo可以說是opengl中里程碑似的東西,通過vbo我們可以把需要渲染的圖元的頂點資訊,直接上傳儲存在gpu的視訊記憶體中。

由於最早的opengl不支援例項化繪製,導致在繪製大量相似圖元的時候,需要反覆向gpu提交**渲染,這點在opengl中的二次方圖元和例項化繪製已經提到過了,會嚴重導致瓶頸效應,而vbo的誕生正好解決了這一問題,當然這特性需要opengl3.1以上或者擴充套件的支援。

說到vbo自然要說到vao,但是實際上兩者可以完全不相關,只是了解了vao的機制,跟容易了解vbo而已。

說到底,vbo就是通過那幾個函式,在gpu視訊記憶體中建立一塊buffer,用於儲存和頂點以及其屬性相關的資訊。

了解了vao並且了解了頂點陣列和頂點索引以後,我們才可以進一步去了解vbo的使用。

所謂的頂點陣列,就是如下的東西:

glfloat vertices = ;

上面是乙個立方體的一共8個頂點,而頂點索引即如下

static glshort frontindices = ;

上面這個索引只包含了立方體的四個頂點即其中乙個面而已

然後我們將這些個頂點陣列和頂點索引上傳至gpu的視訊記憶體,如下

glgenbuffers(3,buffers);//建立3塊buffer

glbindbuffer(gl_array_buffer, buffers[0]);//先將第一塊buffer繫結到當前

glbufferdata(gl_array_buffer, sizeof(vertices),vertices, gl_static_draw);//將頂點陣列放入這個buffer

glvertexpointer(3, gl_float, 0, 0);

//指定這個buffer的格式,3代表3個float值為乙個頂點,第乙個0代表跨度,這裡數值是緊密排列的,最後乙個是陣列的入口位址*point,由於已經將buffer繫結到當前,所以填0

glenableclientstate(gl_vertex_array);//使用這個buffer,一定不要忘記

glbindbuffer(gl_array_buffer, buffers[1]);//這裡開始是將第二塊buffer繫結到當前,上傳color資料,和頂點的做法一樣,不多贅述了

glbufferdata(gl_array_buffer, sizeof(colors), colors, gl_static_draw);

glcolorpointer(3, gl_float, 0, 0);

glenableclientstate(gl_color_array);

glbindbuffer(gl_element_array_buffer, buffers[2]);//將第三塊buffer繫結到當前,用於上傳儲存頂點索引的資料,因此buffer型別變更為gl_element_array_buffer

glbufferdata(gl_element_array_buffer, sizeof(frontindices),frontindices,gl_static_draw);//同樣是對buffer進行填充

經過以上**,某個圖元的頂點位置以及顏色和索引資訊就已經放入gpu了,接下來只要在display函式中,呼叫gldrawelements就可以繪製了

gldrawelements(gl_quads, 4, gl_unsigned_short, buffer_offset(0));//由於索引定義的是4個點,因此第乙個引數mode是四邊形,第二個是索引的size,第三個是索引的資料型別。注意!gldrawelements只接受3種資料型別,當時我因為指定索引型別為gl_int導致無法繪製被卡住了n長時間,坑人啊!最後乙個是指標位址,由於當前繫結的buffer是buffer[2],因此填0即可。

最後別忘記了,vbo是需要glew庫支援的,所以要記得在標頭檔案中新增

需要補充的是,關於另外乙個函式:glvertexattribpointer

這個函式可以在很多人的**中見到,普遍是用於glsl。什麼是glsl,想想我就頭大,簡單圖形的繪製完全用不到自己編寫渲染器,自定義的渲染器這塊內容我覺得和opengl本身一樣水深的很,如果不是從事3d遊戲開發,完全沒必要去碰。言歸正傳,因為大量的這個函式的例子都出現在glsl中,所以我也是費了很大的勁才搞清楚如何將它用在簡單的opengl函式中。

簡單的來說,它和之前我們用的glvertexpointer是同乙個東西,只是如果用了glvertexattribpointer,那麼我們就不需要死板的只指定vertice為頂點位置,而是可以建立乙個包含了所有頂點位置+頂點顏色+頂點法線+頂點***的陣列,通過一次將其送入視訊記憶體,然後呼叫glvertexattribpointer索引其屬性就可以實現。比方說我有個attrib陣列,前3位為位置,後面依次為顏色,法線,這樣子就有3個index,依次為0,1,2.在呼叫glvertexattribpointer的時候,先 glenablevertexattribarray(0);  使能,在用**glvertexattribpointer(0,3,gl_float, gl_false, 0,0);就表示指定了buffer中的第乙個索引為pos,然後用,顏色和法線如法炮製。

總結:其實vbo是很簡單的東西,實現也是很簡單的概念,但是大量的文章不是把關鍵的地方省略了,就是說的不夠通俗易懂,所以還是比較坑人的

關於堆,棧的一些東西

堆和棧的區別 1 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 u 1 棧區 stack 由編譯器自動分配釋放 由編譯器在需要的時候分配,在不需要的時候自動清除 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。u 2 堆區 heap 一般由程式...

關於爬蟲的一些東西

這幾天在寫乙個爬蟲,實際上整個過程和思路很簡單,難點在於繁雜的格式處理和一些未知的小問題,還有對python不太熟悉.基本上是邊學邊寫.記錄一些過程中值得記住的東西.關於python的 1.檔案的開頭要用 coding utf 8 2.建立資料夾可以要import os os.mkdir r new...

關於 media的一些東西

首先,media是css3的新增的標籤,主要的用途就是可以根據不同的螢幕你可以定義不同的樣式來實現響應式布局 先了解一下官方是怎麼定義的吧 使用 media 查詢,你可以針對不同的 型別定義不同的樣式。media 可以針對不同的螢幕尺寸設定不同的樣式,特別是如果你需要設定設計響應式的頁面,media...