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