What do you think of it now?
It is basically the same situation I explained about why the graphics engine knowing about your camera is bad, but expanded to include models as well.
A model, like a camera, is a higher-level structure than just the graphics data contained within it. The graphics library doesn’t care what an AABB is or whatever physics or collision information may accompany the model, nor does it care about animation data. You may not have that data nor plan to, but considering theoretically that you did, it would help you realize that a model is much more than just graphics data, and that the graphics data wanted by the graphics library is a very small sub-set of the entire object.
So, your graphics engine contains your models.
So how do you plan to handle terrain? Just throw that into the gargantuan graphics library? Duplicate it but specialized for rendering terrain?
You may not even be planning to ever have terrain, but theoretically asking yourself these kinds of questions helps you understand where things really need to be and what they really need to do.
You thought the graphics library was the appropriate place for your models because you considered that they were the only thing you would render (and that a model does nothing else but be rendered).
Then you also need to ask yourself what others would expect from your graphics library should they want to use it (again, only hypothetically). If I use your graphics library, am I required
to use your model format? All I want is an easier interface with the hardware. Why do I need to take in this model format? I have my own.
Your graphics library renders every model, but I already have a library whose job is specifically to efficiently manage the scene and all the objects in it, and thanks to some of the spatial partitioning information it keeps (for example) it can cull and render objects more quickly than a graphics library that simply renders everything.
By using your library, I forfeit my efficient rendering?
If you had considered both, “What if I were to theoretically add terrain?”, and, “What do people want by using my library?”, you may have arrived at the more-suitable conclusion: “I could add terrain to the graphics library, but since I myself am not planning to use terrain, it is likely others using my library also probably don’t want terrain. I should make my graphics library more abstract and have it provide an easy-to-use interface that other libraries can use for whatever kind of rendering they want to do. Then I can have models and terrain as separate libraries that can both access the graphics library by themselves without the graphics library knowing about all kinds of things it shouldn’t. Probably the best organization is the following:
#1: Graphics library: Provides a convenient interface with Direct3D, OpenGL, whatever. Has wrappers for textures, vertex buffers, index buffers, and shaders. It is not a crime for it to also link to some kind of vector/quaternion/matrix math library, if necessary.
#2: Model library: Higher-level then the graphics library. Graphics and rendering are only a small subset of what a model actually is and does. It not only includes the graphics library, but also the physics library etc. (if you were ever to add physics).
#3: Terrain library: Same level as the model library. Same exact concept. Just a different way of loading/handling its data, and rendering it.
#4: Engine library: This is the core library that stands above all others. It knows what everything is, and it brings all of these other libraries together in peace and harmony.
Within this library is a scene manager which knows about every single type of entity in the game world, from cameras to models to terrain.
It makes things efficient via spatial partitioning schemes, sweep-and-prune implementation, etc.
It manages the phyics engine directly. When it wants to perform a logical update, it uses its efficient management of the game world to efficiently run over the objects in the world and ask for the data needed for use by the physics engine
(which it then passes off to the physics engine).
When it is time to render, it efficiently gathers objects in view, inform them they are about to render, handles special request by the objects to update a reflective cubemap, and finally lets objects render themselves however they decide to do so.
It handles creation of shadow maps, reflection maps, etc.
It is a mastermind that orchestrates everything.”
With such a design, I am free to use your graphics library without needing to use your model format or terrain.
If I want to use your models, I can also use your model library. No harm done.
If I want the scene to be managed efficiently for me, including the generation of those cubemaps you mentioned, I can use your engine library.
The point is that your “convenience”—that is having cubemaps generated automatically, having a way to render all the objects in the scene with one call, etc.—is not the issue.
These things are
needed. You just didn’t put them in the right places.