Fast way to "morf" images?
I''m creatig an intro for my game and I tough it''d be cool if there was a transformation from one image to another. I used this method, but it was too slow :
struct RGP storagea[640][480],storageb[640][480]; /*int r,g,b in the struct...*/
BITMAP *aa; BITMAP *bb;
int x,y,c;
for(x<640) /*left out the oring stuff*/
{for(y<480)
{c=getpixel(aa,x,y); /*gets color value from bitmap aa, from x,y*/
storagea[x][y].r=getr(c); /*extracts r value from c*/
/*and same for green and blue*/
c=getpixel(bb,x,y); /*gets color value from bitmap bb, from x,y*/
storageb[x][y].r=getr(c); /*extracts r value from c*/
/*and same for green and blue*/
}}
/*Basicly just converted the bitmaps into simpler form, ''cause had some problems with get + putpixel combo, and this could be faster too*/
/*That part was the loading part and doesn''t matter if it''s fast or not, but here comes the speed requiring part*/
while(!keypressed())
for(x<640) /*left out the oring stuff*/
{for(y<480)
{
if(storagea[640][480].rstorageb[640][480].r) storagea.r-=5;
/*same for g and blue*/
putpixel(buffer,x,y,makecol(storagea[640][480].r,-||-g,-||-b));
}}
blit(buffer,screen...);
}
As I said thats too slow. Only way I got it fast enough was by defining BITMAP *anim[50] and recoring the whole session to it. The problem is that the size of that monster scares the crap out of my pants and if I keep making this kind of compromizes, my game won''t be all that stable..
Is there a faster way to do it?
DirectX 7 has something called DirectTransform. It''ll morph surfaces and stuff like you want. It''s fast too.
"We are the music makers, and we are the dreamers of the dreams."
- Willy Wonka
"We are the music makers, and we are the dreamers of the dreams."
- Willy Wonka
Ok, if I'm not wrong, this is allegro code... I've had some runins with allegro before and this is how I would had done it:
A note; your code must look a bit strange, since it's not linear... Colors which are close to each other "morph" faster that for example black and white. The morphing from black to white would take 51 loops, but from dark gray to black maybee only 10 loops, some pieces of the picture will morph faster than the others! But I don't know, maybee that's how you want it.
It is important wich colordepth you are using. Since 8bit is worthless, I'm asuming youre using 16 or 32 and will use a "if" to determine wich, so cut-pasting this might work
First of, let's make the "storage" a one-dimensional structure instead, with the size 640*480. That way indexing into it will be faster... (pixel a(x,y) would be storagea[x+y*640])
putpixel() is way to slow, I'll replace it with direct-access code (this means buffer must be a standard, memory bitmap)
while(!keypressed){
for(i<640*480){ //all pixels in one loop
//This is your code
if(storagea.r)if(storagea.r>storageb.r) storagea.r-=5;<br>/*same for g and blue*/<br><br>if(_color_depth==16) //If in 16 bit graphics mode (allegro variable)<br>int color=((storagea.r<<8)&(31<<3))+((storagea.g<<3)&(63<<2))+((storagea.b>>3)&(31<<3));<br>//creates new color, same as makecol16(r,g,b) but faster<br><br>((__int16 *)buffer->line[0])=color; <br>//puts the pixel (REAL fast)<br><br>}else if(_color_depth==32){ //If in 32bit mode<br>int color=(storagea.r<<16)+(storagea.g<<8)+storagea.b; <br>//creates new color, replaces makecol32(r,g,b)<br><br>((__int32 *)buffer->line[0])=color; //putpixel<br><br>}<br>blit(buffer,screen)<br>}<br><br>The end! This way you get rid of your main bottlenecks, the twodimensional indexing, and the slow putpixel.<br> </i> <br><br>Edited by - joke_dst on July 20, 2001 10:22:04 PM
A note; your code must look a bit strange, since it's not linear... Colors which are close to each other "morph" faster that for example black and white. The morphing from black to white would take 51 loops, but from dark gray to black maybee only 10 loops, some pieces of the picture will morph faster than the others! But I don't know, maybee that's how you want it.
It is important wich colordepth you are using. Since 8bit is worthless, I'm asuming youre using 16 or 32 and will use a "if" to determine wich, so cut-pasting this might work
First of, let's make the "storage" a one-dimensional structure instead, with the size 640*480. That way indexing into it will be faster... (pixel a(x,y) would be storagea[x+y*640])
putpixel() is way to slow, I'll replace it with direct-access code (this means buffer must be a standard, memory bitmap)
while(!keypressed){
for(i<640*480){ //all pixels in one loop
//This is your code
if(storagea.r)if(storagea.r>storageb.r) storagea.r-=5;<br>/*same for g and blue*/<br><br>if(_color_depth==16) //If in 16 bit graphics mode (allegro variable)<br>int color=((storagea.r<<8)&(31<<3))+((storagea.g<<3)&(63<<2))+((storagea.b>>3)&(31<<3));<br>//creates new color, same as makecol16(r,g,b) but faster<br><br>((__int16 *)buffer->line[0])=color; <br>//puts the pixel (REAL fast)<br><br>}else if(_color_depth==32){ //If in 32bit mode<br>int color=(storagea.r<<16)+(storagea.g<<8)+storagea.b; <br>//creates new color, replaces makecol32(r,g,b)<br><br>((__int32 *)buffer->line[0])=color; //putpixel<br><br>}<br>blit(buffer,screen)<br>}<br><br>The end! This way you get rid of your main bottlenecks, the twodimensional indexing, and the slow putpixel.<br> </i> <br><br>Edited by - joke_dst on July 20, 2001 10:22:04 PM
Thanks. The two dimentionality is away anyway. But the new putpixel and makecol wouldn''t work. compiler claimed __int16 was undeclared and the new makecol didn''t give the right colors, instead it looked all blue and black and mixed. Perhaps my Allegro is of too old vesrion or something...
Oops! I put the parathesis in the wrong places it''s supposed to be (in 16 bit mode):
int color=((storagea.r&(31<<3))<<8)+((storagea.g&(63<<2))<<3)+((storagea.b&(31<<3))>>3);<br><br><br>about the __int16 and __int32 those are visual C++ specific, I forgot about that. You can replace them with<br><br>__int16 = short<br>__int32 = long<br><br>that should work… </i>
int color=((storagea.r&(31<<3))<<8)+((storagea.g&(63<<2))<<3)+((storagea.b&(31<<3))>>3);<br><br><br>about the __int16 and __int32 those are visual C++ specific, I forgot about that. You can replace them with<br><br>__int16 = short<br>__int32 = long<br><br>that should work… </i>
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement