I am developing simple 2D environment in Pygame (Python 3.6), however I think this question is general. The environment is moving (player is rendered on the same position and everything else is scrolling).

I have two ideas how to display the environment:

  1. I can draw it with built-in functions - circles, rectangles, polygons (pretty much like simple HTML5 canvas).

  2. I can load images (textures) and build the environment from them.

My questions:

What option is easier for CPU? - Does it depend on resolutions of textures? Does it depend on how many elements I would draw instead of image? Is there some general guideline what approach is better for what situation? Should I combine both approaches?

Should I care? The game will also contain a lot of other real-time computations - for example path-finding for various objects etc. So, should I even care about optimization of that simple 2D graphics?

  • 2
    \$\begingroup\$ Setup a test and profile? \$\endgroup\$ – Tyyppi_77 Apr 4 '18 at 8:14
  • 1
    \$\begingroup\$ @Tyyppi_77 Smart people learn from their mistakes. Geniuses learn from mistakes of others. It is good to use any hard earn knowledge of other people if they are able to share. \$\endgroup\$ – matousc Apr 4 '18 at 8:21
  • 1
    \$\begingroup\$ I never worked with pygame. But with most graphic frameworks, blitting a texture can be a lot faster than drawing a curve because texture blitting is trivial to parallelize for the GPU. \$\endgroup\$ – Philipp Apr 4 '18 at 8:24
  • 1
    \$\begingroup\$ @matousc sure, but it's also good to show that you've put some work in yourself. \$\endgroup\$ – Tyyppi_77 Apr 4 '18 at 8:31
  • 5
    \$\begingroup\$ It's interesting to know, but you shouldn't care too much about, optimisation should be a low priority, unless it's really affecting the game's performance that it's noticeable running slow. If you optimise your game too early, then you'll sooner or later be hindered by it. \$\endgroup\$ – Steven Apr 4 '18 at 10:20

Blitting is always faster on todays machines. One reason is that you do not need any other calculations except adding indexes. Even for a Polygon you need multiple calculations per line instead of a single blit.

Pygame is not using any GPUs but is painting the stuff merely in memory.

So blitting works also fairly well with cache mechanisms on CPUs as the SDLs software blitmethods are layout in memory byte-by-byte. On drawing individual pixels like circles or polygons you will experience a lot of cache-misses slowing down your drawings much more than blitting

Last but not least you are much more scalable by blitting: If you want to create a tree out of 10 green circles and you need to paint 50 trees you will paint 500 circles instead of 50 blits.

  • \$\begingroup\$ Technically if you render to a memory mapping of any kind that tree you could then simply blit it on; it isnt quite as black and white \$\endgroup\$ – TurtleKwitty Aug 23 '18 at 12:41
  • \$\begingroup\$ @TurtleKwitty: true but still the drawing will take more time than the blitting.. (on the condition you are using CPU, not GPU) \$\endgroup\$ – Peter Parker Aug 23 '18 at 12:58
  • \$\begingroup\$ When you render not to the screen the in memory representation will be the same, so think of your original render time as loading the asset, from there it will be the same time as blitting the image from memory. So technically its slower overall, but a non-issue if you have properly set-up loading schemes \$\endgroup\$ – TurtleKwitty Aug 23 '18 at 13:01
  • \$\begingroup\$ @TurtleKwitty: Sorry, I do not get it: rendering 50 trees is slower than rendering it once and then blitting it 50 times. What do you mean by "loading the asset"? Loading the graphic into memory is not relevant, as this happens outside the displayloop. I also do not understand what you meant by "technically it's slower overall" .. slower than what? \$\endgroup\$ – Peter Parker Aug 23 '18 at 13:17
  • \$\begingroup\$ As you said, rendering it once will be faster, than rendering it 50 times, thats my point, if you render it once to memory during your loading phase, it will not be the same as using an image, since you will in both cases be blitting from memory, as the image will also have been loaded previously. \$\endgroup\$ – TurtleKwitty Aug 23 '18 at 13:24

When in doubt, measure it. Programmers can make educated guesses, but they are just that: guesses. If you really want to know what's faster in your case on your target platform, create a benchmark. Create one program which blits a couple hundred bitmaps each frame and a second one which draws the same number of geometric shapes and see which one reaches a higher framerate.

But in the end this is mostly an academic exercise, because in a real game project you will almost always be working with images only. The reason is that images give your graphic artists a lot more creative freedom. Using geometric primitives instead of bitmaps was a method which was sometimes used decades ago to conserve memory and speed up rendering in some edge-cases, but such tricks are unnecessary on today's hardware. Even a low-end mobile phone should have no issues with reaching a proper framerate if it fills the whole screen with small bitmaps.

  • \$\begingroup\$ Which games are you referring to? Except vector based games like asteroids or battlezone nothing comes into my mind. They used a free moving electron ray to draw the lines onto the screen, but merely because (affordable) CPUs where not fast enough to draw these number of lines. Also these games could only render lines, no other primitives. \$\endgroup\$ – Peter Parker Aug 23 '18 at 13:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.