From 69def54f79cace3a1a90ae71f03910986ff74da7 Mon Sep 17 00:00:00 2001 From: b1indy Date: Sat, 8 Sep 2007 15:03:05 +0000 Subject: re-did the colorize stuff, now no need for GraphUtils git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@378 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UTexture.pas | 150 ++++++++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 38 deletions(-) (limited to 'Game/Code') 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); -- cgit v1.2.3