I would like to draw different points with different colors. I put the vertex location data and color data in different VBOs, such as below:
Here is my C++ code:
m_Points.push_back(glm::vec3(4, 0, 0));
m_Points.push_back(glm::vec3(0, 2, 0));
m_Points.push_back(glm::vec3(0, 0, 3));
m_Points.push_back(glm::vec3(0, 0, 6));
m_Colors.push_back(glm::vec3(0, 1.0, 0));
m_Colors.push_back(glm::vec3(1.0, 0, 0));
m_Colors.push_back(glm::vec3(0, 0, 1.0));
m_Colors.push_back(glm::vec3(1.0, 1.0, 0));
glEnable(GL_PROGRAM_POINT_SIZE);
glGenVertexArrays(1, &m_VAO);
glBindVertexArray(m_VAO);
// the first VBO, it is the coordinates
glGenBuffers(1, &m_VBO);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * sizeof(m_Points), &m_Points[0][0], GL_DYNAMIC_DRAW);
// the second VBO, the color
glGenBuffers(1, &m_VBO_Color);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO_Color);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * sizeof(m_Colors), &m_Colors[0][0], GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
// in file axis.vs, there is a statement
// layout (location = 0) in vec3 vertex;
// the first argument 0 means (location = 0)
glVertexAttribPointer(0, // location = 0 in vertics shader file
3, // the position has X,Y,Z 3 elements
GL_FLOAT, // element type
GL_FALSE, // do not normalize
sizeof(glm::vec3), // Stride
(void *) nullptr); // an offset of into the array, it is 0
glEnableVertexAttribArray(1);
// in file axis.vs, there is a statement
// layout (location = 1) in vec3 vertex;
// the first argument 1 means (location = 1)
glVertexAttribPointer(1, // location = 1 in vertics shader file
3, // the position has R,G,B 3 elements
GL_FLOAT, // element type
GL_FALSE, // do not normalize
sizeof(glm::vec3), // Stride
(void *) nullptr); // an offset of into the array, it is 0
glBindVertexArray(0);
Both the m_Points and m_Colors are some kind of std::vector<glm::vec3>
Here is my vertex shader and frame shader:
layout (location = 0) in vec3 vertex;
layout (location = 1) in vec3 color;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
out vec3 ObjectColor;
void main()
{
gl_Position = projection * view * model * vec4(vertex, 1.0);
gl_PointSize = 10.0;
ObjectColor = color;
}
#version 330 core
in vec3 ObjectColor;
out vec4 FragColor;
void main()
{
FragColor = vec4(ObjectColor, 1.0f);
}
The draw code looks like below:
shader.use();
glBindVertexArray(m_VAO);
glDrawArrays(GL_POINTS, 0, m_Points.size());
But I would like to add some points dynamically by AddPoint()
function, so here is the code to add both vertex and color element in the vectors:
void AddPoint()
{
glm::vec3 p(5.0, 6.0, 0.0);
m_Points.push_back(p);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * m_Points.size(), &m_Points[0][0], GL_DYNAMIC_DRAW);
glm::vec3 b(1.0, 0.0, 0.0);
m_Colors.push_back(b);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO_Color);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * m_Colors.size(), &m_Colors[0][0], GL_DYNAMIC_DRAW);
}
The problem is: the initial 4 points shows correctly with 4 different colors, but the AddPoint() never works, I don't see any new points added and rendered.
I know that if I put the vertex location in a single VBO,
such as:
The date array could be:
x, y, z, r, g, b
x, y, z, r, g, b
x, y, z, r, g, b
x, y, z, r, g, b
it works without any issue.
But why it does not work if I put the location and color in different VBOs?
Any ideas? Thanks.
This question(c++ - Storing different vertex attributes in different VBO's - Stack Overflow) is related, but I still don't know why my problem still happens.
EDIT
Rabbid76 point out that glVertexAttribPointer()
function only attach(copy) data from the previous bond VBO by glBindBuffer
. Which suggest that I can't put the vertex location array and vertex color array in different VBOs?
EDIT2
Is my AddPoint()
function wrong here?
glVertexAttribPointer
associated the buffer object, which is bound to the GL_ARRAY_BUFFER
target, to the specified attribute. The specification is stored in the state vector of the current Vertex Array Object.
The proper buffer object has to be bound by glBindBuffer
, before glVertexAttribPointer
is invoked:
// the first VBO, it is the coordinates
glGenBuffers(1, &m_VBO);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * sizeof(m_Points), &m_Points[0][0], GL_DYNAMIC_DRAW);
// the second VBO, the color
glGenBuffers(1, &m_VBO_Color);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO_Color);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * sizeof(m_Colors), &m_Colors[0][0], GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO); // <--- bind `m_VBO`
glVertexAttribPointer(0, // location = 0 in vertics shader file
3, // the position has X,Y,Z 3 elements
GL_FLOAT, // element type
GL_FALSE, // do not normalize
sizeof(glm::vec3), // Stride
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO_Color); // <--- bind `m_VBO_Color`
glVertexAttribPointer(1, // location = 1 in vertics shader file
3, // the position has R,G,B 3 elements
GL_FLOAT, // element type
GL_FALSE, // do not normalize
sizeof(glm::vec3), // Stride
(void *) nullptr); // an offset of into the array, it is 0