Very Large Images

Started by
2 comments, last by TogaMario 16 years, 1 month ago
Hello all, I'm working on a side scrolling game that uses a large (6,000+ pixel) image as the background. Currently, what I have going is as follows: Create a surface from a file - my large image. Create a texture using only a portion of that surface (800x600 rect) at any given time. Draw that texture with a sprite. Problem: This is very slow for practical purposes, as I would need it to scroll smoothly. I've also tried: Create a surface from a file - my large image. GetBackBuffer from device. StretchRectangle a portion of my large surface onto the backbuffer. Problem: While this runs very very quickly, my 32 bit alpha in the png turns into a horrid mess. I would really love to use the backbuffer method, but I don't know that it can be fixed to support the alpha blending that I require. Does anyone know a better method (other than chopping the image up manually into 1024x1024 chunks and having to keep up with a ton of textures in my code)? I'm using C# with VS2008 Pro and DirectX 9 - but any pseudo-code in C++ I will be able to translate. Thanks, -Tyler
P.S. - This is what the alphabet would look like if Q and R were eliminated.
Advertisement
How about using a (larger version of) a tile implementation?

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

I thought about trying to automate the process of ripping it apart and putting it into an ArrayList of Textures to process automatically at start, so it would take the speed hit only at the beginning (during a load process, maybe), but I think I might need help in the form of an outline of how that might work.

Maybe:

Load huge surface from file.
SurfaceLoader.FromSurface and specify the smaller 1024x1024 texture, along with the huge surface portion I want copied.
Do that for each segment till we reach the edges of the huge image.
Loop through these textures at different offsets, possibly governed by a custom class that also holds X / Y information about the texture - so I just multiply the offset by 1024 ... ?
P.S. - This is what the alphabet would look like if Q and R were eliminated.
Success! Thanks for the suggestion and it works beautifully.

In a nut shell (for anyone wanting to do the same) -

Create a custom class that will store the amount of X and Y tiles of 1024 x 1024 that you'll produce.

You'll need a temporary off-screen plain surface to hold the raw image till it's processed.

This class should also have an array of some type that keeps your Textures in it.

----

Get the image info (TextureLoader.ImageInformationFromFile)

Generate the off-screen plain surface using the dimension from that file info ... make sure the format is the same, too.

Load the surface from a file (SurfaceLoader.FromFile)

Loop through the X and Y coords -
+ Make sure that your X and Y aren't within 1024 pixels of the total image bounds, and if they are, reduce the amount of rectangular copying to fit. If you try to copy using a Rectangle that goes out of the raw image's bounds, this will produce an error.
+ Generate the new texture that will be 1024 x 1024 and the same format as your surface.
+ Generate another temporary surface by using the WhateverTextureName.GetSurfaceLevel(0) method.
+ Use SurfaceLoader.FromSurface to copy the source Raw Surface's rectangle (which will be 1024x1024 unless you've reached the edges, in which case, you heeded the warning above) and put them into the destination surface (the texture surface that we just got with the last step).
+ Add this new texture to the Texture array that you're storing all these new textures in.

Make sure to increment the class X and Y values each iteration, so that when you're done, you know how many X and Y 1024 x 1024 tiles you end up with.

I set my class constructor to take the image's path, so it might be a good idea to do that as well.

So I call my constructor, it generates a new "dynamically large image" object (I named it DLI for short) ... and in the device.beginscene() method, if the DLI isn't null, I ForEach through all the Textures in the DLI.TextureArray - I call a transformation on a sprite object, setting it to the proper X and Y coordinates (using the data stored in the DLI object properties) and draw it.

If you have any questions, let me know, but it runs very smoothly for me. I imagine it's only limited to the amount of memory the raw (and huge) image takes up when processing, and how many tiles you end up with.

-Tyler
P.S. - This is what the alphabet would look like if Q and R were eliminated.

This topic is closed to new replies.

Advertisement