+ TempWidth := aBitmap.Width;
+ TempHeight := aBitmap.Height;
+ RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
+ GetMem(pData, TempHeight * RowSize);
+ try
+ pTempData := pData;
+ for Row := 0 to TempHeight -1 do begin
+ pSource := aBitmap.Scanline[Row];
+ if (Assigned(pSource)) then begin
+ Move(pSource^, pTempData^, RowSize);
+ Inc(pTempData, RowSize);
+ end;
+ end;
+ SetData(pData, IntFormat, TempWidth, TempHeight);
+ result := true;
+ except
+ if Assigned(pData) then
+ FreeMem(pData);
+ raise;
+ end;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
+var
+ Row, Col, AlphaInterleave: Integer;
+ pSource, pDest: PByte;
+begin
+ result := false;
+
+ if Assigned(Data) then begin
+ if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
+ if Assigned(aBitmap) then begin
+ aBitmap.PixelFormat := pf8bit;
+ aBitmap.Palette := CreateGrayPalette;
+ aBitmap.Width := Width;
+ aBitmap.Height := Height;
+
+ case Format of
+ tfLuminance8Alpha8ub2:
+ AlphaInterleave := 1;
+ tfRGBA8ub4, tfBGRA8ub4:
+ AlphaInterleave := 3;
+ else
+ AlphaInterleave := 0;
+ end;
+
+ // Copy Data
+ pSource := Data;
+
+ for Row := 0 to Height -1 do begin
+ pDest := aBitmap.Scanline[Row];
+ if Assigned(pDest) then begin
+ for Col := 0 to Width -1 do begin
+ Inc(pSource, AlphaInterleave);
+ pDest^ := pSource^;
+ Inc(pDest);
+ Inc(pSource);
+ end;
+ end;
+ end;
+ result := true;
+ end;
+ end;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
+var
+ data: TglBitmapData;
+begin
+ data := TglBitmapData.Create;
+ try
+ data.AssignFromBitmap(aBitmap);
+ result := AddAlphaFromDataObj(data, aFunc, aArgs);
+ finally
+ data.Free;
+ end;
+end;
+{$ENDIF}
+
+{$IFDEF GLB_LAZARUS}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
+var
+ rid: TRawImageDescription;
+ FormatDesc: TFormatDescriptor;
+begin
+ if not Assigned(Data) then
+ raise EglBitmap.Create('no pixel data assigned. load data before save');
+
+ result := false;
+ if not Assigned(aImage) or (Format = tfEmpty) then
+ exit;
+ FormatDesc := TFormatDescriptor.Get(Format);
+ if FormatDesc.IsCompressed then
+ exit;
+
+ FillChar(rid{%H-}, SizeOf(rid), 0);
+ if FormatDesc.IsGrayscale then
+ rid.Format := ricfGray
+ else
+ rid.Format := ricfRGBA;
+
+ rid.Width := Width;
+ rid.Height := Height;
+ rid.Depth := FormatDesc.BitsPerPixel;
+ rid.BitOrder := riboBitsInOrder;
+ rid.ByteOrder := riboLSBFirst;
+ rid.LineOrder := riloTopToBottom;
+ rid.LineEnd := rileTight;
+ rid.BitsPerPixel := FormatDesc.BitsPerPixel;
+ rid.RedPrec := CountSetBits(FormatDesc.Range.r);
+ rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
+ rid.BluePrec := CountSetBits(FormatDesc.Range.b);
+ rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
+ rid.RedShift := FormatDesc.Shift.r;
+ rid.GreenShift := FormatDesc.Shift.g;
+ rid.BlueShift := FormatDesc.Shift.b;
+ rid.AlphaShift := FormatDesc.Shift.a;
+
+ rid.MaskBitsPerPixel := 0;
+ rid.PaletteColorCount := 0;
+
+ aImage.DataDescription := rid;
+ aImage.CreateData;
+
+ if not Assigned(aImage.PixelData) then
+ raise EglBitmap.Create('error while creating LazIntfImage');
+ Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
+
+ result := true;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
+var
+ f: TglBitmapFormat;
+ FormatDesc: TFormatDescriptor;
+ ImageData: PByte;
+ ImageSize: Integer;
+ CanCopy: Boolean;
+ Mask: TglBitmapRec4ul;
+
+ procedure CopyConvert;
+ var
+ bfFormat: TbmpBitfieldFormat;
+ pSourceLine, pDestLine: PByte;
+ pSourceMD, pDestMD: Pointer;
+ Shift, Prec: TglBitmapRec4ub;
+ x, y: Integer;
+ pixel: TglBitmapPixelData;
+ begin
+ bfFormat := TbmpBitfieldFormat.Create;
+ with aImage.DataDescription do begin
+ Prec.r := RedPrec;
+ Prec.g := GreenPrec;
+ Prec.b := BluePrec;
+ Prec.a := AlphaPrec;
+ Shift.r := RedShift;
+ Shift.g := GreenShift;
+ Shift.b := BlueShift;
+ Shift.a := AlphaShift;
+ bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
+ end;
+ pSourceMD := bfFormat.CreateMappingData;
+ pDestMD := FormatDesc.CreateMappingData;
+ try
+ for y := 0 to aImage.Height-1 do begin
+ pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
+ pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
+ for x := 0 to aImage.Width-1 do begin
+ bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
+ FormatDesc.Map(pixel, pDestLine, pDestMD);
+ end;
+ end;
+ finally
+ FormatDesc.FreeMappingData(pDestMD);
+ bfFormat.FreeMappingData(pSourceMD);
+ bfFormat.Free;
+ end;
+ end;
+
+begin
+ result := false;
+ if not Assigned(aImage) then
+ exit;
+
+ with aImage.DataDescription do begin
+ Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
+ Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
+ Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
+ Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
+ end;
+ FormatDesc := TFormatDescriptor.GetFromMask(Mask);
+ f := FormatDesc.Format;
+ if (f = tfEmpty) then
+ exit;
+
+ CanCopy :=
+ (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
+ (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
+
+ ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
+ ImageData := GetMem(ImageSize);
+ try
+ if CanCopy then
+ Move(aImage.PixelData^, ImageData^, ImageSize)
+ else
+ CopyConvert;
+ SetData(ImageData, f, aImage.Width, aImage.Height);
+ except
+ if Assigned(ImageData) then
+ FreeMem(ImageData);
+ raise;
+ end;
+
+ result := true;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
+var
+ rid: TRawImageDescription;
+ FormatDesc: TFormatDescriptor;
+ Pixel: TglBitmapPixelData;
+ x, y: Integer;
+ srcMD: Pointer;
+ src, dst: PByte;
+begin
+ result := false;
+ if not Assigned(aImage) or (Format = tfEmpty) then
+ exit;
+ FormatDesc := TFormatDescriptor.Get(Format);
+ if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
+ exit;
+
+ FillChar(rid{%H-}, SizeOf(rid), 0);
+ rid.Format := ricfGray;
+ rid.Width := Width;
+ rid.Height := Height;
+ rid.Depth := CountSetBits(FormatDesc.Range.a);
+ rid.BitOrder := riboBitsInOrder;
+ rid.ByteOrder := riboLSBFirst;
+ rid.LineOrder := riloTopToBottom;
+ rid.LineEnd := rileTight;
+ rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
+ rid.RedPrec := CountSetBits(FormatDesc.Range.a);
+ rid.GreenPrec := 0;
+ rid.BluePrec := 0;
+ rid.AlphaPrec := 0;
+ rid.RedShift := 0;
+ rid.GreenShift := 0;
+ rid.BlueShift := 0;
+ rid.AlphaShift := 0;
+
+ rid.MaskBitsPerPixel := 0;
+ rid.PaletteColorCount := 0;
+
+ aImage.DataDescription := rid;
+ aImage.CreateData;
+
+ srcMD := FormatDesc.CreateMappingData;
+ try
+ FormatDesc.PreparePixel(Pixel);
+ src := Data;
+ dst := aImage.PixelData;
+ for y := 0 to Height-1 do
+ for x := 0 to Width-1 do begin
+ FormatDesc.Unmap(src, Pixel, srcMD);
+ case rid.BitsPerPixel of
+ 8: begin
+ dst^ := Pixel.Data.a;
+ inc(dst);
+ end;
+ 16: begin
+ PWord(dst)^ := Pixel.Data.a;
+ inc(dst, 2);
+ end;
+ 24: begin
+ PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
+ PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
+ PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
+ inc(dst, 3);
+ end;
+ 32: begin
+ PCardinal(dst)^ := Pixel.Data.a;
+ inc(dst, 4);
+ end;
+ else
+ raise EglBitmapUnsupportedFormat.Create(Format);
+ end;
+ end;
+ finally
+ FormatDesc.FreeMappingData(srcMD);
+ end;
+ result := true;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
+var
+ data: TglBitmapData;
+begin
+ data := TglBitmapData.Create;
+ try
+ data.AssignFromLazIntfImage(aImage);
+ result := AddAlphaFromDataObj(data, aFunc, aArgs);
+ finally
+ data.Free;
+ end;
+end;
+{$ENDIF}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
+ const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
+var
+ rs: TResourceStream;
+begin
+ PrepareResType(aResource, aResType);
+ rs := TResourceStream.Create(aInstance, aResource, aResType);
+ try
+ result := AddAlphaFromStream(rs, aFunc, aArgs);
+ finally
+ rs.Free;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
+ const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
+var
+ rs: TResourceStream;
+begin
+ rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
+ try
+ result := AddAlphaFromStream(rs, aFunc, aArgs);
+ finally
+ rs.Free;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
+begin
+ if TFormatDescriptor.Get(Format).IsCompressed then
+ raise EglBitmapUnsupportedFormat.Create(Format);
+ result := Convert(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
+var
+ FS: TFileStream;
+begin
+ FS := TFileStream.Create(aFileName, fmOpenRead);
+ try
+ result := AddAlphaFromStream(FS, aFunc, aArgs);
+ finally
+ FS.Free;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
+var
+ data: TglBitmapData;
+begin
+ data := TglBitmapData.Create(aStream);
+ try
+ result := AddAlphaFromDataObj(data, aFunc, aArgs);
+ finally
+ data.Free;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromDataObj(const aDataObj: TglBitmapData; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
+var
+ DestData, DestData2, SourceData: pByte;
+ TempHeight, TempWidth: Integer;
+ SourceFD, DestFD: TFormatDescriptor;
+ SourceMD, DestMD, DestMD2: Pointer;
+
+ FuncRec: TglBitmapFunctionRec;
+begin
+ result := false;
+
+ Assert(Assigned(Data));
+ Assert(Assigned(aDataObj));
+ Assert(Assigned(aDataObj.Data));
+
+ if ((aDataObj.Width = Width) and (aDataObj.Height = Height)) then begin
+ result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
+
+ SourceFD := TFormatDescriptor.Get(aDataObj.Format);
+ DestFD := TFormatDescriptor.Get(Format);
+
+ if not Assigned(aFunc) then begin
+ aFunc := glBitmapAlphaFunc;
+ FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
+ end else
+ FuncRec.Args := aArgs;
+
+ // Values
+ TempWidth := aDataObj.Width;
+ TempHeight := aDataObj.Height;
+ if (TempWidth <= 0) or (TempHeight <= 0) then
+ exit;
+
+ FuncRec.Sender := Self;
+ FuncRec.Size := Dimension;
+ FuncRec.Position.Fields := FuncRec.Size.Fields;
+
+ DestData := Data;
+ DestData2 := Data;
+ SourceData := aDataObj.Data;
+
+ // Mapping
+ SourceFD.PreparePixel(FuncRec.Source);
+ DestFD.PreparePixel (FuncRec.Dest);
+
+ SourceMD := SourceFD.CreateMappingData;
+ DestMD := DestFD.CreateMappingData;
+ DestMD2 := DestFD.CreateMappingData;
+ try
+ FuncRec.Position.Y := 0;
+ while FuncRec.Position.Y < TempHeight do begin
+ FuncRec.Position.X := 0;
+ while FuncRec.Position.X < TempWidth do begin
+ SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
+ DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
+ aFunc(FuncRec);
+ DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
+ inc(FuncRec.Position.X);
+ end;
+ inc(FuncRec.Position.Y);
+ end;
+ finally
+ SourceFD.FreeMappingData(SourceMD);
+ DestFD.FreeMappingData(DestMD);
+ DestFD.FreeMappingData(DestMD2);
+ end;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
+begin
+ result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ result := AddAlphaFromColorKeyFloat(
+ aRed / PixelData.Range.r,
+ aGreen / PixelData.Range.g,
+ aBlue / PixelData.Range.b,
+ aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
+var
+ values: array[0..2] of Single;
+ tmp: Cardinal;
+ i: Integer;
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ with PixelData do begin
+ values[0] := aRed;
+ values[1] := aGreen;
+ values[2] := aBlue;
+
+ for i := 0 to 2 do begin
+ tmp := Trunc(Range.arr[i] * aDeviation);
+ Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
+ Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
+ end;
+ Data.a := 0;
+ Range.a := 0;
+ end;
+ result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromValue(const aAlpha: Byte): Boolean;
+begin
+ result := AddAlphaFromValueFloat(aAlpha / $FF);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ with PixelData do
+ Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
+ result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.RemoveAlpha: Boolean;
+var
+ FormatDesc: TFormatDescriptor;
+begin
+ result := false;
+ FormatDesc := TFormatDescriptor.Get(Format);
+ if Assigned(Data) then begin
+ if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
+ raise EglBitmapUnsupportedFormat.Create(Format);
+ result := ConvertTo(FormatDesc.WithoutAlpha);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.FillWithColor(const aRed, aGreen, aBlue: Byte;
+ const aAlpha: Byte);
+begin
+ FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ FillWithColorFloat(
+ aRed / PixelData.Range.r,
+ aGreen / PixelData.Range.g,
+ aBlue / PixelData.Range.b,
+ aAlpha / PixelData.Range.a);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.Get(Format).PreparePixel(PixelData);
+ with PixelData do begin
+ Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
+ Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
+ Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
+ Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
+ end;
+ Convert(glBitmapFillWithColorFunc, false, @PixelData);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.SetData(const aData: PByte; const aFormat: TglBitmapFormat; const aWidth: Integer; const aHeight: Integer);
+begin
+ if (Data <> aData) then begin
+ if (Assigned(Data)) then
+ FreeMem(Data);
+ fData := aData;
+ end;
+
+ if Assigned(fData) then begin
+ FillChar(fDimension, SizeOf(fDimension), 0);
+ if aWidth <> -1 then begin
+ fDimension.Fields := fDimension.Fields + [ffX];
+ fDimension.X := aWidth;
+ end;
+
+ if aHeight <> -1 then begin
+ fDimension.Fields := fDimension.Fields + [ffY];
+ fDimension.Y := aHeight;
+ end;
+
+ fFormat := aFormat;
+ end else
+ fFormat := tfEmpty;
+
+ UpdateScanlines;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.Clone: TglBitmapData;
+var
+ Temp: TglBitmapData;
+ TempPtr: PByte;
+ Size: Integer;
+begin
+ result := nil;
+ Temp := (ClassType.Create as TglBitmapData);
+ try
+ // copy texture data if assigned
+ if Assigned(Data) then begin
+ Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
+ GetMem(TempPtr, Size);
+ try
+ Move(Data^, TempPtr^, Size);
+ Temp.SetData(TempPtr, Format, Width, Height);
+ except
+ if Assigned(TempPtr) then
+ FreeMem(TempPtr);
+ raise;
+ end;
+ end else begin
+ TempPtr := nil;
+ Temp.SetData(TempPtr, Format, Width, Height);
+ end;
+
+ // copy properties
+ Temp.fFormat := Format;
+ result := Temp;
+ except
+ FreeAndNil(Temp);
+ raise;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.Invert(const aRed, aGreen, aBlue, aAlpha: Boolean);
+var
+ mask: PtrInt;
+begin
+ mask :=
+ (Byte(aRed) and 1) or
+ ((Byte(aGreen) and 1) shl 1) or
+ ((Byte(aBlue) and 1) shl 2) or
+ ((Byte(aAlpha) and 1) shl 3);
+ if (mask > 0) then
+ Convert(glBitmapInvertFunc, false, {%H-}Pointer(mask));
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+type
+ TMatrixItem = record
+ X, Y: Integer;
+ W: Single;
+ end;
+
+ PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
+ TglBitmapToNormalMapRec = Record
+ Scale: Single;
+ Heights: array of Single;
+ MatrixU : array of TMatrixItem;
+ MatrixV : array of TMatrixItem;
+ end;
+
+const
+ ONE_OVER_255 = 1 / 255;
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
+var
+ Val: Single;
+begin
+ with FuncRec do begin
+ Val :=
+ Source.Data.r * LUMINANCE_WEIGHT_R +
+ Source.Data.g * LUMINANCE_WEIGHT_G +
+ Source.Data.b * LUMINANCE_WEIGHT_B;
+ PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+begin
+ with FuncRec do
+ PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
+type
+ TVec = Array[0..2] of Single;
+var
+ Idx: Integer;
+ du, dv: Double;
+ Len: Single;
+ Vec: TVec;
+
+ function GetHeight(X, Y: Integer): Single;
+ begin
+ with FuncRec do begin
+ X := Max(0, Min(Size.X -1, X));
+ Y := Max(0, Min(Size.Y -1, Y));
+ result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
+ end;
+ end;
+
+begin
+ with FuncRec do begin
+ with PglBitmapToNormalMapRec(Args)^ do begin
+ du := 0;
+ for Idx := Low(MatrixU) to High(MatrixU) do
+ du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
+
+ dv := 0;
+ for Idx := Low(MatrixU) to High(MatrixU) do
+ dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
+
+ Vec[0] := -du * Scale;
+ Vec[1] := -dv * Scale;
+ Vec[2] := 1;
+ end;
+
+ // Normalize
+ Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
+ if Len <> 0 then begin
+ Vec[0] := Vec[0] * Len;
+ Vec[1] := Vec[1] * Len;
+ Vec[2] := Vec[2] * Len;
+ end;
+
+ // Farbe zuweisem
+ Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
+ Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
+ Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
+var
+ Rec: TglBitmapToNormalMapRec;
+
+ procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
+ begin
+ if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
+ Matrix[Index].X := X;
+ Matrix[Index].Y := Y;
+ Matrix[Index].W := W;
+ end;
+ end;
+
+begin
+ if TFormatDescriptor.Get(Format).IsCompressed then
+ raise EglBitmapUnsupportedFormat.Create(Format);
+
+ if aScale > 100 then
+ Rec.Scale := 100
+ else if aScale < -100 then
+ Rec.Scale := -100
+ else
+ Rec.Scale := aScale;
+
+ SetLength(Rec.Heights, Width * Height);
+ try
+ case aFunc of
+ nm4Samples: begin
+ SetLength(Rec.MatrixU, 2);
+ SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
+ SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
+
+ SetLength(Rec.MatrixV, 2);
+ SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
+ SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
+ end;
+
+ nmSobel: begin
+ SetLength(Rec.MatrixU, 6);
+ SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
+ SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
+ SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
+ SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
+ SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
+ SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
+
+ SetLength(Rec.MatrixV, 6);
+ SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
+ SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
+ SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
+ SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
+ SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
+ SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
+ end;
+
+ nm3x3: begin
+ SetLength(Rec.MatrixU, 6);
+ SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
+ SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
+ SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
+ SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
+ SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
+ SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
+
+ SetLength(Rec.MatrixV, 6);
+ SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
+ SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
+ SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
+ SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
+ SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
+ SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
+ end;
+
+ nm5x5: begin
+ SetLength(Rec.MatrixU, 20);
+ SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
+ SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
+ SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
+ SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
+ SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
+ SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
+ SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
+ SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
+ SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
+ SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
+ SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
+ SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
+ SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
+ SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
+ SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
+ SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
+ SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
+ SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
+ SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
+ SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
+
+ SetLength(Rec.MatrixV, 20);
+ SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
+ SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
+ SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
+ SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
+ SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
+ SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
+ SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
+ SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
+ SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
+ SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
+ SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
+ SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
+ SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
+ SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
+ SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
+ SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
+ SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
+ SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
+ SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
+ SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
+ end;
+ end;
+
+ // Daten Sammeln
+ if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
+ Convert(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
+ else
+ Convert(glBitmapToNormalMapPrepareFunc, false, @Rec);
+ Convert(glBitmapToNormalMapFunc, false, @Rec);
+ finally
+ SetLength(Rec.Heights, 0);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create;
+begin
+ inherited Create;
+ fFormat := glBitmapDefaultFormat;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aFileName: String);
+begin
+ Create;
+ LoadFromFile(aFileName);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aStream: TStream);
+begin
+ Create;
+ LoadFromStream(aStream);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte);
+var
+ ImageSize: Integer;
+begin
+ Create;
+ if not Assigned(aData) then begin
+ ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
+ GetMem(aData, ImageSize);
+ try
+ FillChar(aData^, ImageSize, #$FF);
+ SetData(aData, aFormat, aSize.X, aSize.Y);
+ except
+ if Assigned(aData) then
+ FreeMem(aData);
+ raise;
+ end;
+ end else begin
+ SetData(aData, aFormat, aSize.X, aSize.Y);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
+begin
+ Create;
+ LoadFromFunc(aSize, aFormat, aFunc, aArgs);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
+begin
+ Create;
+ LoadFromResource(aInstance, aResource, aResType);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
+begin
+ Create;
+ LoadFromResourceID(aInstance, aResourceID, aResType);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TglBitmapData.Destroy;
+begin
+ SetData(nil, tfEmpty);
+ inherited Destroy;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetWidth: Integer;
+begin
+ if (ffX in fDimension.Fields) then
+ result := fDimension.X
+ else
+ result := -1;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetHeight: Integer;
+begin
+ if (ffY in fDimension.Fields) then
+ result := fDimension.Y
+ else
+ result := -1;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetCustomData(const aValue: Pointer);
+begin
+ if fCustomData = aValue then
+ exit;
+ fCustomData := aValue;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetCustomName(const aValue: String);
+begin
+ if fCustomName = aValue then
+ exit;
+ fCustomName := aValue;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetCustomNameW(const aValue: WideString);
+begin
+ if fCustomNameW = aValue then
+ exit;
+ fCustomNameW := aValue;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
+begin
+ if fDeleteTextureOnFree = aValue then
+ exit;
+ fDeleteTextureOnFree := aValue;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetID(const aValue: Cardinal);
+begin
+ if fID = aValue then
+ exit;
+ fID := aValue;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
+begin
+ if fMipMap = aValue then
+ exit;
+ fMipMap := aValue;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetTarget(const aValue: Cardinal);
+begin
+ if fTarget = aValue then
+ exit;
+ fTarget := aValue;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetAnisotropic(const aValue: Integer);
+{$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
+var
+ MaxAnisotropic: Integer;
+{$IFEND}
+begin
+ fAnisotropic := aValue;
+ if (ID > 0) then begin
+{$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
+ if GL_EXT_texture_filter_anisotropic then begin
+ if fAnisotropic > 0 then begin
+ Bind({$IFNDEF OPENGL_ES}false{$ENDIF});
+ glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
+ if aValue > MaxAnisotropic then
+ fAnisotropic := MaxAnisotropic;
+ glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
+ end;
+ end else begin
+ fAnisotropic := 0;
+ end;
+{$ELSE}
+ fAnisotropic := 0;
+{$IFEND}
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.CreateID;
+begin
+ if (ID <> 0) then
+ glDeleteTextures(1, @fID);
+ glGenTextures(1, @fID);
+ Bind({$IFNDEF OPENGL_ES}false{$ENDIF});
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
+begin
+ // Set Up Parameters
+ SetWrap(fWrapS, fWrapT, fWrapR);
+ SetFilter(fFilterMin, fFilterMag);
+ SetAnisotropic(fAnisotropic);
+
+{$IFNDEF OPENGL_ES}
+ SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
+ if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
+ SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
+{$ENDIF}
+
+{$IFNDEF OPENGL_ES}
+ // Mip Maps Generation Mode
+ aBuildWithGlu := false;
+ if (MipMap = mmMipmap) then begin
+ if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
+ glTexParameteri(Target, GL_GENERATE_MIPMAP, GLint(GL_TRUE))
+ else
+ aBuildWithGlu := true;
+ end else if (MipMap = mmMipmapGlu) then
+ aBuildWithGlu := true;
+{$ELSE}
+ if (MipMap = mmMipmap) then
+ glGenerateMipmap(Target);
+{$ENDIF}
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.AfterConstruction;
+begin
+ inherited AfterConstruction;
+
+ fID := 0;
+ fTarget := 0;
+{$IFNDEF OPENGL_ES}
+ fIsResident := false;
+{$ENDIF}
+
+ fMipMap := glBitmapDefaultMipmap;
+ fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
+
+ glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
+ glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
+{$IFNDEF OPENGL_ES}
+ glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
+{$ENDIF}
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.BeforeDestruction;
+begin
+ if (fID > 0) and fDeleteTextureOnFree then
+ glDeleteTextures(1, @fID);
+ inherited BeforeDestruction;
+end;
+
+{$IFNDEF OPENGL_ES}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
+begin
+ fBorderColor[0] := aRed;
+ fBorderColor[1] := aGreen;
+ fBorderColor[2] := aBlue;
+ fBorderColor[3] := aAlpha;
+ if (ID > 0) then begin
+ Bind(false);
+ glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
+ end;
+end;
+{$ENDIF}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
+begin
+ //check MIN filter
+ case aMin of
+ GL_NEAREST:
+ fFilterMin := GL_NEAREST;
+ GL_LINEAR:
+ fFilterMin := GL_LINEAR;
+ GL_NEAREST_MIPMAP_NEAREST:
+ fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
+ GL_LINEAR_MIPMAP_NEAREST:
+ fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
+ GL_NEAREST_MIPMAP_LINEAR:
+ fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
+ GL_LINEAR_MIPMAP_LINEAR:
+ fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
+ else
+ raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
+ end;
+
+ //check MAG filter
+ case aMag of
+ GL_NEAREST:
+ fFilterMag := GL_NEAREST;
+ GL_LINEAR:
+ fFilterMag := GL_LINEAR;
+ else
+ raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
+ end;
+
+ //apply filter
+ if (ID > 0) then begin
+ Bind({$IFNDEF OPENGL_ES}false{$ENDIF});
+ glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
+
+ if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
+ case fFilterMin of
+ GL_NEAREST, GL_LINEAR:
+ glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
+ GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
+ glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
+ glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ end;
+ end else
+ glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);