渲染多个对象的OpenGL问题

时间:2018-11-27 06:52:53

标签: c++ opengl render

我是OpenGL的新手,在渲染多个对象时遇到一些困难。

我有一个向量,每个向量都有其自己的VertexBuffer。然后,在while循环中,我自己绘制每个形状。

当我有许多相同的对象(多个多维数据集等)时,一切都很好,但是,当我添加一个三角形网格时,一切都变得毫无意义了。

我可以有很多立方体

enter image description here

我可以有一个三角形网格:

enter image description here

但是,当我尝试拥有一个立方体然后是一个三角形网格时,我得到:

enter image description here

我对发生的一切完全不知所措。下面提供了我的循环代码。

while (!glfwWindowShouldClose(window))
    {

        // Get the size of the window
        int width, height;
        glfwGetWindowSize(window, &width, &height);

        float aspect_ratio = 1 * float(height)/float(width); // corresponds to the necessary width scaling

        double xpos, ypos;
        glfwGetCursorPos(window, &xpos, &ypos);

        // Clear the framebuffer
        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Enable depth test
        glEnable(GL_DEPTH_TEST);

        glUniform3f(program.uniform("triangleColor"), 1.0f, 1.0f, 1.0f);

        glUniformMatrix4fv(program.uniform("proj"), 1, GL_FALSE, projection.data());
        glUniformMatrix4fv(program.uniform("view"), 1, GL_FALSE, view.data());

        int tally = 0;
    for (int i = 0; i < surfaces.size(); i++) {

        Surface *s = surfaces[i];

        Vector3f color = s->getColor();

        int tempIndex = triangleIndex;
        Matrix4f model = s->getModel();

        // Convert screen position to world coordinates
        double xworld = ((xpos/double(width))*2)-1;
        double yworld = (((height-1-ypos)/double(height))*2)-1; // NOTE: y axis is flipped in glfw

        if (isPressed && mode == "translate") { 
            if(tempIndex == i) {
                Vector4f center = s->getCenter() + model.col(3);
                Vector4f displacement = Vector4f(xworld, yworld, 0, 1) - center;
                Matrix4f translation = translateMatrix(displacement(0), displacement(1), displacement(2));
                model = translation * s->getModel();
                s->setModel(model);
            }
        }
        glUniform3f(program.uniform("triangleColor"), color(0), color(1), color(2));
        glUniformMatrix4fv(program.uniform("model"), 1, GL_FALSE, model.data()); 
        glDrawArrays(GL_TRIANGLES, 0, s->getVertices().size());
    }

然后我将对象设为时初始化每个VBO

VertexBufferObject VBO;
VBO.init();
VBO.update(Vertices);
program.bindVertexAttribArray("position", VBO);

Surface* s = new Surface(VBO, Vertices, percentScale, 0, transformedCenter, SmoothNormals, FlatNormals, color);
s->setModel(model);
surfaces.push_back(s);

其中Program :: bindVertexAttribArray定义为

GLint Program::bindVertexAttribArray(
        const std::string &name, VertexBufferObject& VBO) const
{
  GLint id = attrib(name);
  if (id < 0)
    return id;
  if (VBO.id == 0)
  {
    glDisableVertexAttribArray(id);
    return id;
  }
  VBO.bind();
  glEnableVertexAttribArray(id);
  glVertexAttribPointer(id, VBO.rows, GL_FLOAT, GL_FALSE, 0, 0);
  check_gl_error();

  return id;
}

1 个答案:

答案 0 :(得分:2)

在绘制调用之前,您没有绑定任何缓冲区。您可能只是在绘制初始化它们时最后绑定的任何缓冲区。在循环glDrawArrays之前,您需要在循环末尾添加以下内容:

...
program.bindVertexAttribArray("position", VBO); // where VBO is the buffer of surface s
glUniform3f(program.uniform("triangleColor"), color(0), color(1), color(2));
glUniformMatrix4fv(program.uniform("model"), 1, GL_FALSE, model.data()); 
glDrawArrays(GL_TRIANGLES, 0, s->getVertices().size());