Renderer vs render component

Started by
18 comments, last by Zipster 14 years, 1 month ago
Iv began refactoring my nasty object heiarchy into a component design, its coming along well and i understand alot of the basics, but im a little confused on how an entity would get rendered. My games are all 2d, and so far the "Scene Graph" is simply a vector. Obviously for a more advanced game than iv been making i need something better, with a parenting tree like relationship. The question i have is how the render components in my entities and the scene graph will be setup. In the old system entities drew themselves, so my first inclination was having render components draw themselves. The problem was that they have no way of parenting with other render components and they are alot more abstracted from the vector the entities are held in that i dont trust they will stay in the correct render order. My thought was leting the render component basically control a scene graph node. Is this headed in the right direction? How do i create a parent relationship between two render components? Thanks for any insight you can give.
Advertisement
The render component really shouldn't do the rendering itself, rather it should control "renderable" objects which are handed out by the graphics engine and represent models, particle systems, meshes, etc. The render component then just adds and removes these objects from the scene, and the graphics engine handles all the actual rendering details. So for a 2D game, you could have a Sprite object, and the render component just does something like:
void RenderComponent::Initialize(){   MySprite = new Sprite("Tony.dds");   TheGameScene->Add(MySprite);}void RenderComponent::Shutdown(){   TheGameScene->Remove(MySprite);   delete MySprite;}
Great thats what i was thinking. Thanks!
I recently dealt with the same issue. Take a look at the source of my render task to see how I solved it. It is basically a sorted vector of drawable objects. The renderer simply inserts and removes things from the queue, re-sorting when necessary. Drawable objects are responsible for drawing themselves.
What about parenting?

I have a planet with a moon. I need to parent the moon to the planet so the matrix changes pass down the chain.
What language are you working in?

Drawable objects have an object called Render() that is called by the main render task. There's nothing to stop you doing subsequent calls to Render() on other drawable objects from within the 'main' drawable object, creating a hierarchy of drawables based on relative positions.

A render frame might look like this:

RenderTask -> Begin iterating list (2 items)
RenderTask -> Space Background
RenderTask -> Planet -> Orbiting Moons (x4)
RenderTask -> Finished iterating

The planet object is responsible for drawing its moons. There are probably better ways of doing it, but this is quite basic and works for me.
Quote:Original post by schragnasher
What about parenting?
I have a planet with a moon. I need to parent the moon to the planet so the matrix changes pass down the chain.


I am not a master of this scene graph thing, but it may help that you think your planets as more abstracted entities, which own a graphical presentation of them.

So the graphical presentations don't need to know about the hierarchys of the actual objects.

I understand your approach of planets having "parents" ie. objects they are orbiting around and that fits to the scene graph ideology. This parent-child link however is artificial in on sense. There are real physical forces which actually makes the moon orbit the planet.

Consider the abstracted entity owning a physical presentation of the object too which interacts with the surrounding planets in the way you wish (ie. simple orbiting vs. complex solar systems where planetary movements affect each other). Also, the physical presentation may be just a mathematical sphere for a planet.

In this arragement, you can place your graphical presentations (planets) in their own spatial structure which suits best for rendering them.

Second you may place your physical presentation in another spatial structure which helps solving the required physical calculations (you can still use simple orbits).

As for the abstracted objects, they may be in a single list which you update as often/rarely as needed. How they show up or behave, that depends on the components they own.


One example to explain the reason of this kind of arragement : what if you have a spacecraft travelling through your system? does it have a parent object? In my opinion not, even if it is orbiting a planet. It could well be orbiting two planets by locating itself between a planet and it's moon. So the visual spatial tree handles the visibility of the object. The physical object tree can be used to speed up the calculation for the effects of gravity caused by the planets for the ship.

edit:

Quote:
The planet object is responsible for drawing its moons. There are probably better ways of doing it, but this is quite basic and works for me.


My proposed setup is against this kind of arragements. Planet having moons doesn't make it responsible for drawing them. The moons orbit the planet by the physical rules and that's it.




These are just my ideas, not straight implementation suggestions.

Best regards!

[Edited by - kauna on March 11, 2010 10:29:19 AM]
My solution for parenting is this: A PlacementComponent provides the co-ordinate frame that relates the entity to the world. Parenting (as well as Orbiting, PathFollowing, ...) are specializations of Controller, a class that, well, controls co-ordinate frames. A parameter of Parenting is obviously the parental frame, itself usually provided by another PlacementComponent. Other parameters are the (local) position and orientation. It obviously listens on changes of the parental frame and computes the new placement for its own frame when necessary.
Quote:Original post by haegarr
My solution for parenting is this: A PlacementComponent provides the co-ordinate frame that relates the entity to the world. Parenting (as well as Orbiting, PathFollowing, ...) are specializations of Controller, a class that, well, controls co-ordinate frames. A parameter of Parenting is obviously the parental frame, itself usually provided by another PlacementComponent. Other parameters are the (local) position and orientation. It obviously listens on changes of the parental frame and computes the new placement for its own frame when necessary.


So you parent the position components of the entities? basically...
Quote:Original post by schragnasher
So you parent the position components of the entities? basically...
The PlacementComponent provides a co-ordinate frame. This means in particular a 4x4 homogeneous matrix, i.e. position and orientation, and if wanted also scaling (I don't use that). The interface of the component allows to set the position (as vector) and orientation (as quaternion). These values are ever to be understood as the world position and orientation, i.e. the PlacementComponent relates the object directly to the world.

Now, a Controller can be bound to the frame. The Parenting subclass of Controller is able to output both a position (vector) as well as an orientation (quaternion). As such it can drive both parts of the frame. Binding a Parenting instance to the frame of a PlacementConponent hence means that the global position and orientation of the entity are no longer freely available but driven by the controller.

To do so, the Parenting requires to refer to another frame that is used as parental frame. The Parenting also provides a position (vector) as well as an orientation (quaternion) and an interface to set/get these values. Obviously, these values are the local position and orientation. In other words, an enity provides local position and orientation if and only if a Parenting instance is bound.

That said, parenting an entity to another is an explicit set-up and not just be done by nesting (like in a scene graph). I've chosen this approach because parenting is just one mechanism of a dozen that are useable to control co-ordinate frames. Think e.g. of PathFollowing as another Controller. PathFollowing has a spline (or something else) path as parameter, and a Frenet frame wanders on it. The PathFollowing controller than can copy the position and orientation of the Frenet frame into the controller frame. Or think of Aiming, a Controller that doesn't influence the position but only the orientation so that the z axis of the controlled frame point towards a target that is a parameter of Aiming. Or ...

This topic is closed to new replies.

Advertisement