问题在于我无法弄清楚如何正确绘制两个对象,因为我没有绘制另一个对象。
这是主要代码:
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
GLuint VertexArrayID2;
glGenVertexArrays(1, &VertexArrayID2);
glBindVertexArray(VertexArrayID2);
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint MatrixID2 = glGetUniformLocation(programID, "MVP2");
glm::mat4 Projection = glm::perspective(45.0f, 5.0f / 4.0f, 0.1f, 100.0f);
glm::mat4 View = glm::lookAt(
glm::vec3(4*2,3*2,8*2),
glm::vec3(0,0,0),
glm::vec3(0,1,0)
);
glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
glm::mat4 MVP = Projection * View * Model;
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glm::mat4 Model2 = glm::translate(glm::mat4(1.0f), glm::vec3(-5.0f, 0.0f, 0.0f));
glm::mat4 MVP2 = Projection * View * Model2;
glUniformMatrix4fv(MatrixID2, 1, GL_FALSE, &MVP2[0][0]);
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
(plenty of floats)
1.0f,-1.0f, 1.0f
};
static const GLfloat g_vertex_buffer_data2[] = {
-1.0f, -1.0f, 3.0f,
(plenty of floats)
0.0f, 1.0f, 2.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint vertexbuffer2;
glGenBuffers(1, &vertexbuffer2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data2), g_vertex_buffer_data2, GL_STATIC_DRAW);
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(MatrixID2, 1, GL_FALSE, &MVP2[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 12*3);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 4*3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(2);
glfwSwapBuffers(window);
glfwPollEvents();
}
着色器:
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 2) in vec3 vertexPosition_modelspace2;
uniform mat4 MVP;
uniform mat4 MVP2;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
gl_Position = MVP2 * vec4(vertexPosition_modelspace2,1);
}
我注意到只绘制了最后一个对象,所以问题是'gl_Position'会覆盖它的值,但我应该怎么弄清楚呢?
答案 0 :(得分:14)
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
gl_Position = MVP2 * vec4(vertexPosition_modelspace2,1);
这不是图形管道的工作方式。你不能同时绘制两个对象。只需最后一次写入gl_Position
即可生效,您的第一个对象将被完全忽略。在最基本的变体中,您想要绘制两个完全独立的对象,并且您将需要两个绘制调用 - 就像在代码中一样。
但是,这样做时,您不需要两个不同的顶点属性。您的着色器只处理垂直,在您的情况下只有verexPosition_modelspace
属性。因此,您可以将该属性用于要绘制的所有对象。如果属性意味着同样的事情,那么为不同的对象使用不同的属性是没有意义的。
让我们看一下您的绘图代码:
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
在这里,您设置顶点attibute 0以指向第一个缓冲区的顶点数据,并启用atttribute数组。因此,数据不会用作vertexPosition_modelspace
的来源。
glDrawArrays(GL_TRIANGLES, 0, 12*3);
现在你绘制对象了。但正如我们已经看到的那样,您的着色器仅使用vertexPosition_modelspace2
,您没有设置指针或启用数组。由于数组已去掉,GL将使用属性2的当前值 - 用于所有顶点。因此,对于三角形,您可以创建所有点都相同的三角形 - 获得表面积为0的三角形并且无论如何都是不可见的,无论当前具有什么实际值属性。
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
现在你做了一件奇怪的事情:启用属性2数组,但不要为它设置指针!您应该重新指定属性0的指针以指向您的第二个模型。
glDrawArrays(GL_TRIANGLES, 0, 4*3);
现在您使用属性0和2进行绘制。属性0将包含所需的数据,但着色器会忽略它。属性2只是指向某个地方,你会得到未定义的行为 - 它可能会崩溃,但它也可能显示奇怪的东西,或者根本没有。
要完成此工作,只需从着色器中完全删除vertexPosition_modelspace2
即可。也只使用一个MVP
矩阵。
绘制任何对象时,您必须:
MVP
统一矩阵您可以根据需要使用尽可能多的对象。