OpenGL3 0教程 第九課 VBO索引

2021-07-05 11:35:46 字數 2037 閱讀 9479

分類: opengl es

opengl3.0教程

目前為止,建立vbo時我們總是重複儲存一些共享的頂點和邊。

本課將介紹索引技術。借助索引,我們可以重複使用乙個頂點。這是用索引緩衝區(index buffer)來實現的。

索引緩衝區儲存的是整數;每個三角形有三個整數索引,用索引就可以在各種屬性緩衝區(頂點座標、顏色、uv座標、其他uv座標、法向緩衝區等)中找到頂點的資訊。這有點像obj檔案格式,但有一點相差甚遠:索引緩衝區只有乙個。這意味著若兩個三角形共用乙個頂點,那這個頂點的所有屬性對兩個三角形來說都是一樣的。

來看看法向的例子。下圖中,藝術家建立了兩個三角形,試圖模擬乙個平滑曲面。可以把兩個三角形的法向融合成乙個頂點的法向。為方便**,我畫了一條紅線表示平滑曲面。

然而在第二幅圖中,美工想畫的是「縫隙」或「邊緣」。若融合了法向,就意味著色器會像前例一樣進行平滑插值,生成乙個平滑的表面:

因此在這種情況下,把頂點的法向分開儲存反而更好;在opengl中,唯一實現方法是:把頂點連同其屬性完整複製乙份。

索引的用法很簡單。首先,需要建立乙個額外的緩衝區存放索引。**與之前一樣,不過引數是element_array_buffer,而非array_buffer。

std::vector indices;

// fill "indices" as needed

// generate a buffer for the indices

gluint elementbuffer;

glgenbuffers(1, &elementbuffer);

glbindbuffer(gl_element_array_buffer, elementbuffer);

glbufferdata(gl_element_array_buffer, indices.size() * sizeof(unsigned int), &indices[0], gl_static_draw);

只需把`gldrawarrays`替換為如下語句,即可繪製模型:

// index buffer

glbindbuffer(gl_element_array_buffer, elementbuffer);

// draw the ********s !

gldrawelements(

gl_********s, // mode

indices.size(), // count

gl_unsigned_int, // type

(void*)0 // element array buffer offset

);

現在遇到真正的問題了。如前所述,opengl只能使用乙個索引緩衝區,而obj(及一些其他常用的3d格式,如collada)每個屬性都有乙個索引緩衝區。這意味著,必須通過某種方式把若干個索引緩衝區合併成乙個。

合併演算法如下:

for each input vertex

try to find a similar ( = same for all attributes ) vertex between all those we already output

if found :

a similar vertex is already in the vbo, use it instead !

if not found :

no similar vertex found, add it to the vbo

完整的c++**位於common/vboindexer.cpp,注釋很詳盡。如果理解了以上演算法,讀懂**應該沒問題。

若兩頂點的座標、uv座標和法線都相等,則認為兩頂點是同一頂點。若還有其他屬性,這一標準得酌情修改。

為了表述的簡單,我們採用了蹩腳的線性查詢來尋找相似頂點。實際中用std::map會更好。

雖然和索引沒有直接關係,但現在去看看「fps計數器」是很合適的——這樣我們就能看到,索引究竟能提公升多少效能。「工具——偵錯程式」中還有些其他和效能相關的工具。

標籤: none

OpenGL教程翻譯 第九課 插值

本章講述三維渲染管線中的乙個非常重要的部分 插值,它是光柵器對從頂點著色器輸出的變數所做的操作。正如你已經看到的,為了在螢幕上得到一些有意義的東西,你需要指定vs輸出變數中的乙個為 gl position 這是乙個四維向量,含有頂點的其次座標。這個變數中的xyz分量被除以其w分量 這是乙個透視分割的...

VBScript教程 第九課VBScript過程

vb教程 vbscript過程 過程分類 在 vbscript 中,過程被分為兩類 sub 過程和 function 過程。sub 過程 sub 過程是包含在 sub 和 end sub 語句之間的一組 vbscript 語句,執行操作但不返回值。sub 過程可以使用引數 由呼叫過程傳遞的常數 變數...

第九課 變數

任務與 修改 沒有定義變數r,在第四行float r1,r2之後加上r就可以 include include intmain 閱讀程式 閱讀下面的程式,在閱讀過程中,請為每乙個變數畫出乙個方框,代表對應的記憶體空間。隨著閱讀,標明變數的變化過程,達到讀懂程式的目的。include intmain 圖...