【发布时间】:2018-11-27 06:52:52
【问题描述】:
我是 OpenGL 的新手,在渲染多个对象时遇到了一些困难。
我有一个向量,每个向量都有自己的 VertexBuffer。然后,在 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());
}
并且我在将对象制作为时初始化每个 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;
}
【问题讨论】:
-
您没有展示如何初始化顶点缓冲区。我怀疑缓冲区有一个模型的数据,然后你试图用另一个模型的元素计数来渲染它。顺便说一句,您正在动态生成顶点缓冲区。这不是应该这样做的。为每个模型创建一个 VAO,并在程序开始时将正确的缓冲区与其数据绑定。然后,在渲染循环中,只需激活 VAO 并绘制它。
-
@NicoSchertier 有没有一种方法可以在两个着色模型(平面与 phong)之间切换而无需动态创建顶点缓冲区?我需要在顶点着色器中使用两组不同的法线,并认为我需要创建 VBO。
-
@NicoSchertier 我认为你是对的,因为它还存在一个问题,即绘制 2 个相反颜色的对象。为什么会有这个切换器?
-
如果你想要不同的法线集,你可以有两个 VAO 引用两个不同的法线 VBO。
-
这几乎不清楚。
bindVertexAttribArray、VBO_C.init和VBO_C.update有什么作用?顶点坐标在哪里。您是否错过了更改顶点坐标。你用vertex array object吗?您必须添加更多信息才能使其成为Minimal, Complete, and Verifiable example。