운이 좋다. 프로그램의 구조는 이미 모든 것을 갖추고 있습니다. 우리는 짜증나는 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);
데이터에 대한 공간을 할당 사본을 정점 데이터 버퍼로. 여러분의 정점 요소 인덱스 배열이 1만큼 이동 되었기 때문에 하나의 정점을 더 할당하고 오프셋을 사용하여 그 정점에 데이터를 복사합니다 (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 기능 을 사용하여 일부 요소를 저장하는 요소의 총 개수를 결정합니다. 그래서 iterator를 사용할 수 있도록), 나중에 우리는 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를 가지고 있어야 함)를 사용할 수 있지만, 그렇게 해 둡시다. VBO 그리기는 클라이언트 측 정점 배열에서 그리는 것과 매우 유사합니다. 이제 고정 기능 파이프 라인을 사용하고 있음을 나타내는 glVertexPointer
을 사용했습니다. 우리는 그것을 사용할 수 있습니다. 그러나 VBO는 OpenGL-3에서만 OpenGL 핵심 기능이되었습니다 (이전에는 확장 기능으로 오랫동안 사용할 수있었습니다). 따라서 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 : Bind와 같은 패턴으로 포인터에 대한 정수 오프셋을 캐스팅하여 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);
}