Jump to content
  • Advertisement
Seer

How should rendering be architected?

Recommended Posts

Currently if I was to program a game using C++ with SFML or Java with LibGDX I would render game objects by calling "object.render()" on the game object. Although this makes it easy to access the information necessary to render the game object, it also couples rendering to the game logic which is something I would like to move away from. How can rendering be implemented so that it is decoupled from the game objects?

I wish to know how this can be done in the standard object oriented paradigm, so please don't suggest that I use an ECS. Thank you.

Share this post


Link to post
Share on other sites
Advertisement

This is very much simplified, and purposefully so.

class Object {
  RenderingData _renderData;
  ...
};

int main()
  ...
  while(stillRunning) {
    stillRunning = updateGameLogic(allObjects);
    renderAllObjects(allObjects, renderer);
  }
}

The renderAllObjects function takes in the renderer interface, or a concrete renderer object, or whatever you have or want to pass in, grabs each object in the list and pulls out the render data (which can also be anything you want it to be, textures, models, buffers, shaders, etc), and passes it into the renderer in a renderer specific way.

If you just need to decouple game logic and rendering, this is one way to do it, but not the only way, as i'm sure others will chime in with their ideas.

Share this post


Link to post
Share on other sites
5 hours ago, Seer said:

I wish to know how this can be done in the standard object oriented paradigm, so please don't suggest that I use an ECS

ECS is an architectural pattern which follows composition over inheritance principles. And as such this is an object-oriented design.

Share this post


Link to post
Share on other sites
On 11/16/2018 at 11:07 PM, Seer said:

Currently if I was to program a game using C++ with SFML or Java with LibGDX I would render game objects by calling "object.render()" on the game object. Although this makes it easy to access the information necessary to render the game object, it also couples rendering to the game logic which is something I would like to move away from. How can rendering be implemented so that it is decoupled from the game objects?

Instead of game objects containing rendering logic, have them own a renderable sub-object. Instead of "for each object, render", use "for each object, add renderables to queue". Then pass the queue of renderable items to your renderer object.

e.g. instead of a Monster having a "Render" function that actually goes and draws some things, the Monster class might be composed out of a Sprite or a Model class. You can then have some code like this can extract all the monster sprites to be drawn:
std::vector<Drawable*> queue; for( auto& monster : monsters ) queue.push_back( monster.GetSprite() );

You can take this a step further by removing the specific game objects (e.g. Monster) from this process. When you create a Sprite/Model/etc, it can have it's lifetime owned by the Monster (or whatever created it), but also be weakly owned by a "Scene". The scene then internally has a list of all Drawables at all time, which it can iterate through without any knowledge of your specific gameplay classes.

On 11/17/2018 at 4:49 AM, _Silence_ said:

ECS is an architectural pattern which follows composition over inheritance principles. And as such this is an object-oriented design.

This is off-topic, but ECS is much more closely related to the relational model (so much that I'd go as far as to say that is the relational model, reinvented, badly). In ECS you put logic in systems and non-abstracted data layouts in components, whereas OO typically ties the two together. Also, ECS has the silly restriction that you can only have one level of composition -- Entities can be composed from components, but components can't utilize composition. Some particular ECS implementations also force the silly restriction on composition that Entities can only have one component of a particular type. Neither relational or OO have those kinds of strange restrictions.

Share this post


Link to post
Share on other sites

@Hodgman

I especially like this approach. Great for ordering sensitive objects later on. i.e. handling transparencies that exist within an object.

Edited by orange451

Share this post


Link to post
Share on other sites

I might have been wrong here. But actually 

Quote

ECS follows the composition over inheritance principle

and

Quote

Composition over inheritance (or composite reuse principle) in object-oriented programming (OOP) is the principle that classes should achieve polymorphic behavior and code reuse by their composition (by containing instances of other classes that implement the desired functionality) rather than inheritance from a base or parent class.[2] This is an often-stated principle of OOP, such as in the influential book Design Patterns

Sources:

https://en.wikipedia.org/wiki/Entity–component–system

https://en.wikipedia.org/wiki/Composition_over_inheritance

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!