I guess this is one of does question that never really will be answered but anyway.
I assume that bitmaps a normally stored uncompressed in memory so that's pretty clear but does it directly mean anything to the performance of the game if the memory size of the bitmap is larger? When orx does scaling is it saving a smaller copy of the bitmap in memory, I read somewhere that scaling at run time is expensive, is that the reason and does that mean that zoom function should be avoided if the game gets to slow? Will a very small bitmap be harder to process it is scaled to a large size?
Is it realistic to make object that have graphic size of say 3000*3000, lets say a planet in a 2d space game.
Also on a side i wounder about the bounds of the world, is there a maximum distance that two objects can have and has that an effect on performance?
Comments
It's hard to get a general answer, for sure, but let's try our best.
So, actually, the bitmaps aren't stored in central memory but on GPU memory as OpenGL textures.
Well technically they're stored on central memory for a tiny amount of time while they're on their way to the GPU.
And yes, they're uncompressed unless you're using compressed bitmap which are only available with orx for iOS for now (thanks to tdomhan).
As such, it's good to know on which architecture you're running. Basically GPU textures have some contraints. Some architectures for example only allow textures which width/height are powers of two.
In that case, if your bitmap is say (200x60), orx will actually create a (256x64) texture to store it. That's wasted space there but at least that's portable.
Even when platforms accept non power-of-two (NPOT) textures, having them with power-of-two size makes them slightly faster to use for the GPU.
Also, using what people recently call a texture atlas (similar to the sprite sheet for old timers), will make rendering much more efficient as the GPU will work with only one texture when displaying a lot of different objects.
Every time we need to tell the GPU to switch to a different texture, we have to stop the current rendering batch and switch the context on the GPU. This operation has some time cost which isn't negligible.
As a side note, whenever we need to display a bitmap that doen't have the same blending mode as the previous one, or a different shader or event a different smoothing, we also need to interrupt the current rendering batch and issue a draw call. The less draw calls we issue by frame, the better in term of performances.
If you sync the svn, I added yesterday markers for orxDisplay_DrawArrays in the profiler. Everytime this gets called means we interrupt the current batch and issue a draw call to the GPU. That gives a good idea of how many draw calls are issued by frame.
Also keep in mind that the rendering of the profiler itself uses 18 calls and the display of the FPS uses 1.
That was true with pure 2D rendering (aka blitting) as the source itself needed to be modified before being drawn. And that was CPU intensive, especially if you threw a rotation in there.
That's not the case at all with 3D accelerated rendering. What happens behind the scene is that we create quads (actually it's 2 triangles, but for simplicity sake, let's call them quads).
Every time a sprite is rendered, a quad is created and textured with the appropriate bitmap (let's ignore custom shaders for now.
So the bitmap/texture isn't modified at all, and when filling (aka rasterizing) the quad on screen, for every display pixel the GPU will do a look up to the correct texel in the texture.
So the size of the bitmap/texture isn't really important there (let's forget about the obscure topic that is GPU cache
As explained above, the bitmap/texture itself is left untouched. The GPU is simply doing lookups for every displayed pixel in the original texture, based on the texture coordinate (often called UV).
Well, to sum it up, you should try to make spritesheets/texture atlas whenever you can (in orx you can then specify subparts of it for your bitmap using the TextureCorner and TextureSize config properties of the orxGRAPHIC). These atlas should have power-of-two sizes whenever you can, to make it optimal in term of speed.
That being said, most hardware have limitations on the max size for textures. Most of the time it's 1024 or 2048 for a side.
You also want to group your bitmaps by their use on screen. For example, putting all your pause menu bitmaps in one texture is a good practice as they're likely to be rendered at the same time and that will optimize them as being part of one single batch.
Same for your background, if you level only use a limited set of bitmaps for one background that can fit inside a texture, group them inside.
Well you see the logic now, I guess.
No there isn't any limitation there that would affect performance. The limitation comes however on the precision.
Floating point numbers (aka floats) have a limited precision. The way they are represented on computers (http://en.wikipedia.org/wiki/IEEE_754-1985) means that they're very precise around 0 and get less and less precise the bigger the number is.
In orx we use them to define distance in pixels. That means that up to millions value (< 10 000 000) we still have a sub-pixel precision. However, if we get above that number, our precision will be measured in pixels, and then tens of pixels, etc...
That's why games that need to cover huge areas usually use fixed points for coordinates. In this case they still have the same fixed precision close to 0 or very far from it. Fixed points are represented with integers but orx doesn't have any fixed point support (yet, it has been planned since the beginning but isn't very high priority and that's why you see macros such as orx2F(), ...).
Also note that some architectures don't have a FPU and can't work at all with floats (like the Nintendo DS, for example).
Note that if you're going to develop an open space game, you'll probably reach another performance limitation if you have a huge bunch of objects that exist simultaneously (think of 20 000+). But I wouldn't worry about that in early development stage anyway.
That can be solved with a partitioner. I've planned to add one to orx (likely to be a loose quadree/octree) but haven't had the time yet.
Hope this helps!