Scaling Images

Hello,

I’m working on an SDL port of an old 8-bit game and
I’d like to emulate the same style of 3D view that
this game had.

Basically what I’m looking for is a routine that will
take a rectangular image, can scale it to a smaller or
larger rectangle but can also scale it to appear as
though it’s in perspective. The screenshots here might
make it clearer:

http://wateraxe.demon.nl/alternatereality/

I’m currently using the SDL GFX library which works
fine for the rectangular scaling but can’t do the
perspective scaling as far as I know. I’ve also heard
SDL_SoftStretch mentioned but haven’t found much
written about it.

Can anybody point me to some code or examples that
might be helpful?

Thanks,

Guilherme___________________________________________________________
To help you stay safe and secure online, we’ve developed the all new Yahoo! Security Centre. http://uk.security.yahoo.com

Guilherme De Sousa wrote:

Hello,

I’m working on an SDL port of an old 8-bit game and
I’d like to emulate the same style of 3D view that
this game had.

Basically what I’m looking for is a routine that will
take a rectangular image, can scale it to a smaller or
larger rectangle but can also scale it to appear as
though it’s in perspective. The screenshots here might
make it clearer:

http://wateraxe.demon.nl/alternatereality/

I’m currently using the SDL GFX library which works
fine for the rectangular scaling but can’t do the
perspective scaling as far as I know. I’ve also heard
SDL_SoftStretch mentioned but haven’t found much
written about it.

Can anybody point me to some code or examples that
might be helpful?

You may want to try OpenGL for that. Not only will it be faster than sw
to rescale your surface to an arbitrary size, but you also get some nice
filters for free.

Stephane

Basically what I’m looking for is a routine that will
take a rectangular image, can scale it to a smaller or
larger rectangle but can also scale it to appear as
though it’s in perspective. The screenshots here might
make it clearer:

http://wateraxe.demon.nl/alternatereality/

Right-on! Out of curiosity, have you spoken with the original AR creators?
(A while back they were hoping to make a modern version of AR for PCs,
but that sadly fell through.)

Firstly, it looks like you’re coming from a C=64 perspective, since
there are so few colors in your demo screenshots. Pump it up! Go for
all 256 Atari 8-bit colors, man! ;^) (That game was gorgeous on the
Atari… lots of DLI tricks used!)

(or, like, maybe AR:The Dungeon was less colorful than AR:The City ;^) )

I’m currently using the SDL GFX library which works
fine for the rectangular scaling but can’t do the
perspective scaling as far as I know. I’ve also heard
SDL_SoftStretch mentioned but haven’t found much
written about it.

So in other words you want to take something like this:On Mon, Nov 14, 2005 at 01:13:57PM +0000, Guilherme De Sousa wrote:

±-+
| |
±-+

and turn it into:

|
|
| /
|/

In a sense, it’s simply slicing the rectangle into long, vertical slices,
and scaling each one differently. In the example above, the leftmost ‘slice’
(be it one pixel wide, or more… up to you) is kept at 100% height.

The middle slice is at 50%. The rightmost slice diminishes to nothing. :slight_smile:

Alter the percentages accordingly for other shapes pieces, e.g.:

|
| |
| |
|/

Scaling can be pretty simple to code. And, as someone else pointed out,
you might want to consider using OpenGL. But, I guess it depends on if
you’re targetting high-end PCs, or, say, PDAs, phones or Dreamcasts. :slight_smile:

> Can anybody point me to some code or examples that > might be helpful?

I don’t do perspective, but there is a scaling routine (“thumbnail”, I
call it) in Tux Paint, which is GPL. See the URL in my sig.


-bill!
bill at newbreedsoftware.com
http://www.newbreedsoftware.com/

— Bill Kendrick wrote:

Basically what I’m looking for is a routine that
will
take a rectangular image, can scale it to a
smaller or
larger rectangle but can also scale it to appear
as
though it’s in perspective. The screenshots here
might
make it clearer:

http://wateraxe.demon.nl/alternatereality/

Right-on! Out of curiosity, have you spoken with
the original AR creators?
(A while back they were hoping to make a modern
version of AR for PCs,
but that sadly fell through.)

Dan Pinal who worked on the Dungeon still posts to the
AR Mailing list. Philip Price and Ken Jordan have both
posted to it in the past. Gary Gilbertson who wrote
the music has posted some updated versions of his
music on the AtariAge forums recently. You can find
the AR mailing list at:

http://www.avatardesign.net/alternatereality/

The Archives don’t currently include posts since April
but the list is still in use. Philip Price was working
on a new version but there hasn’t been any news from
him for a few years.

Firstly, it looks like you’re coming from a C=64
perspective, since
there are so few colors in your demo screenshots.
Pump it up! Go for
all 256 Atari 8-bit colors, man! ;^) (That game
was gorgeous on the
Atari… lots of DLI tricks used!)

(or, like, maybe AR:The Dungeon was less colorful
than AR:The City ;^) )

No these are the Atari Dungeon graphics and should
look just about identical :slight_smile: If you look at the
gateway room you should be able to see the DLI stuff.
The Dungeon doesn’t have the colourful ground / sky of
the City. I haven’t added any City content yet.

So in other words you want to take something like
this:

±-+
| |
±-+

and turn it into:

|
|
| /
|/

That’s right.

In a sense, it’s simply slicing the rectangle into
long, vertical slices,
and scaling each one differently. In the example
above, the leftmost ‘slice’
(be it one pixel wide, or more… up to you) is kept
at 100% height.

