Question
When you have a 2D game that uses really large images (larger than your hardware can support), what do you do? Maybe there's some interesting solution to this problem that never occured to me before.
I'm basically working on a sort of graphic adventure game maker. My target audience are people with little to no game development (and programming) experience. If you were working with such an application, wouldn't you prefer for it to handle the problem internally rather than telling you to "go split your images"?
Context
It's well known that graphic cards impose a set of restrictions on the size of the textures they can use. For instance, when working with XNA you're restricted to a maximum texture size of 2048 or 4096 pixels depending on which profile you choose.
Usually this doesn't pose much a problem in 2D games because most of them have levels that can be constructed from smaller individual pieces (e.g. tiles or transformed sprites).
But think about a few classic point'n'click graphic adventure games (e.g. Monkey Island). Rooms in graphic adventure games are usually designed as a whole, with little or no repeatable sections, just like a painter working on a landscape. Or perhaps a game like Final Fantasy 7 which uses large pre-rendered backgrounds.
Some of these rooms can get pretty large, frequently spanning three or more screens of width. Now if we consider these backgrounds in the context of a modern high definition game, they will easily exceed the maximum supported texture size.
Now, the obvious solution to this is to split the background into smaller sections that fit within the requirements and draw them side by side. But should you (or your artist) have to be the one splitting all of your textures?
If you're working with a high level API, shouldn't it perhaps be prepared to deal with this situation and do the splitting and assembling of the textures internally (either as a pre-process such as XNA's Content Pipeline or at runtime)?
Edit
Here's what I was thinking, from a XNA implementation point of view.
My 2D engine only requires a very small subset of Texture2D's functionality. I can actually reduce it down to this interface:
public interface ITexture
{
int Height { get; }
int Width { get; }
void Draw(SpriteBatch spriteBatch, Vector2 position, Rectangle? source, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
}
The only external method I use that relies on Texture2D is SpriteBatch.Draw() so I could create a bridge between them by adding an extension method:
public static void Draw(this SpriteBatch spriteBatch, ITexture texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
texture.Draw(spriteBatch, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
}
This would allow me to use an ITexture interchangibly whenever I used a Texture2D before.
Then I could create two different implementations of ITexture e.g. RegularTexture and LargeTexture, where RegularTexture would simply wrap a regular Texture2D.
On the other hand, LargeTexture would keep a List of Texture2D's each corresponding to one of the splitted pieces of the full image. The most important part is that calling Draw() on the LargeTexture should be able to apply all the transformations and draw all the pieces as if they were just one contiguous image.
Finally, to make the entire process transparent, I'd create an unified texture loader class that would act as a Factory Method. It would take the path of the texture as a parameter and return a ITexture which would be either a RegularTexture or a LargeTexture depending on the image size exceeding the limit or not. But the user didn't need to know which one it was.
A bit overkill or does it sound okay?
