PDA

View Full Version : PixelTest does not work when using png's



arthurprs
07-10-2007, 03:50 PM
:?, i tried load the png from imaging and from SDL_Image, but the function don't work, surface don't have a colorkey color.. it uses RGBA to make the transparency

any ideias to fix it?

lordzero
07-10-2007, 07:39 PM
maybe i can found the solution... i will post here if i found

arthurprs
07-10-2007, 08:42 PM
function SDL_PixelTest( SrcSurface1 : PSDL_Surface; SrcRect1 : PSDL_Rect; SrcSurface2 :
PSDL_Surface; SrcRect2 : PSDL_Rect; Left1, Top1, Left2, Top2 : integer ) : boolean;
var
Src_Rect1, Src_Rect2 : TSDL_Rect;
right1, bottom1 : integer;
right2, bottom2 : integer;
Scan1Start, Scan2Start, ScanWidth, ScanHeight : cardinal;
Mod1, Mod2 : cardinal;
Addr1, Addr2 : cardinal;
BPP : cardinal;
Pitch1, Pitch2 : cardinal;
TransparentColor1, TransparentColor2 : cardinal;
tx, ty : cardinal;
StartTick : cardinal;
Color1, Color2 : cardinal;
begin
Result := false;
if SrcRect1 = nil then
begin
with Src_Rect1 do
begin
x := 0;
y := 0;
w := SrcSurface1.w;
h := SrcSurface1.h;
end;
end
else
Src_Rect1 := SrcRect1^;
if SrcRect2 = nil then
begin
with Src_Rect2 do
begin
x := 0;
y := 0;
w := SrcSurface2.w;
h := SrcSurface2.h;
end;
end
else
Src_Rect2 := SrcRect2^;
with Src_Rect1 do
begin
Right1 := Left1 + w;
Bottom1 := Top1 + h;
end;
with Src_Rect2 do
begin
Right2 := Left2 + w;
Bottom2 := Top2 + h;
end;
if ( Left1 >= Right2 ) or ( Right1 <Left2>= Bottom2 ) or ( Bottom1 <=
Top2 ) then
exit;
if Left1 <Left2> w then
ScanWidth := w;
end
else
begin
// 1. right, 2. left
Scan1Start := Src_Rect1.x;
Scan2Start := Src_Rect2.x + Left1 - Left2;
ScanWidth := Right2 - Left1;
with Src_Rect1 do
if ScanWidth > w then
ScanWidth := w;
end;
with SrcSurface1^ do
begin
Pitch1 := Pitch;
Addr1 := cardinal( Pixels );
inc( Addr1, Pitch1 * UInt32( Src_Rect1.y ) );
with format^ do
begin
BPP := BytesPerPixel;
TransparentColor1 := colorkey;
end;
end;
with SrcSurface2^ do
begin
TransparentColor2 := format.colorkey;
Pitch2 := Pitch;
Addr2 := cardinal( Pixels );
inc( Addr2, Pitch2 * UInt32( Src_Rect2.y ) );
end;
Mod1 := Pitch1 - ( ScanWidth * BPP );
Mod2 := Pitch2 - ( ScanWidth * BPP );
inc( Addr1, BPP * Scan1Start );
inc( Addr2, BPP * Scan2Start );
if Top1 <Top2> Src_Rect2.h then
ScanHeight := Src_Rect2.h;
inc( Addr1, Pitch1 * UInt32( Top2 - Top1 ) );
end
else
begin
// 1. down, 2. up
ScanHeight := Bottom2 - Top1;
if ScanHeight > Src_Rect1.h then
ScanHeight := Src_Rect1.h;
inc( Addr2, Pitch2 * UInt32( Top1 - Top2 ) );
end;
case BPP of
1 :
for ty := 1 to ScanHeight do
begin
for tx := 1 to ScanWidth do
begin
if ( PByte( Addr1 )^ <> TransparentColor1 ) and ( PByte( Addr2 )^ <>
TransparentColor2 ) then
begin
Result := true;
exit;
end;
inc( Addr1 );
inc( Addr2 );
end;
inc( Addr1, Mod1 );
inc( Addr2, Mod2 );
end;
2 :
for ty := 1 to ScanHeight do
begin
for tx := 1 to ScanWidth do
begin
if ( PWord( Addr1 )^ <> TransparentColor1 ) and ( PWord( Addr2 )^ <>
TransparentColor2 ) then
begin
Result := true;
exit;
end;
inc( Addr1, 2 );
inc( Addr2, 2 );
end;
inc( Addr1, Mod1 );
inc( Addr2, Mod2 );
end;
3 :
for ty := 1 to ScanHeight do
begin
for tx := 1 to ScanWidth do
begin
Color1 := PLongWord( Addr1 )^ and $00FFFFFF;
Color2 := PLongWord( Addr2 )^ and $00FFFFFF;
if ( Color1 <> TransparentColor1 ) and ( Color2 <> TransparentColor2 )
then
begin
Result := true;
exit;
end;
inc( Addr1, 3 );
inc( Addr2, 3 );
end;
inc( Addr1, Mod1 );
inc( Addr2, Mod2 );
end;
4 :
for ty := 1 to ScanHeight do
begin
for tx := 1 to ScanWidth do
begin
if ( PLongWord( Addr1 )^ <> TransparentColor1 ) and ( PLongWord( Addr2 )^ <>
TransparentColor2 ) then
begin
Result := true;
exit;
end;
inc( Addr1, 4 );
inc( Addr2, 4 );
end;
inc( Addr1, Mod1 );
inc( Addr2, Mod2 );
end;
end;
end;

