void Sprite::Render() isnt a good idea, you are considering each object in your scene as independent thing (kind of "bottom-up"), my suggestion would be to consider the scene as a whole:

(kind of "top-down")
Code :
void Graphics::Render(const Scene& scene)
{
// set camera matrices etc
 
glUseProgram(m_program1);
glBindVertexArray(m_vertexarray1);
 
for each (element in your scene)
{
upload "model-to-world" transformation matrix
glDrawArrays(... triangles, mesh offset, vertexcount...);
}
 
glBindVertexArray(0);
glUseProgram(0);
 
}

that "Graphics" class has ALL shader, ALL vertices, ALL other resources it needs to visualize what you want to see: the "scene"

the scene is everything in you virtual world, the player, the enemies, the terrain, the nearby wood, the sky, just everything

once you have that, you can easily simulate it (physics) as a whole, using another class or a member function of the Scene class, and updating the sound sources becomes also just 1 for loop over all object in the "scene" thing

example:
https://sites.google.com/site/john87...ultiple-models
https://sites.google.com/site/john87.../0-basic-setup
https://sites.google.com/site/john87...3-4-depth-test

its likely that some of your static models use the same shader + vertex layout, so you can put all of the vertices into 1 big vertex buffer:

|--------------model1---------|--------------model2--------------------|-----etc...
vertex0,vertex1, ..., vertexN, vertexN+1,vertexN+2, ..., vertexN+M, ...

to draw model1, you call glDrawArrays(GL_TRIANGLES, 0, N)
to draw model2, you call glDrawArrays(GL_TRIANGLES, N, M)