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