<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 第九課:VBO索引 ## 索引的原理 目前為止,建立VBO時我們總是重復存儲一些共享的頂點和邊。 本課將介紹索引技術。借助索引,我們可以重復使用一個頂點。這是用*索引緩沖區(index buffer)*來實現的。 ![indexing1.png](https://box.kancloud.cn/2015-11-02_5636f305c8f3e.png) 索引緩沖區存儲的是整數;每個三角形有三個整數索引,用索引就可以在各種*屬性緩沖區*(頂點坐標、顏色、UV坐標、其他UV坐標、法向緩沖區等)中找到頂點的信息。這有點像OBJ文件格式,但有一點相差甚遠:索引緩沖區只有一個。這意味著若兩個三角形共用一個頂點,那這個頂點的所有屬性對兩個三角形來說都是一樣的。 ## 共享vs分開 來看看法向的例子。下圖中,藝術家創建了兩個三角形,試圖模擬一個平滑曲面。可以把兩個三角形的法向融合成一個頂點的法向。為方便觀看,我畫了一條紅線表示平滑曲面。 ![goodsmooth](https://box.kancloud.cn/2015-11-02_5636f305dac79.png) 然而在第二幅圖中,美工想畫的是“縫隙”或“邊緣”。若融合了法向,就意味著色器會像前例一樣進行平滑插值,生成一個平滑的表面: ![badmooth](https://box.kancloud.cn/2015-11-02_5636f305e70c7.png) 因此在這種情況下,把頂點的法向分開存儲反而更好;在OpenGL中,唯一實現方法是:把頂點連同其屬性完整復制一份。 ![spiky](https://box.kancloud.cn/2015-11-02_5636f306000fd.png) ## OpenGL中的索引VBO 索引的用法很簡單。首先,需要創建一個額外的緩沖區存放索引。代碼與之前一樣,不過參數是`ELEMENT_ARRAY_BUFFER`,而非`ARRAY_BUFFER`。 ~~~ std::vector<unsigned int> 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 triangles ! glDrawElements( GL_TRIANGLES, // mode indices.size(), // count GL_UNSIGNED_INT, // type (void*)0 // element array buffer offset ); ~~~ (小提示:最好使用`unsigned short`,不要用`unsigned int`。這樣更節省空間,速度也更快。) ## 填充索引緩沖區 現在遇到真正的問題了。如前所述,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計數器 雖然和索引沒有直接關系,但現在去看看“FPS計數器”是很合適的——這樣我們就能看到,索引究竟能提升多少性能。[“工具——調試器”](http://www.opengl-tutorial.org/miscellaneous/useful-tools-links/#header-4)中還有些其他和性能相關的工具。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看