OpenGL 在不同的 VBO 中绘制具有不同颜色、顶点位置和顶点颜色的点?
OpenGL draw points with different colors, vertex location and vertex color in different VBOs?
我想用不同的颜色画不同的点。我把顶点位置数据和颜色数据放在不同的VBO中,如下图:
这是我的 C++ 代码:
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);
m_Points 和 m_Colors 都是某种 std::vector<glm::vec3>
这是我的顶点着色器和帧着色器:
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);
}
绘制代码如下所示:
shader.use();
glBindVertexArray(m_VAO);
glDrawArrays(GL_POINTS, 0, m_Points.size());
但是我想通过AddPoint()
函数动态添加一些点,所以这里是在向量中添加顶点和颜色元素的代码:
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);
}
问题是:最初的 4 个点以 4 种不同的颜色正确显示,但 AddPoint() 始终不起作用,我没有看到任何新添加和渲染的点。
我知道如果我把顶点位置放在一个VBO中,
如:
日期数组可以是:
x, y, z, r, g, b
x, y, z, r, g, b
x, y, z, r, g, b
x, y, z, r, g, b
它没有任何问题。
但是为什么把location和color放在不同的VBO里就不行了?
有什么想法吗?谢谢。
这个问题(c++ - Storing different vertex attributes in different VBO's - Stack Overflow)是相关的,但我仍然不知道为什么我的问题仍然出现。
编辑
Rabbid76 指出 glVertexAttribPointer()
函数仅通过 glBindBuffer
附加(复制)来自先前绑定 VBO 的数据。这表明我不能将顶点位置数组和顶点颜色数组放在不同的 VBO 中?
EDIT2
我的 AddPoint()
功能在这里错了吗?
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.
调用 glBindBuffer
, before glVertexAttribPointer
必须绑定正确的缓冲区对象:
// 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
我想用不同的颜色画不同的点。我把顶点位置数据和颜色数据放在不同的VBO中,如下图:
这是我的 C++ 代码:
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);
m_Points 和 m_Colors 都是某种 std::vector<glm::vec3>
这是我的顶点着色器和帧着色器:
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);
}
绘制代码如下所示:
shader.use();
glBindVertexArray(m_VAO);
glDrawArrays(GL_POINTS, 0, m_Points.size());
但是我想通过AddPoint()
函数动态添加一些点,所以这里是在向量中添加顶点和颜色元素的代码:
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);
}
问题是:最初的 4 个点以 4 种不同的颜色正确显示,但 AddPoint() 始终不起作用,我没有看到任何新添加和渲染的点。
我知道如果我把顶点位置放在一个VBO中,
如:
日期数组可以是:
x, y, z, r, g, b
x, y, z, r, g, b
x, y, z, r, g, b
x, y, z, r, g, b
它没有任何问题。
但是为什么把location和color放在不同的VBO里就不行了?
有什么想法吗?谢谢。
这个问题(c++ - Storing different vertex attributes in different VBO's - Stack Overflow)是相关的,但我仍然不知道为什么我的问题仍然出现。
编辑
Rabbid76 指出 glVertexAttribPointer()
函数仅通过 glBindBuffer
附加(复制)来自先前绑定 VBO 的数据。这表明我不能将顶点位置数组和顶点颜色数组放在不同的 VBO 中?
EDIT2
我的 AddPoint()
功能在这里错了吗?
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.
调用 glBindBuffer
, before glVertexAttribPointer
必须绑定正确的缓冲区对象:
// 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