hedgewars/uTextures.pas
changeset 10040 4ac87acbaed9
parent 10017 de822cd3df3a
parent 10021 7f36194af01c
child 10078 8572d1f8b2f0
equal deleted inserted replaced
10019:c00db97a668f 10040:4ac87acbaed9
    23 uses SDLh, uTypes;
    23 uses SDLh, uTypes;
    24 
    24 
    25 function  NewTexture(width, height: Longword; buf: Pointer): PTexture;
    25 function  NewTexture(width, height: Longword; buf: Pointer): PTexture;
    26 procedure Surface2GrayScale(surf: PSDL_Surface);
    26 procedure Surface2GrayScale(surf: PSDL_Surface);
    27 function  Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
    27 function  Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
       
    28 procedure PrettifySurfaceAlpha(surf: PSDL_Surface; pixels: PLongwordArray);
       
    29 procedure PrettifyAlpha2D(pixels: TLandArray; height, width: LongWord);
    28 procedure FreeTexture(tex: PTexture);
    30 procedure FreeTexture(tex: PTexture);
    29 procedure FreeAndNilTexture(var tex: PTexture);
    31 procedure FreeAndNilTexture(var tex: PTexture);
    30 
    32 
    31 procedure initModule;
    33 procedure initModule;
    32 procedure freeModule;
    34 procedure freeModule;
   119         end;
   121         end;
   120     fromP4:= @(fromP4^[Surf^.pitch div 4])
   122     fromP4:= @(fromP4^[Surf^.pitch div 4])
   121     end;
   123     end;
   122 end;
   124 end;
   123 
   125 
       
   126 { this will make invisible pixels that have a visible neighbor have the
       
   127   same color as their visible neighbor, so that bilinear filtering won't
       
   128   display a "wrongly" colored border when zoomed in }
       
   129 procedure PrettifyAlpha(row1, row2: PLongwordArray; firsti, lasti, ioffset: LongWord);
       
   130 var
       
   131     i: Longword;
       
   132     lpi, cpi, bpi: boolean; // was last/current/bottom neighbor pixel invisible?
       
   133 begin
       
   134     // suppress incorrect warning
       
   135     lpi:= true;
       
   136     for i:=firsti to lasti do
       
   137         begin
       
   138         // use first pixel in row1 as starting point
       
   139         if i = firsti then
       
   140             cpi:= ((row1^[i] and AMask) = 0)
       
   141         else
       
   142             begin
       
   143             cpi:= ((row1^[i] and AMask) = 0);
       
   144             if cpi <> lpi then
       
   145                 begin
       
   146                 // invisible pixels get colors from visible neighbors
       
   147                 if cpi then
       
   148                     begin
       
   149                     row1^[i]:= row1^[i-1] and not AMask;
       
   150                     // as this pixel is invisible and already colored correctly now, no point in further comparing it
       
   151                     lpi:= cpi;
       
   152                     continue;
       
   153                     end
       
   154                 else
       
   155                     row1^[i-1]:= row1^[i] and not AMask;
       
   156                 end;
       
   157             end;
       
   158         lpi:= cpi;
       
   159         // also check bottom neighbor
       
   160         if row2 <> nil then
       
   161             begin
       
   162             bpi:= ((row2^[i+ioffset] and AMask) = 0);
       
   163             if cpi <> bpi then
       
   164                 begin
       
   165                 if cpi then
       
   166                     row1^[i]:= row2^[i+ioffset] and not AMask
       
   167                 else
       
   168                     row2^[i+ioffset]:= row1^[i] and not AMask;
       
   169                 end;
       
   170             end;
       
   171         end;
       
   172 end;
       
   173 
       
   174 procedure PrettifySurfaceAlpha(surf: PSDL_Surface; pixels: PLongwordArray);
       
   175 var
       
   176     // current row index, second last row index of array, width and first/last i of row
       
   177     r, slr, w, si, li: LongWord;
       
   178 begin
       
   179     w:= surf^.w;
       
   180     slr:= surf^.h - 2;
       
   181     si:= 0;
       
   182     li:= w - 1;
       
   183     for r:= 0 to slr do
       
   184         begin
       
   185         PrettifyAlpha(pixels, pixels, si, li, w);
       
   186         // move indices to next row
       
   187         si:= si + w;
       
   188         li:= li + w;
       
   189         end;
       
   190     // don't forget last row
       
   191     PrettifyAlpha(pixels, nil, si, li, w);
       
   192 end;
       
   193 
       
   194 procedure PrettifyAlpha2D(pixels: TLandArray; height, width: LongWord);
       
   195 var
       
   196     // current y; last x, second last y of array;
       
   197     y, lx, sly: LongWord;
       
   198 begin
       
   199     sly:= height - 2;
       
   200     lx:= width - 1;
       
   201     for y:= 0 to sly do
       
   202         begin
       
   203         PrettifyAlpha(PLongWordArray(pixels[y]), PLongWordArray(pixels[y+1]), 0, lx, 0);
       
   204         end;
       
   205     // don't forget last row
       
   206     PrettifyAlpha(PLongWordArray(pixels[sly+1]), nil, 0, lx, 0);
       
   207 end;
   124 
   208 
   125 function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
   209 function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
   126 var tw, th, x, y: Longword;
   210 var tw, th, x, y: Longword;
   127     tmpp: pointer;
   211     tmpp: pointer;
   128     fromP4, toP4: PLongWordArray;
   212     fromP4, toP4: PLongWordArray;
   146     TryDo(false, 'Surface2Tex failed, expecting 32 bit surface', true);
   230     TryDo(false, 'Surface2Tex failed, expecting 32 bit surface', true);
   147     Surface2Tex^.id:= 0;
   231     Surface2Tex^.id:= 0;
   148     exit
   232     exit
   149     end;
   233     end;
   150 
   234 
   151 
       
   152 glGenTextures(1, @Surface2Tex^.id);
   235 glGenTextures(1, @Surface2Tex^.id);
   153 
   236 
   154 glBindTexture(GL_TEXTURE_2D, Surface2Tex^.id);
   237 glBindTexture(GL_TEXTURE_2D, Surface2Tex^.id);
   155 
   238 
   156 if SDL_MustLock(surf) then
   239 if SDL_MustLock(surf) then
   158 
   241 
   159 fromP4:= Surf^.pixels;
   242 fromP4:= Surf^.pixels;
   160 
   243 
   161 if GrayScale then
   244 if GrayScale then
   162     Surface2GrayScale(Surf);
   245     Surface2GrayScale(Surf);
       
   246 
       
   247 PrettifySurfaceAlpha(surf, fromP4);
   163 
   248 
   164 if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then
   249 if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then
   165     begin
   250     begin
   166     tw:= toPowerOf2(Surf^.w);
   251     tw:= toPowerOf2(Surf^.w);
   167     th:= toPowerOf2(Surf^.h);
   252     th:= toPowerOf2(Surf^.h);