Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have many objects in my game world that all derive from one base class.

Each object will have different materials and will therefore be required to be drawn using various rendering techniques.

I currently use the following order for rendering my objects.

  • Deferred
  • Forward
  • Transparent (order independent)

Each object has a rendering flag that denotes which one of the above methods should be used.

The list of base objects in the scene are then iterated through and added to separate lists of deferred, forward or transparent objects based on their rendering flag value.

The individual lists are then iterated through and drawn using the order above. Each list is cleared at the end of the frame.

This methods works fairly well but it requires different draw methods for each material type.

For example each object will require the following methods in order to be compatible with the possible flag settings.

object.DrawDeferred()
object.DrawForward()
object.DrawTransparent()

It is also hard to see where methods outside of materials, such as rendering shadow maps, would fit using this "flag & method" design.

object.DrawShadow()

I was hoping that someone may have some suggestions for improving this rendering process, possibly making it more generic and less verbose?

share|improve this question

migrated from codereview.stackexchange.com Oct 8 '12 at 15:01

This question came from our site for peer programmer code reviews.

    
This sounds like a good case for some sort of generic IRender that would be responsible for doing the drawing. I guess my point is do your objects really need to know how they are drawn? Perhaps you could put that responsibility elsewhere?? –  dreza Oct 8 '12 at 8:07
    
That sounds like something I would like to investigate. Do you have a link to an article outlining this approach? Or could you perhaps post an answer with a skeleton of this pattern? –  user1423893 Oct 8 '12 at 10:01
    
Like dreza mentioned, it seems like you'd want a seperate hierarchy of render classes that know how to draw, but don't care when. Then your Draw* methods take IRenderer as an argument... object.DrawDeferred(shadowRenderer). –  Griffin Oct 8 '12 at 13:25
    
it seems like you'd want a seperate hierarchy of render classes that know how to draw, but don't care when I would still need to determine what derived IRenderer class to use based on a enum/flag. Are you suggesting that I call Draw(IRenderer iRenderer) for each drawable object with each IRenderer class. Then ignore the draw call should the flag not match the IRenderer type? –  user1423893 Oct 9 '12 at 11:16
    
Is the rendering flag set based on the state of the objects materials or is it just dependent on the object type in which case it's typically hard coded in each derived type? –  dreza Oct 9 '12 at 22:32

2 Answers 2

up vote 2 down vote accepted

You can use Strategy.

You have a base class IDrawer::draw() with subclasses DefferedDrawer, ForwardDrawer, TransperantDrawer, etc

You then have a base class for your objects: IDrawable which uses an IDrawer drawer delegate for actual draw: IDrawable::draw() { drawer->draw(); }

IDrawable also has a method for changing the drawer: IDrawable::setDrawer(IDrawer someDrawer) {this->drawer = someDrawer;}

or the drawer can be automatically updated by some sort of state machine (here it depends on your usage), depending on the context changes.

You then have a single container for your objects (which can be sorted by some criteria) and call obj.draw()

share|improve this answer

I don't know what do the words "deferred" and "forward" mean in your case, but in my opinion, you should render the world in the following order:

  1. Draw the world. If possible, draw the closest polygons first, so depth test can cull the polygons that are not going to be seen by the player. It's better to split the world into multiple segments, so you can do visibility and frustum culling to drastically reduce the amount of drawn polygons.
  2. Draw the models. Because of depth testing, your graphics card won't render the polygons behind walls. Before rendering a model, check if it's in the view frustum, this is impotant because models usually consist of a lot of polygons.
  3. Draw the farthest things such as sky box.
  4. Enable blending and draw solid translucent objects.
  5. Disable writing to Z buffer and draw sprites in far-to-near order.
  6. Reenable writing to Z buffer and clear Z buffer to prevent close objects from going through the walls.
  7. Draw close objects such as weapon model, legs and 3D HUD.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.