It is easy and oftentimes very useful to structure your ModelView subclasses so that they can be used either as standalone subclasses added to the Controller in the usual way, or be used as "helper" classes that are not added to the Controller, rather they are managed by the subclass that needs their "helper" services.
Let us consider the following example which also illustrates another common design pattern: using multiple VAO-VBO collections in a single ModelView subclass:
Suppose I have a ModelView subclass called Foo that, like our basketball goal example, has Foo::render which calls Foo:renderFoo. I can then create a higher level object, say Bar that uses several Foo instances. In main.c++, I would create "new Bar(...) and add it to the Controller in the usual way. The constructor for Bar would dynamically allocate all the Foo instances it needs, but it would not add them to the Controller. Instead, when Bar::render is called, it would do something like:
Bar::renderBar() { f1.renderFoo(); f2.renderFoo(); … // whatever other stuff needs to be done } Bar::render() { // usual prelude stuff renderBar(); // usual cleanup stuff }
In the case of our Basketball example, I might have a class called BasketballCourt with two BasketballGoal instance variables. Rendering of the court would then include:
… goal1.renderGoal(); goal2.renderGoal(); …
This general pattern is what you saw with the CGLString class, and it is what you will see again later in the BasicShapeRenderer class.