aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Game/Code/Classes/UTexture.pas150
1 files changed, 112 insertions, 38 deletions
diff --git a/Game/Code/Classes/UTexture.pas b/Game/Code/Classes/UTexture.pas
index ab21d44c..dc1f9fc2 100644
--- a/Game/Code/Classes/UTexture.pas
+++ b/Game/Code/Classes/UTexture.pas
@@ -11,7 +11,7 @@ unit UTexture;
// Arrow (for arrows, white is white, gray has color, black is transparent);
interface
-uses OpenGL12, Windows, Math, Classes, SysUtils, Graphics, JPEG, UThemes, PNGImage, GraphUtil, dialogs;
+uses OpenGL12, Windows, Math, Classes, SysUtils, Graphics, JPEG, UThemes, PNGImage;
procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
@@ -66,10 +66,10 @@ type
function LoadTexture(Identifier: string): TTexture; overload;
function CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture;
procedure UnloadTexture(Name: string; FromCache: boolean);
- procedure Colorize(var R,G,B : Byte; Color: Cardinal); // Real colorize instead of: "150 grey is now blue, k?"
end;
var
+ lasthue: double;
Texture: TTextureUnit;
TextureDatabase: TTextureDatabase;
@@ -165,6 +165,106 @@ begin
Result := T;
end;
+// expects: src, dst: pointers to r,g,b,a
+// hue: new hue within range [0.0-6.0)
+procedure ColorizeCopy(Src, Dst: PByteArray; hue: Double); overload;
+var
+ i,j,k: Cardinal;
+ clr, hls: array[0..2] of Double;
+ delta, f, p, q, t: Double;
+begin
+ hls[0]:=hue;
+
+ clr[0]:=src[0]/255; clr[1]:=src[1]/255; clr[2]:=src[2]/255;
+ //calculate luminance and saturation from rgb
+ hls[1]:=maxvalue(clr); //l:=...
+ delta:=hls[1]-minvalue(clr);
+ if hls[1]=0.0 then hls[2]:=0.0 else hls[2]:=delta/hls[1]; //v:=...
+ // calc new rgb from our hls (h from color, l ans s from pixel)
+// if (hls[1]<>0.0) and (hls[2]<>0.0) then // only if colorizing makes sense
+ begin
+ k:=trunc(hls[0]);
+ f:=hls[0]-k;
+ p:=hls[1]*(1.0-hls[2]);
+ q:=hls[1]*(1.0-(hls[2]*f));
+ t:=hls[1]*(1.0-(hls[2]*(1.0-f)));
+ case k of
+ 0: begin clr[0]:=hls[1]; clr[1]:=t; clr[2]:=p; end;
+ 1: begin clr[0]:=q; clr[1]:=hls[1]; clr[2]:=p; end;
+ 2: begin clr[0]:=p; clr[1]:=hls[1]; clr[2]:=t; end;
+ 3: begin clr[0]:=p; clr[1]:=q; clr[2]:=hls[1]; end;
+ 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hls[1]; end;
+ 5: begin clr[0]:=hls[1]; clr[1]:=p; clr[2]:=q; end;
+ end;
+ // and store new rgb back into the image
+ dst[0]:=floor(255*clr[0]);
+ dst[1]:=floor(255*clr[1]);
+ dst[2]:=floor(255*clr[2]);
+ dst[3]:=src[3];
+ end;
+end;
+
+// expects: src: $rrggbb
+// dst: pointer to r,g,b,a
+// hue: new hue within range [0.0-6.0)
+procedure ColorizeCopy(Src: Cardinal; Dst: PByteArray; hue: Double); overload;
+var
+ i,j,k: Cardinal;
+ clr, hls: array[0..2] of Double;
+ delta, f, p, q, t: Double;
+begin
+ hls[0]:=hue;
+
+ clr[0]:=((src shr 16) and $ff)/255;
+ clr[1]:=((src shr 8) and $ff)/255;
+ clr[2]:=(src and $ff)/255;
+ //calculate luminance and saturation from rgb
+ hls[1]:=maxvalue(clr); //l:=...
+ delta:=hls[1]-minvalue(clr);
+ if hls[1]=0.0 then hls[2]:=0.0 else hls[2]:=delta/hls[1]; //v:=...
+ // calc new rgb from our hls (h from color, l ans s from pixel)
+// if (hls[1]<>0.0) and (hls[2]<>0.0) then // only if colorizing makes sense
+ begin
+ k:=trunc(hls[0]);
+ f:=hls[0]-k;
+ p:=hls[1]*(1.0-hls[2]);
+ q:=hls[1]*(1.0-(hls[2]*f));
+ t:=hls[1]*(1.0-(hls[2]*(1.0-f)));
+ case k of
+ 0: begin clr[0]:=hls[1]; clr[1]:=t; clr[2]:=p; end;
+ 1: begin clr[0]:=q; clr[1]:=hls[1]; clr[2]:=p; end;
+ 2: begin clr[0]:=p; clr[1]:=hls[1]; clr[2]:=t; end;
+ 3: begin clr[0]:=p; clr[1]:=q; clr[2]:=hls[1]; end;
+ 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hls[1]; end;
+ 5: begin clr[0]:=hls[1]; clr[1]:=p; clr[2]:=q; end;
+ end;
+ // and store new rgb back into the image
+ dst[0]:=floor(255*clr[0]);
+ dst[1]:=floor(255*clr[1]);
+ dst[2]:=floor(255*clr[2]);
+ dst[3]:=255;
+ end;
+end;
+//returns hue within range [0.0-6.0)
+function col2h(Color:Cardinal):double;
+var
+ clr,hls: array[0..2] of double;
+ delta: double;
+begin
+ clr[0]:=((Color and $ff0000) shr 16)/255;
+ clr[1]:=((Color and $ff00) shr 8)/255;
+ clr[2]:=(Color and $ff)/255;
+ hls[1]:=maxvalue(clr);
+ delta:=hls[1]-minvalue(clr);
+ if clr[0]=hls[1] then hls[0]:=(clr[1]-clr[2])/delta
+ else if clr[1]=hls[1] then hls[0]:=2.0+(clr[2]-clr[0])/delta
+ else if clr[2]=hls[1] then hls[0]:=4.0+(clr[0]-clr[1])/delta;
+ if hls[0]<0.0 then hls[0]:=hls[0]+6.0;
+ if hls[0]=6.0 then hls[0]:=0.0;
+ col2h:=hls[0];
+end;
+
+
function TTextureUnit.LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture;
var
Res: TResourceStream;
@@ -187,6 +287,7 @@ var
myAlpha: Real;
myRGBABitmap: array of byte;
RGBPtr: PByte;
+ myHue: Double;
begin
Log.BenchmarkStart(4);
Mipmapping := true;
@@ -426,29 +527,19 @@ begin
TextureB.Width := TexNewW;
TextureB.Height := TexNewH;
+ myHue:=col2h(Col);
// copy and process pixeldata
for Position := 0 to TexOrigH-1 do begin
for Position2 := 0 to TexOrigW-1 do begin
Pix := TextureB.Canvas.Pixels[Position2, Position];
- if (Format = 'PNG') and (length(MyRGBABitmap) <> 0) then begin
- myAlpha:=TextureAlpha[Position*TexOrigW+Position2];
- TextureD32[Position*TexNewW + Position2+1, 1] := MyRGBABitmap[(Position*TexOrigW+Position2)*4+2]; // R
- TextureD32[Position*TexNewW + Position2+1, 2] := MyRGBABitmap[(Position*TexOrigW+Position2)*4+1]; // G
- TextureD32[Position*TexNewW + Position2+1, 3] := MyRGBABitmap[(Position*TexOrigW+Position2)*4]; // B
- TextureD32[Position*TexNewW+Position2+1,4] := MyRGBABitmap[(Position*TexOrigW+Position2)*4+3]; // Alpha
- end else begin
- TextureD32[Position*TexNewW + Position2+1, 1] := (Pix and $ff);
- TextureD32[Position*TexNewW + Position2+1, 2] := ((Pix shr 8) and $ff);
- TextureD32[Position*TexNewW + Position2+1, 3] := ((Pix shr 16) and $ff);
- TextureD32[Position*TexNewW + Position2+1, 4] := 255;
- end;
- end;
- end;
-
- //now the colorize stuff
- for Position := 0 to TexOrigH-1 do begin
- for Position2 := 0 to TexOrigW-1 do begin
- colorize(TextureD32[Position*TexNewW + Position2+1, 1],TextureD32[Position*TexNewW + Position2+1, 2],TextureD32[Position*TexNewW + Position2+1, 3], Col); //pinkie :P
+ if (Format = 'PNG') and (length(MyRGBABitmap) <> 0) then
+ ColorizeCopy(@MyRGBABitmap[(Position*TexOrigW+Position2)*4],
+ @TextureD32[Position*TexNewW + Position2+1, 1],
+ myHue)
+ else
+ ColorizeCopy(Pix,
+ @TextureD32[Position*TexNewW + Position2+1, 1],
+ myHue);
end;
end;
@@ -803,23 +894,6 @@ begin
end;
-
-// Funkyness of colorizing is done in this small box, remember to give credits when you copy from us
-Procedure TTextureUnit.Colorize(var R,G,B : Byte; Color : Cardinal);
-var
- TexHue, TexLum, TexSat, ClrHue, ClrLum, ClrSat : Word;
- ColorizedColors: Cardinal;
-begin //red //green //blue
- Color:=((Color and $ff) shl 16) or (Color and $ff00) or ((Color and $ff0000) shr 16);
- ColorRGBToHLS(Color, ClrHue, ClrLum, ClrSat);
- ColorRGBToHLS((((b shl 8) or g) shl 8 or r),TexHue, TexLum, TexSat);
- ColorizedColors := ColorHLSToRGB(ClrHue, TexLum, TexSat);
- R := ColorizedColors and $FF;
- G := (ColorizedColors and $FF00) shr 8;
- B := (ColorizedColors and $FF0000) shr 16;
-end;
-//eoa COLORIZE
-
function TTextureUnit.LoadTexture(Identifier: string): TTexture;
begin
Result := LoadTexture(false, pchar(Identifier), 'JPG', 'Plain', 0);