Alright, What I'm looking to learn how to do is make effect like the "Geiss" screensaver. In other words, I need to know how to take a 2D image, and then warp it. The 2 main effects that I want to know how to do are...

1) Where the screen zooms towards you (I think it's called Blitter feedback)

2) Where a spiral moves over the image. (I like the entire range of these effects)

The closest I've come to understanding these effects is that they use tables, and then I'm assuming they modify the tables using an equation, then render the table. Also, the table equations seem to be polar ones..

I found one equation set that seems to do d=d*d;and r=r*r

(where d=distance and r=angle) to the table, and it produces a "hill" effect.

Any help would be greatly apprecatied!

1) Where the screen zooms towards you (I think it's called Blitter feedback)

2) Where a spiral moves over the image. (I like the entire range of these effects)

The closest I've come to understanding these effects is that they use tables, and then I'm assuming they modify the tables using an equation, then render the table. Also, the table equations seem to be polar ones..

I found one equation set that seems to do d=d*d;and r=r*r

(where d=distance and r=angle) to the table, and it produces a "hill" effect.

Any help would be greatly apprecatied!

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trialI'd love to see some working code if you wouldn't mind! If you want to get in contact with me, please just use my E-mail : Firefunk@bigfoot.com

(If you want to)

Thank you so much again....You've just helped me more today than I've been able to find for the last month!

Thank you!!

that's funny.. I've worked the whole day on some eyecandies here...

and since I was in the mood to code here is the example code I talked about (it's ugly dos-code... but you should get it up and running)...

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <math.h>

int table_x[320*200];

int table_y[320*200];

char buf1[320*200];

char buf2[320*200];

int lerp (const int a, const int b, const int x)

{

// linear interpolation

return a + (((b-a)*x)>>16);

}

void render (char * dest, char * source)

{

int i;

int * tabx;

int * taby;

tabx = table_x;

taby = table_y;

for ( i=0; i<320*200; i++)

{

int x,y,offset,c,d;

x=*tabx++;

y=*taby++;

offset = (x>>16)+320*(y>>16);

c = lerp(source[offset], source[offset+1], x&0xffff);

d = lerp(source[offset+320], source[offset+1+320], x&0xffff);

*dest++ = lerp (c,d, y&0xffff);

}

}

void make_table (void)

{

// zoom effect..

int x,y,i;

i=0;

for (y=0; y<200; y++)

for (x=0; x<320; x++)

{

table_x[i] = (160<<16)+(x-160)*65000;

table_y[i] = (100<<16)+(y-100)*65000;

if(table_x[i]<0) table_x[i]=0;

if(table_x[i]>(319<<16)) table_x[i]=(319<<16);

if(table_y[i]<0) table_y[i]=0;

if(table_y[i]>(199<<16)) table_y[i]=(199<<16);

i++;

}

}

void make_table_2 (void)

{

int x,y,i;

i=0;

for (y=0; y<200; y++)

for (x=0; x<320; x++)

{

float xx = (x-160);

float yy = (y-100);

float dist = sqrt (xx*xx+yy*yy)*0.0002;

float s = sin(dist)*0.99;

float c = cos(dist)*0.99;

table_x[i] = (160.0+ xx * c - yy * s)*65536.0;

table_y[i] = (100.0+ yy * c + xx * s)*65536.0;

if(table_x[i]<0) table_x[i]=0;

if(table_x[i]>(319<<16)) table_x[i]=(319<<16);

if(table_y[i]<0) table_y[i]=0;

if(table_y[i]>(199<<16)) table_y[i]=(199<<16);

i++;

}

}

void graphic (int on)

{

// system dependent.. this turns on 320x200x8bit under dos

int n;

if ( on )

{

_asm {

mov eax, 13h

int 10h

}

outp (0x3c8, 0);

for ( n=0; n<256; n++ )

{

outp (0x3c9, n>>2);

outp (0x3c9, n>>2);

outp (0x3c9, n>>2);

}

} else {

_asm {

mov eax, 3h

int 10h

}

}

}

void blit (char * source)

{

// system dependent.. this shows the picture.

memcpy ((char *) 0xa0000, source, 320*200);

}

void main (void)

{

char ch;

int n;

float t=0;

memset (buf1, 0, 320*240);

// make_table (); // zoom effect

make_table_2 (); // rotation effect..

graphic (1);

ch=0;

do

{

// draw some lisajous dots

// makes sure there is something to feedback..

for ( n=0; n<100; n++ )

{

int x,y;

float tt = t + 3.14*(float)n/100.0;

x=160+80.0*sin(tt*3.0);

y=100+50.0*cos(tt*2.3);

buf1[320*y+x]=255;

}

t+=0.05;

render (buf2, buf1);

blit (buf2);

memcpy (buf1, buf2, 320*200);

} while ( !kbhit() );

graphic (0);

}

C++

From novice to tech pro — start learning today.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.

to render the new image you need a table. The table has one entry for each pixel of the image. in this entry you can look up from where to copy the pixel of the previous frame.

some pseudo code to render a frame: (for a 320*240 resolution)

int table_x [320*240];

int table_y [320*240];

int i=0;

for (int y=0; y<240; y++)

for (int x=0; x<320; x++)

{

newimage[i] = oldimage[table_y[i] * 320 + table_x[i]);

i++;

}

show (newimage);

memcpy (oldimage, newimage, ...)

the trick of the geiss screensaver is, that it doesn't only read out one pixel, but 4 and do a bilinear interpolation between them. That's where the cool smoothing comes from.

to do so you have to store the coordinates in your arrays with more precision than simple integer. I use fixedpoint arithmetics and render the stuff with a hand full of mmx instructions.

(If you need help ask me.. I can give you working code if you want..)

now you need to calculate the tables.

this little code generates a zooming effect..

i=0;

for (int y=0; y<240; y++)

for (int x=0; x<320; x++)

{

table_x[i] = (x-160)*1.1;

table_y[i] = (y-120)*1.1;

i++;

}

and this is something like your twirl effect:

i=0;

for (int y=0; y<240; y++)

for (int x=0; x<320; x++)

{

float xx = x-160;

float yy = y-120;

// distance from center of screen;

float dist = sqrt(xx*xx+yy*yy)*0.01;

// rotate based on distance and

// zoom a little bit:

float s = sin(dist)*1.1;

float c = cos(dist)*1.1;

table_x[i] = 160+c*xx-s*yy;

table_y[i] = 120+c*yy+s*xx;

i++;

}

I hope you got the idea..

again, if you have any further questions ask me..

Nils