I'm a newbie in OpenGL trying to learn VBO. I have two arrays (point0 with 3 points and point1 with 6 points). Suppose I have two separate VBO names and I initialize them:

glGenBuffers(1, &vbo0); 
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
glBufferData(GL_ARRAY_BUFFER, sizeof(point0), point0, GL_STATIC_DRAW);
glGenBuffers(1, &vbo1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glBufferData(GL_ARRAY_BUFFER, sizeof(point1), point1, GL_STATIC_DRAW);

In my display function, I have


// draw first triangle (point0) in red
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);

// draw second and third triangle (point1) in blue
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glVertexAttribPointer(0, 6, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);

I was expecting a red triangle from vbo0 and two blue triangles from vbo1. But I get a blue triangle from the points in array point0. Why is that?


2 Answers 2

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

This GL call is illegal; if we read the documentation for glVertexAttribPointer we will see:

Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4.

The correct value here would be 3; each triangle you draw has 3 components per point: x, y and z.

If you added some error checking to this you'd see that this call throws a GL_INVALID_VALUE error. The subsequent behaviour of other GL calls that depend on it is not explicitly defined, so may be reasonably assumed to be undefined, and anything can happen.

So step 1 in resolving your problem is to make sure that you have a legal GL program using correct GL calls; once you have that, you should be more easily able to identify the cause of any unwanted behaviours.

  • \$\begingroup\$ It works. I thought size was the number of floats. Should have read the docs carefully. Thanks. \$\endgroup\$ Nov 15, 2021 at 14:04

Your problem is this call:

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

In the documentation here size, parameter 2 should be between 1-4. You specified 6 because that is the amount of vertices you put. You should put the amount of floats that there are per position. Example: (0, 1, 2) 3 (1.0, 0.5).

GLuint index,
GLint size,
GLenum type,
GLboolean normalized,
GLsizei stride,
const GLvoid * pointer

I'm not gonna go over all of these since it is already in the documentation and my favorite one is https://docs.gl. I'm assuming that you don't understand much about glVertexAttribPointer() so i'll show you how you can use it. The first parameter index which is 0 is where we store all of our vert positions in a vec2/vec3. We can use this in our shader as

layout (location=0) in vec3 position

and use that data that we told OpenGL how to interpret. Since we gave them a vec3 we take in vec3 and name the variable whatever. We can use this variable for many things like gl_Position in our vertex shader.

#version 330 core
layout (location = 0) in vec3 aPos;
// layout (location = 1) in vec2 aTexCoord; we can do this if we want multiple things in our data and not just position for example color or textures as well

void main()
    gl_Position = aPos;

Overview of the thing, we told OpenGL to store data in location 0, we told them 1 piece is a vec3 and for every 3 items in our array we can assign this to one vec3, we told them that it is a float, that it is not normalized (read the docs please), and the offset for our each times is 0 because we want to check all items, the last one is the pointer and just read it yourself since I will probably explain it worse.

  • \$\begingroup\$ Thanks for the extras. All the docs I read says index "Specifies the index of the generic vertex attribute to be modified." Took me some a couple of hours to find an example that explains beyond the docs and also to tie it to the location in shaders. \$\endgroup\$ Nov 15, 2021 at 14:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .