I've been playing with an entity/component/system design recently, and I've come across a couple of stumbling blocks.
Instancing
Let's say I have a few hundred "things" (asteroids, chickens, whatever) that are being drawn with instancing. In a classic component hierarchy, I'd have a game object that keeps the individual instance index and vertex buffers, as well as the second dynamic vertex buffer for the instance data (collection of matrices, etc.). That object would be responsible for checking collisions with other objects and between the instances themselves.
In an ES system, I'd like to track each instance as an individual entity, but I don't want to give up simplicity and performance of instancing. The first thing that occurred to me was to create an "instance group" component, with a field that defines a group ID to enable handling of multiple types of instanced geometry.
An "Instance System" would collect those components and maintain the instance vertex buffer. My entity manager already notifies systems when an entity is created or destroyed which makes this part pretty easy to implement.
My confusion comes from how to cleanly integrate that with the rendering system. If each instance appears as a separate entity with a "renderable" component/attribute, the render system will process them individually.
I could:
Include a special case for entities that have both a "renderable" and an "instanced" component, but that seems messy and feels like starting down the path of having a huge render system with tons of special cases.
Have the render system maintain a collection of instance vertex buffers, query the entity list for "instanced" entities, filter based on a group ID, etc., and render as appropriate, so the render system becomes responsible for maintaining instance collections, but that seems like the wrong place to put that sort of logic.
I could also include a single entity in addition to the instances with, say, an "InstanceOutput" component/attribute and a
Renderable
component, and remove theRenderable
component from the individual instance entities, giving a single render point for all of the instances. This component would probably also server as a place to keep the geometry and persistent instance/vertex buffer.
Is there a better way?
Rendering
I have several types of renderable entities. Some have procedural geometry and textures, some are just sprites, some are text displays. What's the best way to differentiate these from the point of view of the rendering system without having to write a massive switch
statement? In a game object hierarchy, each of these types would have their own Draw()
method, but moving the logic into a Render System doesn't seem to provide a lot of flexibility in terms of different effect parameters, etc.