سؤال

I'm trying to draw a rectangle using vbo.

If I draw triangle - it works fine

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);
}

But when I try to draw a rectangle - it still shows only first triangle. The only difference is in the constructor

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);
}

What's the problem?

EDIT If I draw rectangle like this

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);
}

and change glDrawArrays(GL_TRIANGLES, 0, 3); toglDrawArrays(GL_QUADS, 0, 4); it shows a rectangle correctly. But I want to draw it as two triangles.

هل كانت مفيدة؟

المحلول

glDrawArrays(GL_TRIANGLES, 0, 3); draws only 3 vertices if I understand correctly. So if you are only changing your constructor, and not your draw(), you are still only drawing 3 vertices. So instead draw 6 verts for your rectangle.

Edit

You are also only buffering 3 items

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

So what you might want to do is keep track of how many verts make up your model and then whenever you hand them over to OpenGL, you let it know what is going on. So, you need to buffer 6 verts instead of 3 and you need to draw 6 verts instead of 3.

Edit 2

Also, I think you have mismatched wind orders. Your first triangle is created counter-clockwise but your second is made clockwise. That means you are seeing the back of the triangle. Try changing it to:

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
};

نصائح أخرى

The problem is that you're using VAO related functions, without ever creating the VAO itself.

Creating VBO with VAO

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);

Instead of just passing 0 to glEnableVertexAttribArray() and glVertexAttribPointer() you could/would pass an actual attribute location from/in a Shader. Like so.

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

Also instead of using glGetAttribLocation() you would use glBindAttribLocation().

Rendering

When rendering the VAO, you only now need to bind the VAO and then do the regular glDrawArrays()'s call.

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

Deleting

glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top