Warping images

Hi,

I need to warp rectangular images to two other shapes (see attached

file), with interpolation. How easy or difficult is it?

Is there any library that can do this? Or should I use OpenGL? Has

anyone done this?

Any help is appreciated.

<<distortions.gif>>_______________________________________
I?aki Idigoras Igartua <@Idigoras_Inaki>
IKERLAN - Elektronika (http://www.ikerlan.es)
P.Box 146, 20500 Arrasate - Gipuzkoa
Phone +34 943 712400 - Fax. +34 943 796944

-------------- next part --------------
A non-text attachment was scrubbed…
Name: distortions.gif
Type: image/gif
Size: 1621 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20020305/b2fbb987/attachment.gif

Hi,

I need to warp rectangular images to two other shapes (see attached
file), with interpolation. How easy or difficult is it?

In theory, it’s pretty easy. Just figure out a “nice” pair of functions:

source_x = fx(destination_x);
source_y = fy(destination_y);

Then loop over the pixels of the destination surface, grabbing pixels
from the source surface:

for(y = 0; y < dst->height; ++y)
	for(x = 0; x < dst->width; ++x)
		setpixel(dst, x, y, getpixel(src, fx(x), fy(y)));

For good looking results, getpixel() should take fractional coordinates
(fixed or floating point) and read from the source image with bilinear or
bicubic interpolation, or maybe even some form of adaptive supersampling,
to avoid aliasing artifacts. Obviously, it should also implement
clipping, clamping or wrapping, or Bad Things will happen when the
transformation functions generate coordinates outside the source image.

Is there any library that can do this?

Dunno. Probably - but I guess it would be nice if it had a nice licence
and wasn’t too hard to port to SDL…

Or should I use OpenGL?

OpenGL only supports (or at least, most cards only implement) linear and
perspective texture transformations, so you’d have to tile the images
with some suitable grid size, and then move the vertices around to get
the desired effect. Of course, this could be very, very fast, compared to
any software implementation, at least as long as you stick to a
"reasonable" grid resolution.

Has anyone done this?

It’s been done countless times in various contexts - but as (until these
days) it hasn’t been doable in real time, it’s been a bit outside my main
field of interest…

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Tuesday 05 March 2002 10:51, Idigoras Inaki wrote:

Or should I use OpenGL?

OpenGL only supports (or at least, most cards only implement) linear and
perspective texture transformations, so you’d have to tile the images
with some suitable grid size, and then move the vertices around to get
the desired effect. Of course, this could be very, very fast, compared to
any software implementation, at least as long as you stick to a
"reasonable" grid resolution.

I am thinking of OpenGL Evaluators (Red book, chapter 12). You use Bezier curves with
this. The easiest way to get close to the shapes you sent is probably the definition of 4x4
control points (you calculate them yourself like suggested in the previous mail) and a 2D
evaluator of degree 3 (= order 4). All interpolation is then done by GL, with all the nice
filtering and stuff.

The control points can be specified with z = 0, and you can use an orthographic
projection. Control points [0][0], [0][3], [3][0] and [3][3] would form the corners of your
shape, and you arrange the rest of them in between in a sensible way. The nice thing is
that the border of your shape starts from the corner points along the tangent to the next
control point, so the intermediate control points actually have a meaning.

Am I making sense? Hmm…

Has anyone done this?

Me not. But the theory looks good, it’s probably fast, and it’s only 2 GL calls.

Carsten

Yeah, I know - but I’m suspecting that this (like most of the methods not
used in games) isn’t accelerated, unless you have a very high end
professional 3D card…

Still, if it does the job, it’s certainly a lot easier than implementing
it all in software! :slight_smile:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Wednesday 06 March 2002 20:09, Carsten Burstedde wrote:

Or should I use OpenGL?

OpenGL only supports (or at least, most cards only implement) linear
and perspective texture transformations, so you’d have to tile the
images with some suitable grid size, and then move the vertices
around to get the desired effect. Of course, this could be very, very
fast, compared to any software implementation, at least as long as
you stick to a “reasonable” grid resolution.

I am thinking of OpenGL Evaluators (Red book, chapter 12). You use
Bezier curves with this. The easiest way to get close to the shapes you
sent is probably the definition of 4x4 control points (you calculate
them yourself like suggested in the previous mail) and a 2D evaluator
of degree 3 (= order 4). All interpolation is then done by GL, with all
the nice filtering and stuff.

At 10:51 05.03.2002 +0100, you wrote:

    I need to warp rectangular images to two other shapes (see attached

file), with interpolation. How easy or difficult is it?

    Is there any library that can do this? Or should I use OpenGL? Has

anyone done this?

I recently coded a twist-effekt with opengl, so this means, OpenGL gets
stuff like this easily done.
From the Outlines you gave (“distortions.gif”) it looks like this is
really easy to do. I guess you want to morph linear in a certain amount of
time. Now you tile your texture, maybe 30x30 or 60x60 (anything more would
probably cause a significant loss of speed on older cards like TNT’s, just
have a try). Create three arrays of Coordinates for the original coord, the
destination coord and the actual coord like this:
GLfloat orig_pos[Y_TILES][X_TILES][2], dest_pos[Y_TILES][X_TILES][2],
morphed_pos[Y_TILES][X_TILES][2].
now, in every step you know the actual time elapsed and the duration, so go
thru your coords like this:

for(iy=0;iy<Y_TILES;iy++)for(ix=0;ix<X_TILES;ix++) {
morphed_pos[iy][ix][0] = (des_pos[iy][ix][0]-orig_pos[iy][ix][0])

  • (time_elapsed/duration) +
    orig_pos[iy][ix][0];
    morphed_pos[iy][ix][1] = (des_pos[iy][ix][1]-orig_pos[iy][ix][1])
  • (time_elapsed/duration) +
    orig_pos[iy][ix][1];
    }

simple math … at last you have to render it:

for(iy=0;iy<Y_TILES-1;iy++)
glBegin(GL_QUAD_STRIP);
for(ix=0;ix<X_TILES;ix++) {
glTexCoord2f(ix/X_TILES,iy/Y_TILES);
glVertex2fv(morphed_pos[iy][ix];
glTexCoord2f(ix/X_TILES,(iy+1)/Y_TILES);
glVertex2fv(morphed_pos[iy+1][ix];

}

That should be it … report any errors, I just coded this in my
mailprogram …

Just one thing to add: OpenGL is designed to do the “real work” for YOU,
not to let you do it like on older machines. That’s what I learned after
half a year of OpenGL-Programming, after I switched from my commodore 64
(LOVE! :wink: to shitty windoof-machines, but this shitty windoof stuff doesn’t
really matter if you have 1000 times the speed of a RCISC like the
commodore (it is CISC-design, but only 53 MLcommands make it seem a
RISC-Computer)…

HOpe it helps …
St0fF 64

Just found a small error in my little code example, scroll down!

    I need to warp rectangular images to two other shapes (see attached

file), with interpolation. How easy or difficult is it?

    Is there any library that can do this? Or should I use OpenGL? Has

anyone done this?

I recently coded a twist-effekt with opengl, so this means, OpenGL gets
stuff like this easily done.
From the Outlines you gave (“distortions.gif”) it looks like this is
really easy to do. I guess you want to morph linear in a certain amount
of time. Now you tile your texture, maybe 30x30 or 60x60 (anything more
would probably cause a significant loss of speed on older cards like
TNT’s, just have a try). Create three arrays of Coordinates for the
original coord, the destination coord and the actual coord like this:
GLfloat orig_pos[Y_TILES][X_TILES][2], dest_pos[Y_TILES][X_TILES][2],
morphed_pos[Y_TILES][X_TILES][2].
now, in every step you know the actual time elapsed and the duration, so
go thru your coords like this:

for(iy=0;iy<Y_TILES;iy++)for(ix=0;ix<X_TILES;ix++) {
morphed_pos[iy][ix][0] = (des_pos[iy][ix][0]-orig_pos[iy][ix][0])

  • (time_elapsed/duration) +
    orig_pos[iy][ix][0];
    morphed_pos[iy][ix][1] = (des_pos[iy][ix][1]-orig_pos[iy][ix][1])
  • (time_elapsed/duration) +
    orig_pos[iy][ix][1];
    }

simple math … at last you have to render it:

Just some missing lines and symbols …

for(iy=0;iy<Y_TILES-1;iy++) {
glBegin(GL_QUAD_STRIP);
for(ix=0;ix<X_TILES;ix++) {

            glTexCoord2f(ix/X_TILES,iy/Y_TILES);
            glVertex2fv(morphed_pos[iy][ix];
            glTexCoord2f(ix/X_TILES,(iy+1)/Y_TILES);
            glVertex2fv(morphed_pos[iy+1][ix];
     }
     glENd();>}

That should be it … report any errors, I just coded this in my
mailprogram …

Just one thing to add: OpenGL is designed to do the “real work” for YOU,
not to let you do it like on older machines. That’s what I learned after
half a year of OpenGL-Programming, after I switched from my commodore 64
(LOVE! :wink: to shitty windoof-machines, but this shitty windoof stuff
doesn’t really matter if you have 1000 times the speed of a RCISC like the
commodore (it is CISC-design, but only 53 MLcommands make it seem a
RISC-Computer)…

HOpe it helps …
St0fF 64


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

[…]

Just one thing to add: OpenGL is designed to do the “real work” for
YOU, not to let you do it like on older machines. That’s what I learned
after half a year of OpenGL-Programming, after I switched from my
commodore 64 (LOVE! :wink: to shitty windoof-machines, but this shitty
windoof stuff doesn’t really matter if you have 1000 times the speed of
a RCISC like the commodore (it is CISC-design, but only 53 MLcommands
make it seem a RISC-Computer)…

Be it a million times faster - it still sucks if you can’t get those
cycles when you need them, every time you need them.

Real time games are, well real time

(Says RT-Dave of the Real Time Linux Foundation. :slight_smile:

http://www.realtimelinuxfoundation.org

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Thursday 07 March 2002 03:47, St0fF 64 wrote:

At 15:49 07.03.2002 +0100, you wrote:

Be it a million times faster - it still sucks if you can’t get those
cycles when you need them, every time you need them.

Real time games are, well real time

And any precalculations suck … you’re damned right where you’re damned right!

St0fF

At 15:49 07.03.2002 +0100, you wrote:

Be it a million times faster - it still sucks if you can’t get those
cycles when you need them, every time you need them.

Real time games are, well real time

And any precalculations suck …

…and they don’t even help. If you can’t even maintain a continuous
stream of audio samples, video frames or whatever, the experience is
inevitably compromized.

And of course, if you need to respond to real time input (like in a game,
or a software synthesizer played from an external MIDI controller),
buffering has to be minimal, so not even real time capable drivers can
save you.

you’re damned right where you’re
damned right!

I know… :wink:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Thursday 07 March 2002 16:35, St0fF 64 wrote: