It's all ok when i want to draw one object, for example a cube. I create vertices for cube, i create the buffer, i create the MVP matrix and send it to shader and it works nice.
But, what to do when i want to draw 2 or more objects, for example both cube and a triangle? I believe that View and Projection matrices should be same both for triangle and cube, i only need different Model matrix, right? So that means that i will have two MVPs?
//Example (using GLM):
glm::mat4 MVPC = Projection * View * ModelCube;
glm::mat4 MVPT = Projection * View * ModelTriangle;
So what do i do with those two now? This is the vertex shader that works good for cube
//vertex shader
#version 330 core
layout(location = 0) in vec3 verticesCube;
uniform mat4 MVPC;
void main(){
gl_Position = MVPC * vec4(verticesCube,1);
}
And what should i do with MVPT (triangle) in shader, i tried messing around with different things, but i can't get it to work, i can't display both the cube and the triangle at the same time.
The confusion comes from thinking that the shader controls multiple vertex arrays at once, when it should be thought of as a universal entity. A vertex array is passed to the shader, then the object is drawn. And the process is repeated.
For example, let's say we assign the variable matrixID to the uniform MVP:
// get handle for our "MVP" uniform
GLuint matrixID = glGetUniformLocation(programID, "MVP");
When we're ready to draw an object, we set matrixID to the object's MVP:
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &cubeMVP[0][0]);
Then bind the vertex buffer, set the attribute pointer, and draw it:
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, cubeVerteciesBuffer);
glVertexAttribPointer(
0, // shader layout location
3,
GL_FLOAT,
GL_FALSE,
0,
(void *)0
);
glDrawArrays(GL_TRIANGLES, 0, 12*3); // draw cube
Now we move on to the triangle and repeat the process - set matrixID to the object's MVP, bind the vertex buffer, set the attribute pointer, and draw it:
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &triMVP[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, triangleVerteciesBuffer);
glVertexAttribPointer(
0, // shader layout location
3,
GL_FLOAT,
GL_FALSE,
0,
(void *)0
);
glDrawArrays(GL_TRIANGLES, 0, 3); // draw triangle
The corresponding vertex shader code:
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertecies_modelspace;
uniform mat4 MVP;
void main(){
gl_Position = MVP * vec4(vertecies_modelspace, 1);
}
OpenGL is not a scene graph. It draws things according to the current state and then forgets about it.
So if you want to draw different geometries, with different transformations just set the corresponding transformation matrix (uniform), draw the object and repeat this for each object you want to draw. After geometry has been drawn, the following operations will have no further effect on it, other than it might be overdrawn.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With