Rendering

From TheManaWorld
Jump to: navigation, search

This article contains information for Programmers working or interested in working for The Mana World

This article is currently only a proposal

The features or design guidelines described in this article are only a proposal made by one or some persons. It has not been evaluated or accepted by the core development team yet. Feel free to add your personal opinion about them or make counter proposals.

I'm not sure if i got the current rendering approach right, so feel free to correct (or flame) me ;)

Currently, all rendering happens in Image::draw(), this is a simple approach that works, but it has some drawbacks. Model and view are combined in the same class, this makes it hard to implement different approaches for different graphic libraries (SDL vs. OpenGL in this case). There's also a tight coupling between the Image class and various other classes that could be avoided.

Actually the SubImage class just abstracts from drawing a part of a bigger image, it does not really contain a SubImage. This is used to simplify the drawing code in other places, but places an important constraint on the way how rendering can be done. As the drawing code is in the (Sub)Image class, rendering happens on a image-by-image basis. OpenGL suffers a lot from this, as the repeated glBegin()/glEnd() calls cause some overhead, one should always try to send as much data at once as possible.

To improve the situation, especially with OpenGL, I'd suggest the following, based on how the Map would handle the new stuff.

Tilesets are indexed like this:

1 2 3 4 
5 6 7 8
9 x x x
x x x x

Instead of having a lot of Images in the Map, it is associated with a tileset and has a set of indices into the tileset.

That way, a rendering class could get the right x,y values inside the tileset with a simple calculation based on tileset's tile-width, tile-height, row-width and the index into the tileset.

For a SDLRenderer, this would probably just end up in copying the SubImage::draw() code and having the above calculation, as the 'draw a part of a larger image' code is already there.

For a OpenGLRenderer, it would like a little different, a vertex array could be prepared beforehand, as the vertex positions will never change, only the textures. For the texture, there would be a prepared array of coordinates into the tileset texture for each tileset that is being used. That way the indices stored in the map could probably directly be sent to opengl to render the map (I need to read up on glDrawElements to actually confirm that).

So the rendering code for the SDL part would just be moved around a little and separated from the data structures (i.e. quite a trivial change). The OpenGL code would get quite some change for the better, as the separation of image and map data allows a quite better handling of this stuff.

PS: I hope anyone understands what I'm trying to say, I feel like unable to speak english today...