# HG changeset patch # User sheepluva # Date 1390135271 -3600 # Node ID 59a6d65fcb600fa50986dbf92f8abc435ff718ed # Parent 56d2f2d5aad861ba8f750c6c0790b5be230c74a6 (experimental) make the mysterious borders around land/hats/etc that appear on zoom vanish note: not applied to everything yet note: I'll probably merge the two functions that do the same thing (one for 1darray, one for 2darray representation of pixels) into a single function diff -r 56d2f2d5aad8 -r 59a6d65fcb60 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Sun Jan 19 00:18:28 2014 +0400 +++ b/hedgewars/uLand.pas Sun Jan 19 13:41:11 2014 +0100 @@ -60,6 +60,61 @@ end; end; +{ this will make invisible pixels that have a visible neighbor have the + same color as their visible neighbor, so that bilinear filtering won't + display a "wrongly" colored border when zoomed in } +procedure PrettifyLandAlpha(); +var + x, y, lastx, lasty: Longword; + lpi, cpi, bpi: boolean; // was last/current/bottom neighbor pixel invisible? +begin + lasty:= LAND_HEIGHT - 1; + lastx:= LAND_WIDTH - 1; + if (cReducedQuality and rqBlurryLand) <> 0 then + begin + lasty:= lasty div 2; + lastx:= lastx div 2; + end; + for y:= 0 to lasty do + for x:= 0 to lastx do + begin + // use first pixel in row as starting point + //LandPixels[y, x]:= (LandPixels[y, x] and (BMask or GMask or AMask)); + if x = 0 then + lpi:= ((LandPixels[y, x] and AMask) = 0) + else + begin + cpi:= ((LandPixels[y, x] and AMask) = 0); + if lpi <> cpi then + begin + // invisible pixels get colors from visible neighbors + if cpi then + begin + LandPixels[y, x]:= LandPixels[y, x-1] and not AMask; + // as this pixel is invisible and already colored correctly now, no point in further comparing it + lpi:= cpi; + continue; + end + else + LandPixels[y, x-1]:= LandPixels[y, x] and not AMask; + lpi:= cpi; + end; + end; + // also check bottom neighbor, lpi is now current pixel info + if y < lasty - 1 then + begin + bpi:= ((LandPixels[y+1, x] and AMask) = 0); + if cpi <> bpi then + begin + if cpi then + LandPixels[y, x]:= LandPixels[y+1, x] and not AMask + else + LandPixels[y+1, x]:= LandPixels[y, x] and not AMask; + end; + end + end; +end; + procedure DrawBorderFromImage(Surface: PSDL_Surface); var tmpsurf: PSDL_Surface; @@ -811,6 +866,8 @@ LandPixels[y,x]:= w or (LandPixels[y div 2, x div 2] and AMask) end end; + +PrettifyLandAlpha(); end; procedure GenPreview(out Preview: TPreview); diff -r 56d2f2d5aad8 -r 59a6d65fcb60 hedgewars/uTextures.pas --- a/hedgewars/uTextures.pas Sun Jan 19 00:18:28 2014 +0400 +++ b/hedgewars/uTextures.pas Sun Jan 19 13:41:11 2014 +0100 @@ -25,6 +25,7 @@ function NewTexture(width, height: Longword; buf: Pointer): PTexture; procedure Surface2GrayScale(surf: PSDL_Surface); function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture; +procedure PrettifySurfaceAlpha(surf: PSDL_Surface; p: PLongwordArray); procedure FreeTexture(tex: PTexture); procedure FreeAndNilTexture(var tex: PTexture); @@ -121,6 +122,53 @@ end; end; +{ this will make invisible pixels that have a visible neighbor have the + same color as their visible neighbor, so that bilinear filtering won't + display a "wrongly" colored border when zoomed in } +procedure PrettifySurfaceAlpha(surf: PSDL_Surface; p: PLongwordArray); +var + i, lasti: Longword; + lpi, cpi, bpi: boolean; // was last/current/bottom neighbor pixel invisible? +begin + lasti:= surf^.w * surf^.h - 1; + for i:=0 to lasti do + begin + // use first pixel in row as starting point + //p^[i]:= p^[i] and (BMask or GMask); + if (i mod surf^.w) = 0 then + lpi:= ((p^[i] and AMask) = 0) + else + begin + cpi:= ((p^[i] and AMask) = 0); + if cpi <> lpi then + begin + // invisible pixels get colors from visible neighbors + if (p^[i] and AMask) = 0 then + begin + p^[i]:= p^[i-1] and not AMask; + // as this pixel is invisible and already colored correctly now, no point in further comparing it + lpi:= cpi; + continue; + end + else + p^[i-1]:= p^[i] and not AMask; + lpi:= cpi; + end; + end; + // also check bottom neighbor, lpi is now current pixel info + if i < lasti - surf^.w then + begin + bpi:= ((p^[i + surf^.w] and AMask) = 0); + if cpi <> bpi then + begin + if cpi then + p^[i]:= p^[i + surf^.w] and not AMask + else + p^[i + surf^.w]:= p^[i] and not AMask; + end; + end; + end; +end; function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture; var tw, th, x, y: Longword; @@ -148,7 +196,6 @@ exit end; - glGenTextures(1, @Surface2Tex^.id); glBindTexture(GL_TEXTURE_2D, Surface2Tex^.id); @@ -161,6 +208,8 @@ if GrayScale then Surface2GrayScale(Surf); +PrettifySurfaceAlpha(surf, fromP4); + if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then begin tw:= toPowerOf2(Surf^.w);