at

if &#40; PLongWord&#40; Addr1 &#41;^ <> TransparentColor1 &#41; and &#40; PLongWord&#40; Addr2 &#41;^ <>
TransparentColor2 &#41; then

if we can test Pixel RGBA.A = 255 instead of transparentcolor (colorkey)
i think it will work

jasonf
08-10-2007, 09:07 AM
It might be better to test if the RGBA.A > some Alpha Threshold, which could be set using the transparent colour, or a new property could be created.

If you just check for Alpha=255 then you'll only ever be able to collide with pixels with less than 100% transparency, but when you consider that a lot of the time, transparency is used for Anti-Aliasing, you'll end up with a lot of false collisions where it will look like things aren't really touching.
But if you set the Alpha Threshold to 128, then you'll collide with pixels which are less than 50% transparent but other pixels which are more transparent would not be used for collision, so anti aliased images would look like they're colliding properly.

User137
08-10-2007, 01:15 PM
...
if ( Left1 >= Right2 ) or ( Right1 <Left2>= Bottom2 ) or ( Bottom1
...
if Top1 <Top2> Src_Rect2.h then
...


This forum still manipulates sent code i see...
if x <y> z then
This structure would not work at all. Boolean > z?

arthurprs
09-10-2007, 01:50 AM
It might be better to test if the RGBA.A > some Alpha Threshold, which could be set using the transparent colour, or a new property could be created.

If you just check for Alpha=255 then you'll only ever be able to collide with pixels with less than 100% transparency, but when you consider that a lot of the time, transparency is used for Anti-Aliasing, you'll end up with a lot of false collisions where it will look like things aren't really touching.
But if you set the Alpha Threshold to 128, then you'll collide with pixels which are less than 50% transparent but other pixels which are more transparent would not be used for collision, so anti aliased images would look like they're colliding properly.

Yes but how get RGBA.A from sdl surface?

arthurprs
10-10-2007, 09:17 PM
any help is apreciated :?

technomage
10-10-2007, 09:54 PM
you need to use the SDL_GetPixel utility function in SDLUtils.pas. then use the SDL_GetRGBA function with the result of the SDL_GeTPixel function to map that to R,G,B,A values.