標籤:兩種方法 兩種 put 方法 add 原因 UI 建立 順序
本節將採用兩種方法繪製兩個三角形。
先看第一種方法的代碼
MyGlWindow.cpp
1 #include <gl\glew.h> 2 #include "MyGlWindow.h" 3 4 void MyGlWindow::initializeGL() 5 { 6 glewInit(); 7 8 GLfloat verts[] = 9 {10 +0.0f, +0.0f,11 +1.0f, +1.0f,12 -1.0f, +1.0f,13 14 +0.0f, +0.0f,15 -1.0f, -1.0f,16 +1.0f, -1.0f,17 };18 GLuint myBufferID;19 glGenBuffers(1, &myBufferID);20 glBindBuffer(GL_ARRAY_BUFFER, myBufferID);21 glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);22 glEnableVertexAttribArray(0);23 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);24 }25 26 void MyGlWindow::paintGL()27 {28 glViewport(0, 0, width(), height());29 glDrawArrays(GL_TRIANGLES, 0, 6);30 }
和上一節的代碼很相似,區別是verts數組增加了6個元素(能額外表示3個頂點),另外glDrawArrays()函數的最後一個參數變成了6,表示繪製六個頂點。這樣當然就可以繪製2個三角形了。
但是這種方法造成了一個浪費,代碼中可以看到兩次出現了(0.0,0.0)點。
EBO
OpenGL允許我們提供一個索引數組用來指定三角形的頂點組成順序。這個數組通常被稱為EBO。
看第二種繪製三角形的方法:
1 #include <gl\glew.h> 2 #include "MyGlWindow.h" 3 4 void MyGlWindow::initializeGL() 5 { 6 glewInit(); 7 8 GLfloat verts[] = 9 {10 +0.0f, +0.0f, //011 +1.0f, +1.0f, //112 -1.0f, +1.0f, //213 -1.0f, -1.0f, //314 +1.0f, -1.0f, //415 };16 GLuint vertexBufferID;17 glGenBuffers(1, &vertexBufferID);18 glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);19 glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);20 glEnableVertexAttribArray(0);21 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);22 23 GLushort indices[] =24 {25 0,1,2,26 0,3,4,27 };28 GLuint indexBufferID;29 glGenBuffers(1, &indexBufferID);30 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);31 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);32 }33 34 void MyGlWindow::paintGL()35 {36 glViewport(0, 0, width(), height());37 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);38 }
*註:為了區分兩個Buffer,我們這裡把之前的myBufferID改名為vertexBufferID
23-31行和頂點位置設定代碼(8-19行)非常相似。
28-29行建立了另外一個BufferObject- indexBuffer
30行把indexBuffer綁定到GL_ELEMENT_ARRAY_BUFFER綁定點上
31行對其填充資料,其資料內容是一個GLushort類型的數組,每三個元素表示一個三角形的頂點索引,索引值是相對於verts數組來說的(參考verts中的注釋)。這裡使用GLushort而不使用GLint的原因是GLushort給了我們更大的資料存放區量,索引始終都是正整數,所以使用unsigned類型更合理。
在paintGL函數中,這次不使用glDrawArrays函數了,改用glDrawElements()函數繪製
第二個參數表示6個頂點
第三個參數表示indices數組的類型
第四個參數表示位移值
使用EBO在本例中僅節約了一個頂點位置資料,但是在複雜的模型中,會節約非常多的資料。
3D Computer Grapihcs Using OpenGL - 05 EBO