无法在opengl中绘制多个对象

Posted

技术标签:

【中文标题】无法在opengl中绘制多个对象【英文标题】:Cant draw multiple objects in opengl 【发布时间】:2013-04-16 13:01:24 【问题描述】:

我不知道为什么下面的代码不起作用,我正在尝试绘制 2 个形状,一个红色的三角形和一个多色的立方体,它们本身可以完美绘制,但如果我尝试同时绘制这两个形状它立即给出了奇怪的错误,我尝试在更改变量修改我的着色器周围更改行,但我似乎无法接近我想要的结果,当前代码最终绘制了 2 个使用立方体颜色的相同三角形。

GLuint VertexArrayID;

glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

GLuint MatrixID = glGetUniformLocation(shader->id(), "MVP");

glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
glm::mat4 View       = glm::lookAt(
glm::vec3(4,2,2), // Camera location
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
);

glm::mat4 myMatrix = glm::translate(-2.f,0.f,0.f);
glm::mat4 Model = glm::mat4(1.f);
Model= myMatrix * Model;
glm::mat4 MVP = Projection * View * Model;

glm::mat4 myMatrix2 = glm::translate(2.f,0.f,0.f);
glm::mat4 Model2 = glm::mat4(1.f);
Model2= myMatrix2 * Model2;
glm::mat4 MVP2 = Projection * View * Model2;

glViewport(0, 0, windowWidth, windowHeight); // set viewport to the size of the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT  | GL_STENCIL_BUFFER_BIT);

shader->bind();
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colourBuffer);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glDrawArrays(GL_TRIANGLES,0,12*3);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP2[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer2);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colourBuffer2);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

SwapBuffers(hdc);

glDeleteBuffers(1, &vertexBuffer);
glDeleteBuffers(1, &vertexBuffer2);
glDeleteBuffers(1, &colourBuffer);
glDeleteBuffers(1, &colourBuffer2);
shader->unbind();
glDeleteVertexArrays(1, &VertexArrayID);

这是主要代码。我以类似的方式创建所有缓冲区,基本上使用以下 3 行的变体来插入不同的缓冲区名称和数据,

glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(Cube), Cube, GL_STATIC_DRAW);

片段着色器

#version 330 core
in vec3 fragmentColour;
out vec3 colour;
void main()
colour = fragmentColour;

顶点着色器

  #version 330 core

  uniform mat4 MVP;

  layout(location = 0) in vec3 vertexPosition_modelspace;
  layout(location = 1) in vec3 vertexColour;
  out vec3 fragmentColour;

   void main()

    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
    fragmentColour = vertexColour;
   

【问题讨论】:

由于您使用的是 VAO,您不妨创建其中两个并保存其中每个形状的 VBO 绑定,这样您就不必每次都设置所有属性. 【参考方案1】:

我看到你正在尝试使用 VAO,但你只创建了一个。还有你为什么要准备:

glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 顶点缓冲区); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 颜色缓冲区); glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);

并删除:

glDeleteBuffers(1, &vertexBuffer); glDeleteBuffers(1, &vertexBuffer2); glDeleteBuffers(1, &colourBuffer); glDeleteBuffers(1, &colourBuffer2);

每次渲染调用时您的 VAO不再需要这些对象了。Here 是一个很好的例子,它是如何正确完成的。

你应该做的是: 仅在某些 init 方法中启动您的 VAO。然后在渲染循环中:

   glBindVertexArray(m_VAO1);

   ///draw geometry here

    glBindVertexArray(0);

对您要渲染的每个几何图形执行此操作。

在深入审查您的代码后,我看到您这样做了:

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

所以你确实绑定了 VAO。但是你只创建和绑定了一个!你需要为每个可渲染对象创建一个,将所有需要的缓冲区附加到它,然后在渲染循环中使用它们,就像我上面解释的那样。

【讨论】:

嘿,谢谢,似乎出了什么问题,但我似乎无法修复它,我添加了一个新的 vao 并在禁用第一个后​​绑定它,现在三角形有红色纹理但立方体没有'似乎不知道我做错了什么?生病继续修修补补。我也没有在我的代码中使用循环,它基本上是一次渲染调用,这就是我删除缓冲区的原因。 尝试单独渲染立方体,可能是你有几何问题,如错误的缠绕或顶点数据错误。 设法让它运行,这是我设置/未设置我的 vao 的方式感谢您的帮助。

以上是关于无法在opengl中绘制多个对象的主要内容,如果未能解决你的问题,请参考以下文章

无法在openGL中绘制对象

opengl从一个vao中绘制多个对象

如何在 OpenGL 中的单个绘制调用上绘制多个顶点数组?

如何使用 VBO 和单个 OpenGL drawelements 调用绘制多个对象?

在 Opengl Glut 中绘制对象数组

opengl 多个对象,纹理和非纹理,伪影