The middle slice is at 50%. The rightmost slice
diminishes to nothing. :slight_smile:

Alter the percentages accordingly for other shapes
pieces, e.g.:

|
| |
| |
|/

I think the main thing I was unsure of was how to
decide which pixels or vertical slices you should omit
from the image (If you’re scaling down say). I’ll
check out your example anyway.

Scaling can be pretty simple to code. And, as
someone else pointed out,
you might want to consider using OpenGL. But, I
guess it depends on if
you’re targetting high-end PCs, or, say, PDAs,
phones or Dreamcasts. :slight_smile:

I have looked at OpenGL but I feel that it’s properly
overkill for this case given that the 3D environment
is fairly simple and I would like to be able to offer
the port to PDA users.

Can anybody point me to some code or examples that
might be helpful?

I don’t do perspective, but there is a scaling
routine (“thumbnail”, I
call it) in Tux Paint, which is GPL. See the URL in
my sig.

Thanks I’ll have a look at Tux Paint.

Guilherme> On Mon, Nov 14, 2005 at 01:13:57PM +0000, Guilherme De Sousa wrote:


How much free photo storage do you get? Store your holiday
snaps for FREE with Yahoo! Photos http://uk.photos.yahoo.com

[…]

Alter the percentages accordingly for other shapes
pieces, e.g.:

|
| |
| |
|/

I think the main thing I was unsure of was how to
decide which pixels or vertical slices you should omit
from the image (If you’re scaling down say). I’ll
check out your example anyway.

That’s the really, REALLY hard part, and is the reason why basically
the only way to create really good looking low resolution graphics is
(still) to do it by hand - that is, Pixel Art. Though you can come up
with amazingly smart algorithms, the problem is that “good” and "bad"
is decided, somewhat subjectively, by the (human) viewer.

In short, the best scaling method is the one that produces a result
that is most true to the original image.

The bad news is that there is no single, catch-all, truly correct
algorithm, or even a single correct definition of the problem space.
For example, if you’re doing distance/perspective transforms, you
play by different rules than you are when making tiny, fixed size
versions of icons. The latter allows you to make details look better
by modifying the contents of the image (as in reducing the number of
keys when scaling down an image of a keyboard), whereas the former
does not.

Anyway, the simplest way is to calculate the fractional source
coordinate corresponding to each destination pixel, and just grab the
nearest pixel from the original image.

If you’ve?got more cycles to spare, you interpolate between the two
nearest pixels, ie Linear Interpolation. You can use higher order
filters, but beyond cubic (considering the four nearest pixels),
you’ll hardly be able to tell the difference under normal
circumstances.

When scaling images down so much that interpolation filter windows do
not overlap suficiently (ie some source pixels are skipped and not
even considered by the interpolation filters), you need to decimate
the image before interpolating, ie Mipmapping. Usually, you’ll
pre-render down-filtered versions of half size, quarter size, eighth
size etc, until you’ve covered the scaling range you need.

Now, pure interpolation doesn’t handle perspective transforms very
well. When looking at an image at an angle, the smallest projected
dimension has to decide what mipmap and filter to use (or you’d get
"nearest pixel" type of artifacts), impacting the sharpness of the
bigger dimension. Anisotrophic Filtering is the cure, and basically
means you deal with the “big” and “small” dimensions separately, to
avoid filtering away detail that would fit without artifacts.

Anisotrophic filtering and other general computer graphics discussions
are also off topic for this list, so I think I’ll stop here. :slight_smile:

[…]

I have looked at OpenGL but I feel that it’s properly
overkill for this case given that the 3D environment
is fairly simple and I would like to be able to offer
the port to PDA users.

Makes sense. Though I rather like the idea of making use of
accelerated OpenGL whenever it’s available (hint: glSDL), the idea of
totally depending on OpenGL makes me feel uneasy. Only depend on
OpenGL when doing without it would be too much work and/or too slow.

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Tuesday 15 November 2005 14.33, Guilherme De Sousa wrote:

El lun, 14-11-2005 a las 11:20 -0800, Bill Kendrick escribi?:

I’m currently using the SDL GFX library which works
fine for the rectangular scaling but can’t do the
perspective scaling as far as I know. I’ve also heard
SDL_SoftStretch mentioned but haven’t found much
written about it.

So in other words you want to take something like this:

±-+
| |
±-+

and turn it into:

|
|
| /
|/

In a sense, it’s simply slicing the rectangle into long, vertical slices,
and scaling each one differently. In the example above, the leftmost ‘slice’
(be it one pixel wide, or more… up to you) is kept at 100% height.

The middle slice is at 50%. The rightmost slice diminishes to nothing. :slight_smile:

This works, but the effect is NOT perspective. The middle slice is half
the size of the original slice but you need to apply a nonlinear
scaling, because distance (Z) is not linear respect to screen x (x’) and
screen y (y’). In other words, a 1-pixel increment at the left part of
the polygon doesn’t mean the same Z increment that a 1-pixel increment
at the right side. This is essentially the problem which “perspective
correct texture mapping” solves, which involves interpolating u/z, v/z
and 1/z which are linear in x’ and y’, unlike z (I’ll clarify this when
I get to texture mapping in my blog, see signature)

Since in this case he doesn’t have z values (I believe), the correct way
to simulate a perspective mapping knowing only the starting and ending
shapes is to calculate a planar homography between the two shapes.

--Gabriel-- 

Gabriel Gambetta
Mystery Studio - http://www.mysterystudio.com
Gabriel on Graphics - http://gabrielongraphics.blogspot.com