C++ 如何使用两个顶点缓冲区?
我创建了两个缓冲区,如下所示:C++ 如何使用两个顶点缓冲区?,c++,opengl,vertex-buffer,C++,Opengl,Vertex Buffer,我创建了两个缓冲区,如下所示: GLuint vao; GLuint vbo[2]; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(2, vbo); // 1 glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), tri
GLuint vao;
GLuint vbo[2];
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(2, vbo);
// 1
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(0);
// 2
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(rectangle), rectangle, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glDrawArrays(GL_POLYGON, 0, 3); // Triangle
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glDrawArrays(GL_POLYGON, 0, 4); // Rectangle
第一个必须创建一个三角形,第二个必须创建一个矩形。
因此,我在渲染循环中调用glDrawArrays()
,如下所示:
GLuint vao;
GLuint vbo[2];
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(2, vbo);
// 1
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(0);
// 2
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(rectangle), rectangle, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glDrawArrays(GL_POLYGON, 0, 3); // Triangle
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glDrawArrays(GL_POLYGON, 0, 4); // Rectangle
那么为什么这不起作用呢?
(注:我知道现在使用GL_三角形,但对于这个项目,我必须使用GL_多边形)对于VBO和顶点属性指针,绑定哪个VBO并不重要,重要的是哪个VBO附加到属性。VBO属性绑定是通过调用
glvertexattributepointer
建立的,这意味着使用相同的属性索引第二次调用它将解除第一次绑定
您必须在每次绘制调用之前建立绑定,如:
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glDrawArrays(GL_POLYGON, 0, 3); // Triangle
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glDrawArrays(GL_POLYGON, 0, 4); // Rectangle
或者您可以使用两个VAO,各自设置,并在渲染期间切换VAO
如果您的几何体是固定的,并且始终必须渲染这两个几何体,我会考虑在一个VBO中组合这两个几何体,并使用glDrawArrays
命令的第一个参数来绘制几何体。这将导致更好的性能,因为您需要更少的状态更改。这方面的代码类似于:
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, vbo);
// Allocate memory for both geometries
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle) + sizeof(rectangle), NULL, GL_STATIC_DRAW);
//Copy geometries one after the other to the VBO
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(triangle), triangle);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(triangle), sizeof(rectangle), rectangle);
//Attribute binding
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(0);
渲染:
glBindVertexArray(vao);
glDrawArrays(GL_POLYGON, 0, 3); // Triangle
glDrawArrays(GL_POLYGON, 3, 4); // Rectangle
对于VBO和顶点属性指针,绑定哪个VBO并不重要,重要的是将哪个VBO附加到属性。VBO属性绑定是通过调用
glvertexattributepointer
建立的,这意味着使用相同的属性索引第二次调用它将解除第一次绑定
您必须在每次绘制调用之前建立绑定,如:
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glDrawArrays(GL_POLYGON, 0, 3); // Triangle
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glDrawArrays(GL_POLYGON, 0, 4); // Rectangle
或者您可以使用两个VAO,各自设置,并在渲染期间切换VAO
如果您的几何体是固定的,并且始终必须渲染这两个几何体,我会考虑在一个VBO中组合这两个几何体,并使用glDrawArrays
命令的第一个参数来绘制几何体。这将导致更好的性能,因为您需要更少的状态更改。这方面的代码类似于:
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, vbo);
// Allocate memory for both geometries
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle) + sizeof(rectangle), NULL, GL_STATIC_DRAW);
//Copy geometries one after the other to the VBO
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(triangle), triangle);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(triangle), sizeof(rectangle), rectangle);
//Attribute binding
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(0);
渲染:
glBindVertexArray(vao);
glDrawArrays(GL_POLYGON, 0, 3); // Triangle
glDrawArrays(GL_POLYGON, 3, 4); // Rectangle