Large Bitmaps
The standard bitmap is unable to load files that exceed the GPU's texture size limit. As such, the Bitmap class has special "chunk" functionality, which splits up a Bitmap into several smaller bitmaps and will selectively redraw only the parts of the bitmap that have changed.
This "chunky bitmap" acts as though it's one bitmap, but in reality is comprised of several smaller bitmaps, referred to as "chunks". When creating a Bitmap, you can specify the width and height of the chunks.
When you draw to a normal Bitmap and then proceed to Lock() that bitmap, the entire bitmap will be copied from the CPU to the GPU. That's a huge waste of CPU and GPU power when you've only changed pixel (0, 0) from black to red on, say, a 8192x8192 bitmap. So instead of using a normal bitmap, you could use a chunky Bitmap in this case.
Let's take a look at a quick example for how to create a chunky Bitmap.
Bitmap b = new Bitmap(8192, 8192, 256, 256);
b.Unlock();
b.SetPixel(0, 0, Color.Red);
b.Lock();As you can see in this code block, the only difference between a chunky bitmap and a regular bitmap is the constructor, which now has two chunk width and height parameters (256x256 here). Beyond that, it functions exactly the same.
Now, when you draw on a chunky Bitmap and Lock() it, it will only redraw the chunks inside the chunky Bitmap that have changed. As such, when you have an 8192x8192 chunky Bitmap with a chunk size of 256x256 and then change pixel (0, 0) from black to red, it will only redraw the first chunk - the other 1023 bitmaps remain untouched. This provides an immense performance boost, but at the cost of memory. Naturally, storing 1024 256x256 bitmaps takes up more memory than one 8192x8192 bitmap.
Beyond creating and splitting up bitmaps into chunks though, this chunk functionality also allows you to load files that exceed the texture size limit. SDL2_image, the library that converts the raw image data to a Bitmap, typically immediately creates a standard Bitmap from the image data. If that image data exceeds the texture size limit, it would crash. As such, odl has a brand new dependency, decodl, which it will switch to if the image exceeds the texture size limit. This decoder is about 2 to 3 times as slow as the traditional decoder, so is only used as a fallback for very large images.
This slowdown is worrisome enough, and should be plenty reason not to use overly large images. However, if you must exceed the texture size limit, it is highly suggested that you exceed it vertically, and not horizontally. When splitting an image up into several Bitmap chunks, it has to copy the data from the raw image data. If the image only exceeds the maximum texture height, this can be copied in one call, as all the data is right next to each other. However, if it exceeds horizontally, or horizontally and vertically, it has to copy a very large amount of data, but line-by-line. This is an insanely long process, and will likely not be viable for use.
Why does decodl exist at all then? Because it is very useful for tilesets that do end up exceeding the maximum texture size. The goal is not to support 256x100,000px tilesets, but decodl handles 256x16384 - 16384px being a common limit these days - perfectly fine.
The LargeBitmap class supports all methods that Bitmap does. You can draw text, circles, rectangles, lines, etc. just like you would on a normal Bitmap. The only difference is behind-the-scenes, and when creating the bitmap.
In conclusion, split a Bitmap up into multiple chunks when you have a large bitmap and are only redrawing a small portion of it at a time.
In RPG Studio MK, the use-case for the chunky Bitmap was very large maps. A 256x256 map with 32x32 tiles amounts to a 8192x8192 tiles - or 67.108.864 pixels. If you change the top-left tile, the first 32x32 pixels, recreating the entire bitmap took far too long to be acceptable.
Last updated