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



我正在尝试使用多个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;
}

片段着色器:

#version 330 core
layout(location = 0) out vec4 color;
uniform vec4 u_Color;
void main()
{
    color = u_Color;
}

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);

渲染循环中的绘制调用:

    //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);
    }

我再说一遍,为了使用相同的顶点绘制多个对象,我已经做到了。我需要知道如何使用相同的顶点和片段着色器但顶点数量不同的顶点绘制多个对象。该项目很小,最多只能渲染 10 个 2D 对象。

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

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

// [...]
glBindVertexArray(vao2);
glDrawArrays(GL_TRIANGLE_FAN, 0, 360);
// [...]
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6); 

我找到了一个带有代码的项目:

#pragma once
#include "glmglm.hpp"
struct VertexFormat
{
    glm::vec3 position;
    VertexFormat(const glm::vec3 &iPos)
    {
        position = iPos;
    }
    VertexFormat()
    {
    }
};

最新更新