使用vbo绘制矩形

时间:2013-12-27 16:03:01

标签: opengl vbo

我正在尝试使用vbo绘制一个矩形。

如果我绘制三角形 - 它可以正常工作

Character::Character() {
   float arr[9] = {
      -0.5, -0.5, 0,
      0.5, -0.5, 0,
      -0.5, 0.5, 0,
   };
   vertices.insert(vertices.begin(), arr, arr + 9);
}
void Character::init() {
   glGenBuffers(1, &vertexbuffer);
   glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
   glBufferData(GL_ARRAY_BUFFER, sizeof (vertices) * 3, &vertices[0], GL_STATIC_DRAW);
}
void Character::draw() {
   glEnableVertexAttribArray(0);
   glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
   glDrawArrays(GL_TRIANGLES, 0, 3);
   glDisableVertexAttribArray(0);
}

但是当我尝试绘制一个矩形时 - 它仍然只显示第一个三角形。唯一的区别在于构造函数

Character::Character() {
   float arr[18] = {
      -0.5, -0.5, 0,
      0.5, -0.5, 0,
      -0.5, 0.5, 0,

      -0.5, 0.5, 0,
      0.5, 0.5, 0,
      0.5, -0.5, 0
   };
   vertices.insert(vertices.begin(), arr, arr + 18);
}

有什么问题?

修改 如果我像这样绘制矩形

Character::Character() {
float arr[12] = {   
                    -0.5, -0.5, 0,    
                    0.5, -0.5, 0,    
                    0.5, 0.5, 0,
                    -0.5, 0.5, 0 
                };
vertices.insert(vertices.begin(), arr, arr + 12);
}

并将glDrawArrays(GL_TRIANGLES, 0, 3);更改为glDrawArrays(GL_QUADS, 0, 4);,它会正确显示一个矩形。但我想把它画成两个三角形。

2 个答案:

答案 0 :(得分:1)

如果我理解正确的话,

glDrawArrays(GL_TRIANGLES, 0, 3);只会绘制3个顶点。因此,如果您只是更改构造函数而不是draw(),那么您仍然只绘制3个顶点。因此,为您的矩形绘制6个顶点。

修改

你也只是缓冲3项

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

所以您可能想要做的是跟踪构成模型的顶点数量,然后无论何时将它们交给OpenGL,您都可以知道发生了什么。因此,您需要缓冲6个顶点而不是3个顶点,您需要绘制6个顶点而不是3个顶点。

修改2

另外,我认为您的风订单不匹配。您的第一个三角形是逆时针创建的,但第二个是顺时针方向。这意味着你正在看到三角形的背面。尝试将其更改为:

float arr[18] = {
   -0.5, -0.5, 0,
   0.5, -0.5, 0,
   -0.5, 0.5, 0,

   0.5, 0.5, 0,
   -0.5, 0.5, 0,
   0.5, -0.5, 0
};

答案 1 :(得分:1)

问题是您正在使用VAO相关功能,而无需创建VAO本身。

使用VAO创建VBO

GLuint vao, vbo;

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

glGenBuffers(1, &vbo);

GLfloat vertices[] = {
    0.0f, 0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
};

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

您可以/将从/在Shader中传递实际属性位置,而不是仅仅将0传递给glEnableVertexAttribArray()glVertexAttribPointer()。像这样。

GLint position_attrib = glGetAttribLocation(shader_program_handle, "position");
glEnableVertexAttribArray(position_attrib);
glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

您也可以使用glBindAttribLocation()而不是glGetAttribLocation()

渲染

渲染VAO时,您现在只需要绑定VAO,然后进行常规glDrawArrays()的呼叫。

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

删除

glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);