如何使用多个 VAO 和 VBO 在 OpenGL 中绘制多个对象?

s_d*_*onu 3 c++ opengl vbo glm-math vao

我正在尝试使用多个 VAO 和 VBO 在 OpenGL 中渲染多个对象。为了使用相同的顶点渲染多个对象,我已经完成了,但我想要做的是为每个对象使用不同的顶点,例如绘制一个正方形和一个圆形。对于正方形,我只需要 6 个顶点,但对于圆形,我需要 360 个顶点。我在读取或创建着色器时出错。

这是顶点着色器:

#version 330 core

layout (location = 0) in vec4 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * position;
}
Run Code Online (Sandbox Code Playgroud)

片段着色器:

#version 330 core

layout(location = 0) out vec4 color;

uniform vec4 u_Color;

void main()
{
    color = u_Color;
}
Run Code Online (Sandbox Code Playgroud)

VAO 和 VBO 生成和绑定

// Circle
std::vector<VertexFormat> vertices;

for (int i = 0; i < 360; i++)
{
    GLfloat angle = i * ((2.0f * 3.14159f) / 360);
    vertices.push_back(VertexFormat(glm::vec3(cos(angle) * 100.0f, sin(angle) * 100.0f, 0.0f)));
}

// Pipette object
std::vector<VertexFormat> pipetteVertices;
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 500.0f, injPipette.y + 500.0f, 0.0f))); // 0
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 700.0f, injPipette.y + 500.0f, 0.0f))); // 1
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 700.0f, injPipette.y + 700.0f, 0.0f))); // 2
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 500.0f, injPipette.y + 700.0f, 0.0f))); // 3
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 500.0f, injPipette.y + 500.0f, 0.0f)));
pipetteVertices.push_back(VertexFormat(glm::vec3(injPipette.x + 700.0f, injPipette.y + 700.0f, 0.0f)));

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexFormat) * 6, &pipetteVertices[0], GL_STATIC_DRAW);

//Position attribute
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (GLvoid *)0);

GLuint vao2;
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);

GLuint vbo2;
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexFormat) * 360, &vertices[0], GL_STATIC_DRAW);

//Position attribute
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (GLvoid *) 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
Run Code Online (Sandbox Code Playgroud)

以及渲染循环中的绘制调用:

    //Get the uniform locations of model, view and projection matrices
    modelID = glGetUniformLocation(program, "model");
    viewID = glGetUniformLocation(program, "view");
    projectionID = glGetUniformLocation(program, "projection");

    //View transform
    glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 2), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
    //Projection transform
    //glm::mat4 projection = glm::perspective(45.0f, (GLfloat)screenWidth / (GLfloat)screenHeight, 0.1f, 1000.0f);
    glm::mat4 projection = glm::ortho(0.0f, (GLfloat)screenWidth, 0.0f,  (GLfloat)screenHeight, 0.1f, 10.0f);

    {
        glUniformMatrix4fv(viewID, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projectionID, 1, GL_FALSE, glm::value_ptr(projection));

        glm::mat4 translate = glm::translate(glm::mat4(1.0), glm::vec3(100.0f + move_x, 100.0f + move_y, 0.0f));
        glm::mat4 rotate = glm::rotate(glm::mat4(1.0), 0.0f, glm::vec3(0.0f, 0.0f, 1.0f));
        glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(1.0f, 1.0f, 2.0f));

        glm::mat4 model = translate * rotate * scale;
        glUniformMatrix4fv(modelID, 1, GL_FALSE, glm::value_ptr(model));

        glUniform4f(color, 0.0f, 0.0f, 1.0f, 1.0f);

        //Render
        glDrawArrays(GL_TRIANGLE_FAN, 0, 360);
    }

    {
        glUniformMatrix4fv(viewID, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projectionID, 1, GL_FALSE, glm::value_ptr(projection));

        glm::mat4 translate = glm::translate(glm::mat4(1.0), glm::vec3(300.0f + injPipette.x, 300.0f + injPipette.y, 0.0f));
        glm::mat4 rotate = glm::rotate(glm::mat4(1.0), 0.0f, glm::vec3(0.0f, 0.0f, 1.0f));
        glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(1.0f, 1.0f, 2.0f));

        glm::mat4 model = translate * rotate * scale;
        glUniformMatrix4fv(modelID, 1, GL_FALSE, glm::value_ptr(model));

        glUniform4f(color, 1.0f, 0.0f, 0.0f, 0.5f);

        //Render
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
Run Code Online (Sandbox Code Playgroud)

我重复一遍,使用我已经完成的相同顶点绘制多个对象。我需要知道如何使用相同的顶点和片段着色器但不同数量的顶点来绘制多个对象。该项目很小,仅在 2D 中渲染最多 10 个对象。

Rab*_*d76 7

绘制命令,例如glDrawArrays处理和绘制当前绑定的顶点数组对象中指定的通用顶点属性数据数组

这意味着您需要在执行 Draw 调用之前绑定正确的顶点数组对象:

// [...]

glBindVertexArray(vao2);
glDrawArrays(GL_TRIANGLE_FAN, 0, 360);
Run Code Online (Sandbox Code Playgroud)
// [...]

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6); 
Run Code Online (Sandbox Code Playgroud)