Some theory behind ness-engine
This page goes over the theory behind ness-engine and explains the concepts of a scene-oriented graphic engine.
First, let's begin with general terms you should know. if you already worked with a scene-oriented engine before, you might skip this part:
Renderable is every object in the engine you can render. it might also be a container object, i.e. something that holds multiple Renderables as data members and render them together.
Entity is a renderable that represent a single whole object, like a sprite, text, shapes, ect..
Node is a renderable container object that holds other renderables inside it, for example, a list of sprites with 'render' functionality will be considered as a node, but as you will see shortly, a node is more then merely a list.
Transformations are render settings you can apply on an entity. these includes: color tilt, scaling, position, size, rotation, etc...
Transformable is any renderable object that transformations can be applied on (currently all ness-engine objects are transformable).
Ness-Engine is a scene oriented rendering engine.
This means that instead of calling procedural rendering functions yourself, you create scenes and put entities in them, and they are responsible of rendering themselves when required.
Imagine the scene is like a stage, and you put and operate the actors inside.
There are many advantages to scene-oriented rendering. for example, most optimizations you can think of are already implemented inside the scene, like which objects are visible and which are not. in addition the engine provides special scenes that do some hard work for you, like a scene that orders rendering automatically based on z-index, or scene that generate lights.
Having a scene-based structure does not limit you in any way. you can create your own scene types & node and extend the behaviour of the engine indefinitely. you can even access the procedural rendering functions yourself, but that would be a bit pointless.
Scene as a tree
As mentioned before, there are basically two main types of objects in ness-engine: Nodes and Entities.
As you can probably guess, what is called a "Scene" is actually a node object; something you can render that contains other renderable objects inside it.
A scene is built like a tree data structure. the scene itself is the root node, and it contains children nodes and entities (leafs). children node may also contain children nodes of their own:
So the advantages of scene & entities rendering is pretty clear. but why do we need hierarchy of more then one step, i.e. why do we need nodes to contain children nodes and not just entities? well first and most obvious reason is you can use nodes like groups. grouping entities in nodes makes it easy to add/remove a chunk of entities with a single call, or change their rendering order. in the example above, we have one node which is the background and another which is the player. if the player node is above the background node, any entity we will add to background will be rendered under the player as well. cool huh? but that's not the only reason. one of the cool features of nodes hierarchy are transformations inheritance.
As mentioned earlier in this page, renderable objects are also Transformable, meaning you can move, scale, tint and rotate them. but did you know they are also stackable?
Every node can hold it's own transformations, and when an entity is rendered the final output transformations will be summed from all the parent nodes of that entity. so in the example above, lets say we want to move the player and obviously we need to move the body as well as the armor. instead of changing the position of two entities, we only move the node containing the player. same with scaling, color tint, rotating, or any other transformation: we can either do it separately on every entity, or apply it on their parent node.
Transformation inheritance is awesome. once you'll start using it you won't be able to live without it.
Even with scene-oriented rendering, there is still one main object that manages the access to the graphic drivers and is the root for all our objects. this is the renderer. it provides basic rendering functionality (which the scene and entities use), responsible for the begin and end of every frame, manage timing events and animators, and more.. the renderer is the first object you create and the last one you delete.
In most games the viewport is something dynamic; as you move your character around the level, you see different parts of it.
When rendering in ness-engine you can provide a camera object which is your viewport. the engine knows how to cull out objects that are out of screen automatically.
In ness-engine all the memory is managed by shared pointers. in short, that means that every dynamic object object dies as soon as it loses all references to it.
Here are the three rules you must remember about the memory management in ness-engine:
all pointers are made with "make_shared", which include the "we know where you live" optimization. this means that passing shared pointers between threads is illegal and will not work!
when you create your own pointers be sure to use the same types that ness-engine provides, and use make_shred (ness-engine alias it, see API for more info) to make them optimized.
just because pointers are managed does not mean you can't leak. for example, if you put an entity in a scene and forget all references to it, that entity will remain alive and stuck in that scene. don't worry though, it will die when the scene dies, so the "leak" is temporary.
External resources (textures, fonts, etc..) are also managed automatically. a resource will be loaded as soon as you need it, and unloads once you are no longer using it.
You can also pre-load all the resource you need, or easily force a resource to stay in memory if you don't want it to unload.
Help ness-engine grow!