在现代OpenGL中使用索引绘制绘制立方体

时间:2019-05-12 14:40:06

标签: opengl glfw glew

我正在尝试使用OpenGL 3.3中的索引绘制绘制一个立方体。但这并没有显示出来... 这是我尝试做的。

GLfloat vertices01[] = {
  -1.0f,1.0f,0.0f,
  -1.0f,-1.0f,0.0f,
  1.0f,1.0f,0.0f,
  1.0f,-1.0f,0.0f,
  -1.0f,1.0f,-1.0f,
  -1.0f,-1.0f,-1.0f,
  1.0f,1.0f,-1.0f,
  1.0f,-1.0f,-1.0f
};
unsigned int indices01[] = {
  0, 2, 3, 1,
  2, 6, 7, 3,
  6, 4, 5, 7,
  4, 0, 1, 5,
  0, 4, 6, 2,
  1, 5, 7, 3
};


Mesh* obj3 = new Mesh();
obj3->CreateMesh(vertices01, indices01, 24, 24);
meshList.push_back(obj3);

meshList[0]->RenderMesh();

//在网格类别中     indexCount = numOfIndices;

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);

glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0])*numOfIndices, indices, GL_STATIC_DRAW);

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0])*numOfVertices, vertices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glBindVertexArray(0);

glBindVertexArray(VAO);

//bind ibo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

glDrawElements(GL_TRIANGLES,indexCount, GL_UNSIGNED_INT, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);

输出显示一个局部立方体,每个立方体的每个侧面分别有一个三角形和一个穿过对角线的三角形

1 个答案:

答案 0 :(得分:1)

如果使用兼容性配置文件上下文,则可以使用GL_QUADS而不是GL_TRIANGLES来保留索引。但这已被弃用(Legacy OpenGL)。

由于基本类型为GL_TRIANGLES,因此立方体的每一侧必须由2个三角形形成。参见Triangle primitives

更改索引缓冲区以解决该问题:

unsigned int indices01[] = {
  0, 2, 3, 0, 3, 1,
  2, 6, 7, 2, 7, 3,
  6, 4, 5, 6, 5, 7,
  4, 0, 1, 4, 1, 5,
  0, 4, 6, 0, 6, 2,
  1, 5, 7, 1, 7, 3,
};

另一种解决方案是使用原始类型GL_TRIANGLE_STRIPPrimitive Restart索引。

启用原始重启并定义重启索引:

例如

glEnable( GL_PRIMITIVE_RESTART );
glPrimitiveRestartIndex( 99 );

定义2个三角带,由重新启动索引分隔:

unsigned int indices01[] = {
    0, 1, 2, 3, 6, 7, 4, 5,
    99, // 99 is the restart index
    7, 3, 5, 1, 4, 0, 6, 2
};
int indexCOunt = 17;

并绘制元素:

glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);

请注意,Index buffer绑定存储在Vertex Array Object中。
因此,在设置VAO时,一次绑定索引缓冲区就足够了:

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);  

// [...]

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

// [...]

// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); <---- delete this

glBindVertexArray(0);

然后在绘制调用之前再次绑定索引缓冲区是多余的:

glBindVertexArray(VAO);

// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); <---- now this is superfluous 

glDrawElements(GL_TRIANGLES,indexCount, GL_UNSIGNED_INT, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);