-1

I am working on a kind of 2D game engine. The engine itself is a separate thread running in a loop and calling a renderer function. This functions renders the current game situation from scratch each loop. It all works fine with small objects. I can move a character, add/remove obkect dynamically, detect collisions, and much more.

The problem is that I now added a 8000 x 8000 pixel background and the whole thing collapses. That is a large image but not extreme. right?

The "g.DrawImage(BGImage,new Point(0,0));" function just takes a lot of time and totally wrecks my renderer thread. the same code with a much smaller bg image runs fine. So g.DrawImage seems to be not able to handle large images.

The image drawn is already in an Image object. Loaded only once via BGImage = new Bitmap(Image.FromFile(BGImagePathAndFile));

The reason for using one large image file is that I use g.rotate/Scale/TranslateTransform functions to zoom in/out and pan around on the game field. My objects are pinned to pixel coordinates on that (large) background image.

What would be a good approach to handle this?

Is there a way to only g.DrawImage() my background once and use that as a starting point for each consecutive render?

Any other advice?

Hasse
  • 383
  • 3
  • 11
  • https://stackoverflow.com/a/31541847/1616948 you might want to use GPU accelerated methods instead. – cidermole Mar 06 '22 at 19:13
  • DrawImage together with complex scaling is probably what kills your performance. You should consider using hardware acceleration for that. – PMF Mar 06 '22 at 19:25
  • It is not common to load the background as a huge bitmap. Usually, people like to use tilemaps that are assembled from smaller bitmaps. Such an 8000*8000 bitmap with Alpha Chanel occupies ~256MB uncompressed. Even for a full HD full screen application, a maximum of 1920x1080 is always displayed. But it doesn't matter whether it's tilemaps or a huge bitmap, at 30 fps ~250MB per second must be written. Once the bitmap is loaded, it should run smoothly even on a slightly older computer. If this is not the case, I would assume that something unnecessary is happening in your code. –  Mar 07 '22 at 08:21

1 Answers1

1

First of all, you might want to use a graphics library purpose made for gaming. DrawImage is using GDI+, and while this is hardware accelerated to at least some degree, it is not really intended for high performance gaming. So it is perfectly possible that you can only get so far using GDI. Games tend to use something built on top of Direct3D, or sometimes Direct2D, since these are much better adapted to how modern hardware works. But using these in c# will require some familiarity with how COM and c++ works, since even if you are using an abstraction layer, such layers tend to be leaky.

The typical way to deal with large bitmaps is tiling. Split your bitmap into multiple chunks of say 512x512, compute the position each tile should have, and only draw the tiles visible on screen.

You might also want multiple resolutions of each tile, typically a pyramid of power of twos, so 256x256, 128x128 and so on. That may allow you to do things like zooming in without ever needing to render the complete 8000x8000 source bitmap.

You can also do the rendering to a background buffer using Graphics.FromImage. And while this can help in some cases, it may cause an uneven framerate, since you will need much more time to do the initial rendering of the background.

JonasH
  • 28,608
  • 2
  • 10
  • 23