你很幸運。你的程序結構已經包含了一切。我們甚至可以避開那個煩人的基於1的索引。
首先創建一個VBO:
GLuint vbo_id;
GLuint eabo_id; /* EIB = Element Array Buffer */
size_t eabo_n_elements;
void make_vbo()
{
GLuint genbuf_ids;
glGenBuffers(2, genbuf_ids);
vbo_id = genbuf_ids[0];
eabo_id = genbuf_ids[1];
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
分配空間的數據,任何拷貝頂點數據到緩衝區中。由於您的頂點元素索引數組移動了一個,所以我們爲其中一個頂點分配更多的數據並將其複製到偏移量中(我們也可以使用GL_ARB_draw_elements_base_vertex
擴展名,但我想這樣展示它:
glBufferData(
GL_ARRAY_BUFFER,
(vertexCoords.size() + 3)*sizeof(vertexCoords[0]),
NULL,
GL_STATIC_DRAW);
glBufferSubData(
GL_ARRAY_BUFFER,
sizeof(vertexCoords[0])*3, /* offset by 1 vertex */
(vertexCoords.size())*sizeof(vertexCoords[0],
&vertexCoords[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
對於元素數組緩衝區也是一樣的;你將兩個向量「堆棧」在一起......這種方法效率不高,讓我們展開這個,首先爲緩衝區分配內存,但不要複製數據,因爲每個子向量可能具有不同的長度(儘管如果用於特定的原始繪製模式,它們應該都是相同的大小)首先確定元素的總數(使用C++ 11功能auto
來保存一些輸入並且我們可以使用迭代器);稍後我們需要知道這個num BER吸引他們:
eabo_n_elements = 0;
for(auto i = faces.begin(); i != faces.end(); i++) {
eabo_n_elements += i.size();
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eabo_id);
glBufferData(
GL_ELEMENT_ARRAY_BUFFER,
sizeof(faces[0][0]) * eabo_n_elements,
NULL,
GL_STATIC_DRAW);
展開拷貝面部數據到EAB
size_t offset = 0;
for(auto i = faces.begin(); i != faces.end(); i++) {
size_t const len = i.size() * sizeof(i[0]);
glBufferSubData(
GL_ELEMENT_ARRAY_BUFFER,
offset,
len,
&i[0]);
offset += len;
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
現在我們可以得出。從技術上講,我們可以使用VAO(並且使用OpenGL-4,我們必須擁有一個),但我們要保證這一點。繪製VBOs與從客戶端頂點數組繪製非常相似。現在您使用了glVertexPointer
這表明您正在使用固定功能流水線。我們可以使用它。但是,然後,維也納組織成爲OpenGL核心功能,只有OpenGL-3(在此之前它已經作爲一個擴展可用很長時間)。所以它是glVertexAttribPointer
加上匹配的着色器。爲了保持儘可能小的過渡,讓我們回收您使用glVertexPointer
。主要的區別是,我們使glVertexPointer
呼叫之前結合VBO並傳遞一個integer-cast-to-a-pointer (which actually may invoke UB for anything other than 0)偏移到數據參數:
void draw_vbo()
{
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glVertexPointer(3, GL_FLOAT, 0, (void*)0);
一旦VBO已經「鏈接」到一個頂點數組訪問,我們可以解除綁定。數據仍將從VBO中獲取。
glBindBuffer(GL_ARRAY_BUFFER, 0);
最後進行繪製調用。請記住,我們在將頂點數據複製到VBO時應用了1單元的偏移量。所以我們只是通過臉部頂點元素索引。與VBO的模式相同:綁定,將指數轉換爲指針並將其傳遞給glDrawElements
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eabo_id);
glDrawElements(GL_TRIANGLE_STRIP, eabo_n_elements, GL_UNSIGNED_INT, (void*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}