Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL渲染多个对象的问题_C++_Opengl_Render - Fatal编程技术网

C++ OpenGL渲染多个对象的问题

C++ OpenGL渲染多个对象的问题,c++,opengl,render,C++,Opengl,Render,我是OpenGL的新手,在渲染多个对象时遇到了一些困难 我有一个向量,每个向量都有自己的顶点缓冲区。然后,在while循环中,我自己绘制每个形状 当我有许多相同的对象(多个立方体等)时,一切都很好。然而,当我添加三角形网格时,一切都变得不正常 我可以有很多立方体 我可以使用单个三角形网格: 但是,当我尝试使用立方体和三角形网格时,我得到: 我完全不知道发生了什么事。下面提供了我的循环代码 while (!glfwWindowShouldClose(window)) {

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

我有一个向量,每个向量都有自己的顶点缓冲区。然后,在while循环中,我自己绘制每个形状

当我有许多相同的对象(多个立方体等)时,一切都很好。然而,当我添加三角形网格时,一切都变得不正常

我可以有很多立方体

我可以使用单个三角形网格:

但是,当我尝试使用立方体和三角形网格时,我得到:

我完全不知道发生了什么事。下面提供了我的循环代码

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());
    }
其中Program::BindVertexAttributeArray定义为

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;
}
闪烁程序::BindVertexAttributeArray( 常量std::字符串和名称,VertexBufferObject和VBO)常量 { 闪烁id=attrib(名称); if(id<0) 返回id; 如果(VBO.id==0) { glDisableVertexAttributeArray(id); 返回id; } VBO.bind(); GlenableVertexAttributeArray(id); glvertexattributepointer(id,VBO.rows,GL_FLOAT,GL_FALSE,0,0); 检查_gl_error(); 返回id; }
在draw调用之前,您没有绑定任何缓冲区。您可能只是在绘制初始化时最后绑定的缓冲区。在
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());

在draw调用之前,您没有绑定任何缓冲区。您可能只是在绘制初始化时最后绑定的缓冲区。在
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());

不显示如何初始化顶点缓冲区。我怀疑缓冲区中有一个模型的数据,然后您试图使用另一个模型的元素计数来渲染它。顺便说一句,您正在动态生成顶点缓冲区。这不是应该怎么做的。为每个模型创建VAO,并在程序开始时将正确的缓冲区与其数据绑定。然后,在渲染循环中,只需激活VAO并绘制它。@NicoSchertier有没有一种方法可以在两个着色模型(flat和phong)之间切换,而无需动态创建顶点缓冲区?我需要在顶点着色器中使用两组不同的法线,并认为我需要创建VBOs。@NicoSchertier我认为你是对的,因为它还存在绘制两个颜色相反的对象的问题。为什么会有这个切换器?如果你想要不同的法线集,你可以有两个VAO引用两个不同的法线VBO。这几乎是不清楚的。
bindvertexattributearray
VBO_C.init
VBO_C.update
做什么?顶点坐标在哪里。您是否错过了更改顶点坐标的步骤。你用的是自行车吗?您必须添加更多信息,以使其成为一个。您没有显示如何初始化顶点缓冲区。我怀疑缓冲区中有一个模型的数据,然后您试图使用另一个模型的元素计数来渲染它。顺便说一句,您正在动态生成顶点缓冲区。这不是应该怎么做的。为每个模型创建VAO,并在程序开始时将正确的缓冲区与其数据绑定。然后,在渲染循环中,只需激活VAO并绘制它。@NicoSchertier有没有一种方法可以在两个着色模型(flat和phong)之间切换,而无需动态创建顶点缓冲区?我需要在顶点着色器中使用两组不同的法线,并认为我需要创建VBOs。@NicoSchertier我认为你是对的,因为它还存在绘制两个颜色相反的对象的问题。为什么会有这个切换器?如果你想要不同的法线集,你可以有两个VAO引用两个不同的法线VBO。这几乎是不清楚的。
bindvertexattributearray
VBO_C.init
VBO_C.update
做什么?顶点坐标在哪里。您是否错过了更改顶点坐标的步骤。你用的是自行车吗?你必须添加更多的信息,让这成为一个。哇。这完全奏效了。但这感觉真的很低效。如果我只绑定一次对象,但可以操纵它的模型、法线等,有没有更好的方法呢?是的,Nico Schertler在他的评论中写道:每个曲面使用VAO。哇。这完全奏效了。但这感觉真的很低效。如果我只绑定一次对象,但可以操纵其模型、法线等,是否有更好的方法来实现这一点?是的,Nico Schertler在其评论中写道:对每个曲面使用VAO。