0
\$\begingroup\$

I've been wondering how to achieve some kind of zooming behavior with 2D graphics. I'm pretty sure that this is not right term, but let me try to explain my thoughts.

Let's start by defining that we are using here tileset with 16x16 tiles. That would something like this:

When we're looking these graphics here, all the tiles look pretty small. Now, when we load this tileset to RPG Maker 2K and look at it in game, it looks something like this:

Like you can see, the image is more zoomed and tiles look a lot more bigger than in a real tileset. How do you think this kind of effect is done in code and how I can do it?

\$\endgroup\$
3
  • \$\begingroup\$ just plot every pixel as 2x2 pixels (or 3x3, or 4x4..).. Since there's also other, more involved upscaling methods (like eagle etc), I'll let someone else answer. \$\endgroup\$ Commented Dec 26, 2012 at 8:21
  • \$\begingroup\$ @Wondermike, it's not zooming. It's called scaling. Zooming would be "magnifying" from the initial "scale" of your view. I assume it's just done by transformation matrix ( well...I don't see a different way). Stretched to meet he viewport/screen bounds. \$\endgroup\$
    – Sidar
    Commented Dec 26, 2012 at 8:28
  • \$\begingroup\$ I think I understand what you're saying and it makes sense. I'm still waiting for someone to make it more clear. \$\endgroup\$
    – WonderMike
    Commented Dec 26, 2012 at 8:32

1 Answer 1

3
\$\begingroup\$

The term you're looking for is scaling, not zooming.

If you search scaling algorithms, you'll find a very large number of them. Different scaling algorithms have different qualities and are optimized for different purposes. Some are designed to scale up low-quality bitmaps while making them look smooth and pretty, often used when trying to play games made for old resolutions like 320x200 at newer monitor resolution sizes like 1920x1080.

Your graphics hardware has several simpler scaling algorithms naturally built in. If you try to render a 16x16 texture to a square that is 64x64 in size, OpenGL/Direct3D will just do the right thing. They'll also handle uneven sizes. The same is going to be true of whatever other low-level 2D graphics API you might be using.

The simplest approach is to just change your sample rate. Say you have a 16x16 bitmap that you want to scale up to 32x32. That is a 2x increase in dimension, so you would "sample" the source bitmap twice in each dimension (for a total for four samples). Example:

Source = 1 2
         3 4
Destination =
         1 1 2 2
         1 1 2 2
         3 3 4 4
         3 3 4 4

Notice how for the first row in the source, we wrote out each element twice in the destination. Likewise, for each row in the source, we wrote out two rows in the destination. 2x scale factor.

In code, that might look something like following (in one dimension; should be simple enough for you to expand to two dimensions):

scale = in_width / out_width;
for (dx = 0, sx = 0; dx < out_width; ++dx, sx += scale)
{
   output[dx] = input[sx];
}

Note that scale is the reciprocal of the scale factor. That is, a 2x scale would actually be 1/2 in the code above. The terminology can be a little ambiguous and confusing, unfortunately.

The algorithm will handle scaling up and down, to even or uneven sizes. If you expand it to two dimensions properly, it'll even handle scaling to different aspect ratios (e.g., changing a square input bitmap to a rectangular output). The results won't be great, but they'll work. I wouldn't use that code in production, but if you want to get your feet wet with some basic bitmap manipulation code, it's as good a starting point as any.

There are much more robust and efficient ways to write that, but I'd guess those might be a bit beyond your current skill level.

If you are interested in higher quality scaling algorithms, or more optimized scaling algorithms, take a look at the excellent WikiPedia Image Scaling article, which covers most of them and has either explanations of the algorithms or links to pages with explanations.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for answering Sean. This explains pretty much what I was after. For some reason I've never understood this properly, but now I finally got it. I'm experienced programmer, but graphics have allways been my Achilles' heel. I will look at those algorithms and I'm sure I'll be fine. \$\endgroup\$
    – WonderMike
    Commented Dec 26, 2012 at 9:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .