Panel alpha blitting

Posted By: RyuMaster

Panel alpha blitting - 12/26/08 16:49

Hi, everyone!
I needed alpha blitting for my game, and there was no single thread on a forum with relevant help, and no one
answered to my topics, so I coded it myself and I hope, this code will help some other newbies like me, stucked
with the same problem during development.


Here is the demo: http://rapidshare.com/files/176980140/alphablit.rar.html

It has overlay.png image, and source.png image, both with transparency.

Overlay.png is attached to mouse and moves around screen. When
some of it pixels touches source.png, this part of source.png becomes transparent.

Here is the source code. Shoud work with all extreme cases.
Unfortunately, pixel operations are slow, and as I was told in a forums, shaders can not be used with panels.
I'll try to find a way to make this code work faster.


Quote:
////////////////////////////////////
/////By RyuMaster///////////////////
////////////////////////////////////



#include <acknex.h>
#include <default.c>



BMAP* original = "panel.png"; //Holder of original image
BMAP* overlayb = "overlay.png"; //Holder of our overlay image
BMAP* tempr; //This will hold original image's copy
var entered_panel = 0; //This will confirm that we create copy during overlap once



///Our image panel
PANEL* aircraft_pan =
{
bmap = original;
pos_x =200; pos_y = 200;
flags = VISIBLE;
layer = 1;
}


///Background image to see effect in real-time
PANEL* panelik =
{
bmap = "panel2.png";
layer = 0;
pos_x =0; pos_y = 0;
flags = VISIBLE;
}
///Overlay image, hidden, no VISIBLE set
PANEL* overlay =
{
bmap = overlayb;
pos_x = 800; pos_y = 400;
layer = 2;

}


function main() // start of program
{
video_mode = 8;
mouse_mode = 4;
wait(1);
level_load("");
sky_color.red = 1;
sky_color.green = 1;
sky_color.blue = 0;
video_window(NULL,NULL,0,"WaveRunner");



while(1)
{
//Attach overlay to mousy mousy
overlay.pos_x = mouse_cursor.x - overlay.size_x / 2;
overlay.pos_y = mouse_cursor.y- overlay.size_y / 2;


///Check if overlapping
if (((overlay.pos_x >= aircraft_pan.pos_x && overlay.pos_x <= aircraft_pan.pos_x + aircraft_pan.size_x) || (overlay.pos_x < aircraft_pan.pos_x && overlay.pos_x + overlay.size_x > aircraft_pan.pos_x)) && ((overlay.pos_y >= aircraft_pan.pos_y && overlay.pos_y <= aircraft_pan.pos_y + aircraft_pan.size_y) || (overlay.pos_y < aircraft_pan.pos_y && overlay.pos_y + overlay.size_y > aircraft_pan.pos_y)) )
{
/////
/////On first entry, create dublicate.
////If You use no ALPHA CHANNEL on image below, there is no need for dublicate.
////We need in order to restore correct alpha of image, when we move overlay away.
if (entered_panel == 0)
{
entered_panel = 1;
tempr = bmap_createblack(aircraft_pan.size_x, aircraft_pan.size_y,32); ///32 may be 24 if You use no alpha on source image
bmap_blit(tempr,original,NULL,NULL);
}
//Blit temp image every frame to restore correct alphas for original
bmap_blit(original, tempr, NULL, NULL);



var overlapwidth;
var overlapheight;


//Here we get all needed sizes and make sure they are OK
var squaresizex = overlay.pos_x - aircraft_pan.pos_x;
if (squaresizex >= 0)
{
overlapwidth = aircraft_pan.size_x - squaresizex - 1;
if (overlapwidth > overlay.size_x - 1)
overlapwidth = overlay.size_x - 1;
}
else
{
overlapwidth = overlay.size_x - abs(squaresizex);
if (overlapwidth > aircraft_pan.size_x - 1)
{
overlapwidth = aircraft_pan.size_x - 1;
}

}
var squaresizey = overlay.pos_y - aircraft_pan.pos_y;
if (squaresizey >= 0)
{
overlapheight = aircraft_pan.size_y - squaresizey - 1;
if (overlapheight > overlay.size_y - 1)
overlapheight = overlay.size_y - 1;
}
else
{
overlapheight = overlay.size_y - abs(squaresizey);
if (overlapheight > aircraft_pan.size_y - 1)
{
overlapheight = aircraft_pan.size_y - 1;
}

}
var squaresizex2 = aircraft_pan.pos_x - overlay.pos_x;
var squaresizey2 = aircraft_pan.pos_y - overlay.pos_y;
var format;
var pixel;
var format2;
var pixel2;


///ooooooket, let lock original and overlay
format = bmap_lock(original, 0);
format2 = bmap_lock(overlayb, 0);

if (format == 0 || format2 == 0)
error("wrong format");

var width = 0;
var height = 0;
//Process their pixel now
for (width = 0; width < overlapwidth; width++)
{
for(height = 0; height < overlapheight; height++)
{
//Here we process correct overlapping reictangle
if(squaresizex >= 0 && squaresizey >= 0)
pixel = pixel_for_bmap(overlayb,0 + width,0+height);
if(squaresizex < 0 && squaresizey >= 0)
pixel = pixel_for_bmap(overlayb,squaresizex2 + width,0+height);
if(squaresizex >= 0 && squaresizey < 0)
pixel = pixel_for_bmap(overlayb,0+ width,squaresizey2 + height);
if(squaresizex < 0 && squaresizey < 0)
pixel = pixel_for_bmap(overlayb,squaresizex2 + width,squaresizey2 + height);

COLOR tempcolor;
COLOR tempcolor2;
var putx;
var puty;
//Convert received pixel to color format
//Ok, this pixel holds transparency data
pixel_to_vec(tempcolor, NULL, format2,pixel);


var temppixel;
COLOR tempcolor2;
//Now, we take pixel from original image.
//And put our transparency data there...
if(squaresizex >= 0 && squaresizey >= 0)
{
pixel2 = pixel_for_bmap(original, squaresizex + width,squaresizey +height);
putx = squaresizex + width;
puty = squaresizey +height;
}
if(squaresizex < 0 && squaresizey >= 0)
{
pixel2 = pixel_for_bmap(original, 0 + width,squaresizey + height);
putx = 0 + width;
puty = squaresizey + height;
}
if(squaresizex >= 0 && squaresizey < 0)
{
pixel2 = pixel_for_bmap(original, squaresizex + width,0+height);
putx = squaresizex + width;
puty = 0+height;

}
if(squaresizex < 0 && squaresizey < 0)
{
pixel2 = pixel_for_bmap(original, 0 + width,0+height);
putx = 0 + width;
puty = 0 +height;

}
var alphaval;
pixel_to_vec(tempcolor2, alphaval, format,pixel2);
var newalpha = (tempcolor.blue /255) * 100; //Here we calculate new alpha from temcolor we received before
if(alphaval != 0)
{
if (alphaval < newalpha) ////This part very important. You may comment it and see why.
newalpha = alphaval;
var putpixel = pixel_for_vec(tempcolor2,newalpha,format);
pixel_to_bmap(original,putx,puty,putpixel);
}







}
}
//Unlock when all done
bmap_unlock(original);
bmap_unlock(overlayb);
}
else
{
if (entered_panel == 1)
{
//Release memory when overlay goes away...
entered_panel = 0;
bmap_blit(original, tempr, NULL, NULL);
bmap_purge(tempr);

}

}







wait(1);
}
}





Regards,
Konstantin.
Posted By: Quad

Re: Panel alpha blitting - 12/27/08 00:01

it drops fps from 512 to 100 but

it's cool
© 2024 lite-C Forums