Use glTranslatef and shaders?
Update the uniform and draw again.

auto tMVP = glm::translate(MVP, glm::vec3(1,0,0));
glUniformMatrix4fv(loc_MVP, 1, GL_FALSE, &amp;tMVP[0][0]);
gluSphere(...);

tMVP = glm::translate(MVP, glm::vec3(2,0,0));
glUniformMatrix4fv(loc_MVP, 1, GL_FALSE, &amp;MVP[0][0]);
gluSphere(...);


Using glTranslate would have done the exact same thing behind the scenes.



You can instead use instancing instead where you upload all the transforms into a buffer and then tell the gpu to use that. 

However the more portable way involves allocating a vertex attribute for the data. This involves using glVertexAttribDivisor.

So a full mat4 would need 4 vertex attributes. You can decrease that to 2 by separating out the translation as a vec3 and the rotation as a quaternion and pass the view-perspective as a uniform and combining it all in the vertex shader.