Please note that this is *nowhere near* a functioning entity, it is purely speculation and there may well be better ways of doing it.
Also this post kinda follows on from some of the other ideas I've heard around such as storing sprites in PNG format, and seperating the graphics engine and the gameplay engine; which may or may not be feasable.
I may also have greatly mis-understood the current graphics internals, and some of my post may be invalid.
This is mainly research for my own benefit and I'm in no way imposing it on OTTD. I'd be interested to hear your views on it, and how this might differ to using other methods.
As most of you know, the current graphics system works by blitting all of the sprites that the user sees in a frame, for every frame. This means that the CPU has to spend a lot of time transferring pixel data around.
[edit]I have just talked with Tron and this is *not* true. I had mis-understood the graphics code. Infact OpenTTD only redraws what is necessary. This is actually an advantage to opengl since opengl will have to redraw the entire frame for every draw. This invaildates a large amount of my post[/edit]
The aim is, one way or another - either by using OpenGL, SDL, or some other API - to eliminate this copying of pixel data, so that only positional data has to be specified for each frame.
This is done by having a texture containing lots of sprites, then drawing a quad (a square) in 3-D space, and specifying the texture co-ordinates which should be rendered onto this quad. The texture itself should always stay in video memory, and the video card should do all of the processing.
Good things about OpenGL:
- Smooth Zooming - OpenGL will provide an infinate number of levels of zoom with relatively little processor cost.
- Only positional data has to be sent for each frame.
- Positional data can all be specified in one huge array, and drawn using one function call.
- Alpha blending is made easy - textures can be full 32 bit colour.
- lighting? Explosions? weather effects?
- 3D vehicles?
- Textures are going to use MASSIVE amounts of memory at 32 bit colour. Judging by the 800 x 18928 pixel image containing all of the sprites Celestar sent me, it is going to require upwards of 50mb. Also in another post I read about the idea of sprites being stored using PNG. The palettized image Celestar sent me was around 3-4mb in size. The RGB+A PNG image was 18mb in size.
- Textures must be powers of two in dimension. So we cannot just create a 800x18928 texture.
- By the time it all works out, no actual speed benefit? The experiments I've been doing involve rendering 256x256 quads and zooming in and out so that the entire map is visible. It renders nicely at 75fps (cap due to vsync) - but my CPU usage is somewhere up at 80%. I'm on an Athalon 2600XP+ with a GeForce 4 Ti4600 graphics card, which is all quite powerful. Transport Tycoon was designed for old systems which aren't going to be as capable. Culling may help though, I mean, who is going to want to see all 65535 tiles at once?
- OpenGL uses floating point positional data for nearly everything. This means that quite a bit of calculation may be required to align things and such.
- As far as I am aware, OpenGL cannot handle indexed sprites, this throws out palette animations [edit]Someone showed me a very nice demonstration of palette animations using opengl today. I take it all back.[/edit] - though OpenGL does provide functions for modifying small portions of large textures efficiently. Also palette animations could be replaced with multiple sprites.
- Potentially crippling to people with older computers.
- Generation of the textures at runtime. Take a large set of PNGs, and pack as many as possible into a relatively large texture. - This might take a while to load though.
- One texture for each different 'set' of things. Since there are limitations on the sizes we can make textures, it might be sensible to have several 4096x4096 textures. Also you can only specify one texture per array of positional data. So it would make sense to have a 'landscape' texture, and to then specify positional data for all of the landscape which needs to be rendered. And to have a 'buildings' texture, and an array of positional data for all of the buildings, and so on.
- (Re: PNG sprites) Do we really need 32 bit colour?
- Running graphics engine and gameplay/networking engines on seperate threads?
- A lot of this is speculation.
- I may be factually incorrect about a few things I have said.
- You may already be aware of the problems I have presented, I don't intend to be patronizing.
- OpenGL is NOT the solution to everything! there may well be better solutions, and some of the things I've written about in this post will apply to other APIs and solutions.
- Some of this post may not make sense because I may have assumed you know things just because I know them. Let me know if I need to explain anything more clearly
- I have no wish to stir up fights about whether we should be using one graphics API or another - I'm interested to know about the technical details.
- Irid.