diff -r c00db97a668f -r 4ac87acbaed9 hedgewars/uTextures.pas --- a/hedgewars/uTextures.pas Tue Jan 21 22:44:37 2014 +0100 +++ b/hedgewars/uTextures.pas Tue Jan 21 22:53:15 2014 +0100 @@ -25,6 +25,8 @@ 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; pixels: PLongwordArray); +procedure PrettifyAlpha2D(pixels: TLandArray; height, width: LongWord); procedure FreeTexture(tex: PTexture); procedure FreeAndNilTexture(var tex: PTexture); @@ -121,6 +123,88 @@ 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 PrettifyAlpha(row1, row2: PLongwordArray; firsti, lasti, ioffset: LongWord); +var + i: Longword; + lpi, cpi, bpi: boolean; // was last/current/bottom neighbor pixel invisible? +begin + // suppress incorrect warning + lpi:= true; + for i:=firsti to lasti do + begin + // use first pixel in row1 as starting point + if i = firsti then + cpi:= ((row1^[i] and AMask) = 0) + else + begin + cpi:= ((row1^[i] and AMask) = 0); + if cpi <> lpi then + begin + // invisible pixels get colors from visible neighbors + if cpi then + begin + row1^[i]:= row1^[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 + row1^[i-1]:= row1^[i] and not AMask; + end; + end; + lpi:= cpi; + // also check bottom neighbor + if row2 <> nil then + begin + bpi:= ((row2^[i+ioffset] and AMask) = 0); + if cpi <> bpi then + begin + if cpi then + row1^[i]:= row2^[i+ioffset] and not AMask + else + row2^[i+ioffset]:= row1^[i] and not AMask; + end; + end; + end; +end; + +procedure PrettifySurfaceAlpha(surf: PSDL_Surface; pixels: PLongwordArray); +var + // current row index, second last row index of array, width and first/last i of row + r, slr, w, si, li: LongWord; +begin + w:= surf^.w; + slr:= surf^.h - 2; + si:= 0; + li:= w - 1; + for r:= 0 to slr do + begin + PrettifyAlpha(pixels, pixels, si, li, w); + // move indices to next row + si:= si + w; + li:= li + w; + end; + // don't forget last row + PrettifyAlpha(pixels, nil, si, li, w); +end; + +procedure PrettifyAlpha2D(pixels: TLandArray; height, width: LongWord); +var + // current y; last x, second last y of array; + y, lx, sly: LongWord; +begin + sly:= height - 2; + lx:= width - 1; + for y:= 0 to sly do + begin + PrettifyAlpha(PLongWordArray(pixels[y]), PLongWordArray(pixels[y+1]), 0, lx, 0); + end; + // don't forget last row + PrettifyAlpha(PLongWordArray(pixels[sly+1]), nil, 0, lx, 0); +end; function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture; var tw, th, x, y: Longword; @@ -148,7 +232,6 @@ exit end; - glGenTextures(1, @Surface2Tex^.id); glBindTexture(GL_TEXTURE_2D, Surface2Tex^.id); @@ -161,6 +244,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);