- function MoveMemory replaced with function Move (little speed change)
- several calculations stored in variables (little speed change)
29-09-2003
-- property BuildMipsMaps added (default = True)
+- property BuildMipsMaps added (default = true)
if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
-- property FreeDataAfterGenTexture added (default = True)
+- property FreeDataAfterGenTexture added (default = true)
if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
- parameter DisableOtherTextureUnits of Bind removed
- parameter FreeDataAfterGeneration of GenTextures removed
AlphaRange: Cardinal;
AlphaShift: Shortint;
end;
+ PglBitmapPixelDesc = ^TglBitmapPixelDesc;
////////////////////////////////////////////////////////////////////////////////////////////////////
TglBitmapPixelData = packed record
////////////////////////////////////////////////////////////////////////////////////////////////////
TglBitmap = class;
TglBitmapFunctionRec = record
- Sender : TglBitmap;
- Size: TglBitmapPixelPosition;
+ Sender: TglBitmap;
+ Size: TglBitmapPixelPosition;
Position: TglBitmapPixelPosition;
- Source: TglBitmapPixelData;
- Dest: TglBitmapPixelData;
- CustomData: Pointer;
+ Source: TglBitmapPixelData;
+ Dest: TglBitmapPixelData;
+ Args: PtrInt;
end;
TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
TglBitmapFormat = (
tfEmpty = 0,
- { TODO
- tfAlpha4,
- tfAlpha8,
- tfAlpha12,
- tfAlpha16,
+ //TODO
+ //tfAlpha4,
+ //tfAlpha8,
+ //tfAlpha12,
+ //tfAlpha16,
- tfLuminance4, }
+ //tfLuminance4,
tfLuminance8,
-{ tfLuminance12,
- tfLuminance16,
-
- tfuminance4Alpha4,
- tfLuminance6Alpha2,}
+ //tfLuminance12,
+ //tfLuminance16,
+ //
+ //tfuminance4Alpha4,
+ //tfLuminance6Alpha2,
tfLuminance8Alpha8,
-{ tfLuminance12Alpha4,
- tfLuminance12Alpha12,
- tfLuminance16Alpha16,
+ //tfLuminance12Alpha4,
+ //tfLuminance12Alpha12,
+ //tfLuminance16Alpha16,
- tfR3G3B2,
- tfRGB4,
- tfRGB5, }
+ //tfR3G3B2,
+ //tfRGB4,
+ tfRGB5,
tfRGB8,
-{ tfRGB10,
- tfRGB12,
- tfRGB16,
+ //tfRGB10,
+ //tfRGB12,
+ //tfRGB16,
- tfRGBA2,
- tfRGBA4,
- tfRGB5A1, }
+ //tfRGBA2,
+ //tfRGBA4,
+ tfRGB5A1,
tfRGBA8,
-{ tfRGB10A2,
- tfRGBA12,
- tfRGBA16,
- }
+ //tfRGB10A2,
+ //tfRGBA12,
+ //tfRGBA16,
+
+ //tfBGR4,
+ //tfBGR5,
tfBGR8,
- tfBGRA8,
- {
- tfDepth16,
- tfDepth24,
- tfDepth32 }
+ //tfBGR10,
+ //tfBGR12,
+ //tfBGR16,
+
+ //tfBGRA2,
+ //tfBGRA4,
+ //tfBGR5A1,
+ tfBGRA8
+ //tfBGR10A2,
+ //tfBGRA12,
+ //tfBGRA16,
+
+ //tfDepth16,
+ //tfDepth24,
+ //tfDepth32
);
////////////////////////////////////////////////////////////////////////////////////////////////////
- TglBitmapGetPixel = procedure(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData) of object;
- TglBitmapSetPixel = procedure(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData) of object;
+ TglBitmapGetPixel = procedure(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData) of object;
+ TglBitmapSetPixel = procedure(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData) of object;
TglBitmapMapFunc = procedure(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
TglBitmapUnMapFunc = procedure(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
class function GetPixelDesc: TglBitmapPixelDesc; virtual; abstract;
class function GetFormatDesc: TglBitmapFormatDesc; virtual; abstract;
- class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); virtual; abstract;
- class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); virtual; abstract;
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); virtual; abstract;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); virtual; abstract;
//virtual
class function WithoutAlpha: TglBitmapFormat; virtual;
class function WithAlpha: TglBitmapFormat; virtual;
+ class function GetSize: Single; virtual; overload;
+ class function GetSize(const aSize: TglBitmapPixelPosition): Integer; virtual; overload;
+ class function GetColorCompCount: Integer; virtual;
+
class function IsEmpty: Boolean; virtual;
class function HasAlpha: Boolean; virtual;
class function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; virtual;
end;
TglBitmapFormatDescClass = class of TglBitmapFormatDescriptor;
- // Base Class
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TglBitmap = class
protected
- fID: Cardinal;
- fTarget: Cardinal;
+ fID: GLuint;
+ fTarget: GLuint;
fAnisotropic: Integer;
fDeleteTextureOnFree: Boolean;
fFreeDataAfterGenTexture: Boolean;
// Mapping
fPixelSize: Integer;
fRowSize: Integer;
- fUnmapFunc: TglBitmapUnMapFunc;
- fMapFunc: TglBitmapMapFunc;
+ //TODO delete? fUnmapFunc: TglBitmapUnMapFunc;
+ //TODO delete? fMapFunc: TglBitmapMapFunc;
// Filtering
fFilterMin: Cardinal;
fWrapT: Cardinal;
fWrapR: Cardinal;
- fGetPixelFunc: TglBitmapGetPixel;
- fSetPixelFunc: TglBitmapSetPixel;
+ //TODO delete? fGetPixelFunc: TglBitmapGetPixel;
+ //TODO delete? fSetPixelFunc: TglBitmapSetPixel;
// CustomData
fFilename: String;
fCustomData: Pointer;
//Getter
- function GetHeight: Integer; virtual;
function GetWidth: Integer; virtual;
+ function GetHeight: Integer; virtual;
+
+ function GetFileWidth: Integer; virtual;
+ function GetFileHeight: Integer; virtual;
//Setter
procedure SetCustomData(const aValue: Pointer);
procedure SetTarget(const aValue: Cardinal);
procedure SetAnisotropic(const aValue: Integer);
- //Load
- {$IFDEF GLB_SUPPORT_PNG_READ}
- function LoadPNG(Stream: TStream): Boolean; virtual;
- {$ENDIF}
- {$IFDEF GLB_SUPPORT_JPEG_READ}
- function LoadJPEG(Stream: TStream): Boolean; virtual;
- {$ENDIF}
- function LoadDDS(Stream: TStream): Boolean; virtual;
- function LoadTGA(Stream: TStream): Boolean; virtual;
- function LoadBMP(Stream: TStream): Boolean; virtual;
-
- //Save
- {$IFDEF GLB_SUPPORT_PNG_WRITE}
- procedure SavePNG(Stream: TStream); virtual;
- {$ENDIF}
- {$IFDEF GLB_SUPPORT_JPEG_WRITE}
- procedure SaveJPEG(Stream: TStream); virtual;
- {$ENDIF}
- procedure SaveDDS(Stream: TStream); virtual;
- procedure SaveTGA(Stream: TStream); virtual;
- procedure SaveBMP(Stream: TStream); virtual;
-
procedure CreateID;
procedure SetupParameters(var aBuildWithGlu: Boolean);
- procedure SelectFormat(const aFormat: TglBitmapFormat; var glFormat, glInternalFormat, glType: Cardinal);
-
- procedure SetDataPointer(NewData: pByte; Format: TglBitmapFormat; Width: Integer = -1; Height: Integer = -1); virtual;
- procedure GenTexture(TestTextureSize: Boolean = True); virtual; abstract;
+ procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
+ const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
+ procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
function FlipHorz: Boolean; virtual;
function FlipVert: Boolean; virtual;
property Width: Integer read GetWidth;
property Height: Integer read GetHeight;
+
+ property FileWidth: Integer read GetFileWidth;
+ property FileHeight: Integer read GetFileHeight;
public
+ //Properties
property ID: Cardinal read fID write SetID;
property Target: Cardinal read fTarget write SetTarget;
property Format: TglBitmapFormat read fFormat write SetFormat;
property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
- property Dimension: TglBitmapPixelPosition read fDimension;
- property Data: PByte read fData;
- property IsResident: Boolean read fIsResident;
+ property Dimension: TglBitmapPixelPosition read fDimension;
+ property Data: PByte read fData;
+ property IsResident: Boolean read fIsResident;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
- //Loading
- procedure LoadFromFile(const aFileName: String);
+ //Load
+ procedure LoadFromFile(const aFilename: String);
procedure LoadFromStream(const aStream: TStream); virtual;
procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0);
{$IFDEF GLB_DELPHI}
- procedure LoadFromResource(const aInstance: Cardinal; aResource: String; const aResType: PChar = nil);
- procedure LoadFromResourceID(const sInstance: Cardinal; aResourceID: Integer; const aResType: PChar);
+ procedure LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
+ procedure LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
{$ENDIF}
+ //Save
procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
- //function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; Format: TglBitmapFormat; CustomData: Pointer = nil): boolean; overload;
- //function AddFunc(const aFunc: TglBitmapFunction; CreateTemp: Boolean; CustomData: Pointer = nil): boolean; overload;
-(* TODO
+ //Convert
+ function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt = 0): Boolean; overload;
+ function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
+ const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0): Boolean; overload;
+ public
+ //Alpha & Co
{$IFDEF GLB_SDL}
function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
const aArgs: PtrInt = 0): Boolean;
- {$ENDIF}
-
- function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0): Boolean; virtual;
- function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
- function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
- function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
- {$IFDEF GLB_DELPHI}
function AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil;
const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
{$ENDIF}
+ function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0): Boolean; virtual;
+ function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
+ function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
+ function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
+
function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
function RemoveAlpha: Boolean; virtual;
+ public
+ //Common
function Clone: TglBitmap;
- function ConvertTo(const aFormat: TglBitmapFormat; const aInternalFormat: TglBitmapFormat): Boolean; virtual;
- procedure SetBorderColor(Red, Green, Blue, Alpha: Single);
- procedure Invert(const aUseRGB: Boolean = true; aUseAlpha: Boolean = false);
+ function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
+ procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
+ procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
procedure FreeData;
- procedure FillWithColor(const aRed, aGreen, aBlue: aByte; Alpha: Byte = 255);
+ //ColorFill
+ procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
-*)
+
+ //TexParameters
procedure SetFilter(const aMin, aMag: Cardinal);
procedure SetWrap(
const S: Cardinal = GL_CLAMP_TO_EDGE;
const T: Cardinal = GL_CLAMP_TO_EDGE;
const R: Cardinal = GL_CLAMP_TO_EDGE);
- procedure GetPixel(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData); virtual;
- procedure SetPixel(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData); virtual;
+ procedure GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData); virtual;
+ procedure SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData); virtual;
- procedure Unbind(DisableTextureUnit: Boolean = True); virtual;
- procedure Bind(EnableTextureUnit: Boolean = True); virtual;
+ procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
+ procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
+ //Constructors
constructor Create; overload;
- constructor Create(FileName: String); overload;
- constructor Create(Stream: TStream); overload;
+ constructor Create(const aFileName: String); overload;
+ constructor Create(const aStream: TStream); overload;
+ constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
+ constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0); overload;
{$IFDEF GLB_DELPHI}
- constructor CreateFromResourceName(Instance: Cardinal; Resource: String; ResType: PChar = nil);
- constructor Create(Instance: Cardinal; Resource: String; ResType: PChar = nil); overload;
- constructor Create(Instance: Cardinal; ResourceID: Integer; ResType: PChar); overload;
+ constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
+ constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
{$ENDIF}
- constructor Create(Size: TglBitmapPixelPosition; Format: TglBitmapFormat); overload;
- constructor Create(Size: TglBitmapPixelPosition; Format: TglBitmapFormat; Func: TglBitmapFunction; CustomData: Pointer = nil); overload;
- end;
+ private
+ {$IFDEF GLB_SUPPORT_PNG_READ}
+ function LoadPNG(const aStream: TStream): Boolean; virtual;
+ procedure SavePNG(const aStream: TStream); virtual;
+ {$ENDIF}
+ {$IFDEF GLB_SUPPORT_JPEG_READ}
+ function LoadJPEG(const aStream: TStream): Boolean; virtual;
+ procedure SaveJPEG(const aStream: TStream); virtual;
+ {$ENDIF}
+ function LoadBMP(const aStream: TStream): Boolean; virtual;
+ procedure SaveBMP(const aStream: TStream); virtual;
+ function LoadTGA(const aStream: TStream): Boolean; virtual;
+ procedure SaveTGA(const aStream: TStream); virtual;
+ function LoadDDS(const aStream: TStream): Boolean; virtual;
+ procedure SaveDDS(const aStream: TStream); virtual;
+ end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TglBitmap2D = class(TglBitmap)
protected
// Bildeinstellungen
fLines: array of PByte;
+ (* TODO
procedure GetDXTColorBlock(pData: pByte; relX, relY: Integer; var Pixel: TglBitmapPixelData);
procedure GetPixel2DDXT1(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
procedure GetPixel2DDXT3(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
procedure GetPixel2DDXT5(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
procedure GetPixel2DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
- function GetScanline(Index: Integer): Pointer;
-
procedure SetPixel2DUnmap(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData);
+ *)
- procedure SetDataPointer(Data: pByte; Format: TglBitmapFormat; Width: Integer = -1; Height: Integer = -1); override;
- procedure UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
+ function GetScanline(const aIndex: Integer): Pointer;
+ procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
+ const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
+ procedure UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
public
property Width;
property Height;
- property Scanline[Index: Integer]: Pointer read GetScanline;
+ property Scanline[const aIndex: Integer]: Pointer read GetScanline;
procedure AfterConstruction; override;
procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
procedure GetDataFromTexture;
- procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3; const aScale: Single = 2; const aUseAlpha: Boolean = False);
- procedure GenTexture(TestTextureSize: Boolean = True); override;
+ procedure GenTexture(const aTestTextureSize: Boolean = true); override;
function FlipHorz: Boolean; override;
function FlipVert: Boolean; override;
+
+ procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
+ const aScale: Single = 2; const aUseAlpha: Boolean = false);
end;
(* TODO
fGenMode: Integer;
// Hide GenTexture
- procedure GenTexture(TestTextureSize: Boolean = True); reintroduce;
+ procedure GenTexture(TestTextureSize: Boolean = true); reintroduce;
public
procedure AfterConstruction; override;
procedure GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean = true);
- procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = True); reintroduce; virtual;
- procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = True); reintroduce; virtual;
+ procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = true); reintroduce; virtual;
+ procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = true); reintroduce; virtual;
end;
function FlipHorz: Boolean; override;
// Generation
- procedure GenTexture(TestTextureSize: Boolean = True); override;
+ procedure GenTexture(TestTextureSize: Boolean = true); override;
end;
*)
function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
-// Formatfunctions
-function FormatGetSize(const aFormat: TglBitmapFormat): Single;
-
var
glBitmapDefaultDeleteTextureOnFree: Boolean;
glBitmapDefaultFreeDataAfterGenTextures: Boolean;
type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TBitfieldFormat = class(TObject)
+ private
+ fRedShift: ShortInt;
+ fGreenShift: ShortInt;
+ fBlueShift: ShortInt;
+ fAlphaShift: ShortInt;
+
+ fRedRange: Cardinal;
+ fGreenRange: Cardinal;
+ fBlueRange: Cardinal;
+ fAlphaRange: Cardinal;
+
+ fRedMask: UInt64;
+ fGreenMask: UInt64;
+ fBlueMask: UInt64;
+ fAlphaMask: UInt64;
+ function GetSize: Integer;
+ procedure SetAlphaMask(aValue: UInt64);
+ procedure SetAlphaRange(aValue: Cardinal);
+ procedure SetAlphaShift(aValue: ShortInt);
+ procedure SetBlueMask(aValue: UInt64);
+ procedure SetBlueRange(aValue: Cardinal);
+ procedure SetBlueShift(aValue: ShortInt);
+ procedure SetGreenMask(aValue: UInt64);
+ procedure SetGreenRange(aValue: Cardinal);
+ procedure SetGreenShift(aValue: ShortInt);
+ procedure SetRedMask(aValue: UInt64);
+ procedure SetRedRange(aValue: Cardinal);
+ procedure SetRedShift(aValue: ShortInt);
+
+ procedure CalcShiftAndRange(aMask: UInt64; out aRange: Cardinal; out aShift: ShortInt);
+ public
+ property RedShift: ShortInt read fRedShift write SetRedShift;
+ property GreenShift: ShortInt read fGreenShift write SetGreenShift;
+ property BlueShift: ShortInt read fBlueShift write SetBlueShift;
+ property AlphaShift: ShortInt read fAlphaShift write SetAlphaShift;
+
+ property RedRange: Cardinal read fRedRange write SetRedRange;
+ property GreenRange: Cardinal read fGreenRange write SetGreenRange;
+ property BlueRange: Cardinal read fBlueRange write SetBlueRange;
+ property AlphaRange: Cardinal read fAlphaRange write SetAlphaRange;
+
+ property RedMask: UInt64 read fRedMask write SetRedMask;
+ property GreenMask: UInt64 read fGreenMask write SetGreenMask;
+ property BlueMask: UInt64 read fBlueMask write SetBlueMask;
+ property AlphaMask: UInt64 read fAlphaMask write SetAlphaMask;
+
+ property Size: Integer read GetSize;
+
+ procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte);
+ procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); overload;
+ procedure Unmap(const aData: UInt64; var aPixel: TglBitmapPixelData); overload;
+ end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TfdEmpty = class(TglBitmapFormatDescriptor)
public
class function GetFormat: TglBitmapFormat; override;
class function GetPixelDesc: TglBitmapPixelDesc; override;
class function GetFormatDesc: TglBitmapFormatDesc; override;
- class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
- class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function GetFormatDesc: TglBitmapFormatDesc; override;
class function WithAlpha: TglBitmapFormat; override;
- class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
- class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function GetFormatDesc: TglBitmapFormatDesc; override;
class function WithoutAlpha: TglBitmapFormat; override;
- class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
- class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TfdRGB5 = class(TglBitmapFormatDescriptor)
+ public
+ class function GetFormat: TglBitmapFormat; override;
+ class function GetPixelDesc: TglBitmapPixelDesc; override;
+ class function GetFormatDesc: TglBitmapFormatDesc; override;
+ class function WithAlpha: TglBitmapFormat; override;
+
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
+ end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TfdRGB8 = class(TglBitmapFormatDescriptor)
public
class function GetFormat: TglBitmapFormat; override;
class function GetFormatDesc: TglBitmapFormatDesc; override;
class function WithAlpha: TglBitmapFormat; override;
- class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
- class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
+ end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TfdRGB5A1 = class(TglBitmapFormatDescriptor)
+ public
+ class function GetFormat: TglBitmapFormat; override;
+ class function GetPixelDesc: TglBitmapPixelDesc; override;
+ class function GetFormatDesc: TglBitmapFormatDesc; override;
+ class function WithoutAlpha: TglBitmapFormat; override;
+
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function GetFormatDesc: TglBitmapFormatDesc; override;
class function WithoutAlpha: TglBitmapFormat; override;
- class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
- class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function GetFormatDesc: TglBitmapFormatDesc; override;
class function WithAlpha: TglBitmapFormat; override;
- class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
- class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function GetFormatDesc: TglBitmapFormatDesc; override;
class function WithoutAlpha: TglBitmapFormat; override;
- class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
- class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+ class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+ class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
end;
const
LUMINANCE_WEIGHT_R = 0.30;
LUMINANCE_WEIGHT_G = 0.59;
LUMINANCE_WEIGHT_B = 0.11;
- UNSUPPORTED_INTERNAL_FORMAT = 'the given format isn''t supported by this function.';
+
+ ALPHA_WEIGHT_R = 0.30;
+ ALPHA_WEIGHT_G = 0.59;
+ ALPHA_WEIGHT_B = 0.11;
+
+ UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
+
+ FORMAT_DESCRIPTORS: array[TglBitmapFormat] of TglBitmapFormatDescClass = (
+ TfdEmpty,
+
+ TfdLuminance8,
+ TfdLuminance8Alpha8,
+
+ TfdRGB5,
+ TfdRGB8,
+
+ TfdRGB5A1,
+ TfdRGBA8,
+
+ TfdBGR8,
+ TfdBGRA8
+ );
+
{$REGION Private Helper}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
begin
- Result.Fields := [];
+ result.Fields := [];
if X >= 0 then
- Result.Fields := Result.Fields + [ffX];
+ result.Fields := result.Fields + [ffX];
if Y >= 0 then
- Result.Fields := Result.Fields + [ffY];
+ result.Fields := result.Fields + [ffY];
- Result.X := Max(0, X);
- Result.Y := Max(0, Y);
-end;
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function FormatGetImageSize(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat): Integer;
-begin
- if (aSize.X = 0) and (aSize.Y = 0) then
- Result := 0
- else
- Result := Ceil(Max(aSize.Y, 1) * Max(aSize.X, 1) * FormatGetSize(aFormat));
+ result.X := Max(0, X);
+ result.Y := Max(0, Y);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
begin
- //TODO check Formats!
- result := [];
-
+ //TODO Supported File Formats!
+ result := [ftDDS, ftTGA, ftBMP];
+ (*
{$IFDEF GLB_SUPPORT_PNG_WRITE}
if aFormat in [
tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
tfDepth16, tfDepth24, tfDepth32]
then
result := result + [ftDDS, ftTGA, ftBMP];
+ *)
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function GetBitSize(aBitSet: Cardinal): Integer;
+function GetTopMostBit(aBitSet: UInt64): Integer;
+begin
+ result := 0;
+ while aBitSet > 0 do begin
+ inc(result);
+ aBitSet := aBitSet shr 1;
+ end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function CountSetBits(aBitSet: UInt64): Integer;
begin
result := 0;
while aBitSet > 0 do begin
end;
{$ENDREGION}
+//TODO check _ARB functions and constants
+
(* GLB_NO_NATIVE_GL
{$IFNDEF GLB_NO_NATIVE_GL}
procedure ReadOpenGLExtensions;
ExtPos: Integer;
begin
ExtPos := Pos(Extension, Buffer);
- Result := ExtPos > 0;
+ result := ExtPos > 0;
- if Result then
- Result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
+ if result then
+ result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
end;
function glLoad (aFunc: pAnsiChar): pointer;
begin
{$IFDEF LINUX}
- Result := glXGetProcAddress(aFunc);
+ result := glXGetProcAddress(aFunc);
{$else}
- Result := wglGetProcAddress(aFunc);
+ result := wglGetProcAddress(aFunc);
{$ENDIF}
end;
Buffer := glGetString(GL_VERSION);
TrimVersionString(Buffer, MajorVersion, MinorVersion);
- GL_VERSION_1_2 := False;
- GL_VERSION_1_3 := False;
- GL_VERSION_1_4 := False;
- GL_VERSION_2_0 := False;
+ GL_VERSION_1_2 := false;
+ GL_VERSION_1_3 := false;
+ GL_VERSION_1_4 := false;
+ GL_VERSION_2_0 := false;
if MajorVersion = 1 then begin
if MinorVersion >= 1 then begin
if MinorVersion >= 2 then
- GL_VERSION_1_2 := True;
+ GL_VERSION_1_2 := true;
if MinorVersion >= 3 then
- GL_VERSION_1_3 := True;
+ GL_VERSION_1_3 := true;
if MinorVersion >= 4 then
- GL_VERSION_1_4 := True;
+ GL_VERSION_1_4 := true;
end;
end;
if MajorVersion >= 2 then begin
- GL_VERSION_1_2 := True;
- GL_VERSION_1_3 := True;
- GL_VERSION_1_4 := True;
- GL_VERSION_2_0 := True;
+ GL_VERSION_1_2 := true;
+ GL_VERSION_1_3 := true;
+ GL_VERSION_1_4 := true;
+ GL_VERSION_2_0 := true;
end;
// Extensions
{$R+}
{$ENDIF}
- Result := CreatePalette(Pal^);
+ result := CreatePalette(Pal^);
FreeMem(Pal);
end;
{$IFDEF GLB_SDL_IMAGE}
function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
begin
- Result := TStream(context^.unknown.data1).Seek(offset, whence);
+ result := TStream(context^.unknown.data1).Seek(offset, whence);
end;
function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
begin
- Result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
+ result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
end;
function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
begin
- Result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
+ result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
end;
function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
begin
- Result := 0;
+ result := 0;
end;
function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
begin
- Result := SDL_AllocRW;
+ result := SDL_AllocRW;
- if Result = nil then
+ if result = nil then
raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
- Result^.seek := glBitmapRWseek;
- Result^.read := glBitmapRWread;
- Result^.write := glBitmapRWwrite;
- Result^.close := glBitmapRWclose;
- Result^.unknown.data1 := Stream;
+ result^.seek := glBitmapRWseek;
+ result^.read := glBitmapRWread;
+ result^.write := glBitmapRWwrite;
+ result^.close := glBitmapRWclose;
+ result^.unknown.data1 := Stream;
end;
{$ENDIF}
*)
var
glBitmap: TglBitmap2D;
begin
- Result := false;
+ result := false;
Texture := 0;
{$IFDEF GLB_DELPHI}
glBitmap := TglBitmap2D.Create(FileName);
try
- glBitmap.DeleteTextureOnFree := False;
- glBitmap.FreeDataAfterGenTexture := False;
- glBitmap.GenTexture(True);
+ glBitmap.DeleteTextureOnFree := false;
+ glBitmap.FreeDataAfterGenTexture := false;
+ glBitmap.GenTexture(true);
if (glBitmap.ID > 0) then begin
Texture := glBitmap.ID;
- Result := True;
+ result := true;
end;
finally
glBitmap.Free;
CM := TglBitmapCubeMap.Create;
try
- CM.DeleteTextureOnFree := False;
+ CM.DeleteTextureOnFree := false;
// Maps
{$IFDEF GLB_DELPHI}
CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
Texture := CM.ID;
- Result := True;
+ result := true;
finally
CM.Free;
end;
NM := TglBitmapNormalMap.Create;
try
- NM.DeleteTextureOnFree := False;
+ NM.DeleteTextureOnFree := false;
NM.GenerateNormalMap(Size);
Texture := NM.ID;
- Result := True;
+ result := true;
finally
NM.Free;
end;
end;
{$ENDREGION}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TCustomFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetAlphaMask(aValue: UInt64);
+begin
+ if fAlphaMask = aValue then Exit;
+ fAlphaMask := aValue;
+ CalcShiftAndRange(fAlphaMask, fAlphaRange, fAlphaShift);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TBitfieldFormat.GetSize: Integer;
+var
+ tmp: UInt64;
+begin
+ tmp :=
+ (fRedRange shl fRedShift) or
+ (fGreenRange shl fGreenShift) or
+ (fBlueRange shl fBlueShift) or
+ (fAlphaRange shl fAlphaShift);
+ result := Trunc(GetTopMostBit(tmp) / 8);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetAlphaRange(aValue: Cardinal);
+begin
+ if fAlphaRange = aValue then Exit;
+ fAlphaRange := aValue;
+ fAlphaMask := fAlphaRange shl fAlphaShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetAlphaShift(aValue: ShortInt);
+begin
+ if fAlphaShift = aValue then Exit;
+ fAlphaShift := aValue;
+ fAlphaMask := fAlphaRange shl fAlphaShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetBlueMask(aValue: UInt64);
+begin
+ if fBlueMask = aValue then Exit;
+ fBlueMask := aValue;
+ CalcShiftAndRange(fBlueMask, fBlueRange, fBlueShift);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetBlueRange(aValue: Cardinal);
+begin
+ if fBlueRange = aValue then Exit;
+ fBlueRange := aValue;
+ fBlueMask := fBlueRange shl fBlueShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetBlueShift(aValue: ShortInt);
+begin
+ if fBlueShift = aValue then Exit;
+ fBlueShift := aValue;
+ fBlueMask := fBlueRange shl fBlueShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetGreenMask(aValue: UInt64);
+begin
+ if fGreenMask = aValue then Exit;
+ fGreenMask := aValue;
+ CalcShiftAndRange(fGreenMask, fGreenRange, fGreenShift);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetGreenRange(aValue: Cardinal);
+begin
+ if fGreenRange = aValue then Exit;
+ fGreenRange := aValue;
+ fGreenMask := fGreenRange shl fGreenShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetGreenShift(aValue: ShortInt);
+begin
+ if fGreenShift = aValue then Exit;
+ fGreenShift := aValue;
+ fGreenMask := fGreenRange shl fGreenShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetRedMask(aValue: UInt64);
+begin
+ if fRedMask = aValue then Exit;
+ fRedMask := aValue;
+ CalcShiftAndRange(fRedMask, fRedRange, fRedShift);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetRedRange(aValue: Cardinal);
+begin
+ if fRedRange = aValue then Exit;
+ fRedRange := aValue;
+ fRedMask := fRedRange shl fRedShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetRedShift(aValue: ShortInt);
+begin
+ if fRedShift = aValue then Exit;
+ fRedShift := aValue;
+ fRedMask := fRedRange shl fRedShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.CalcShiftAndRange(aMask: UInt64; out aRange: Cardinal;
+ out aShift: ShortInt);
+begin
+ aShift := 0;
+ aRange := 0;
+ if (aMask = 0) then
+ exit;
+ while (aMask > 0) and ((aMask and 1) = 0) do begin
+ inc(aShift);
+ aMask := aMask shr 1;
+ end;
+ aRange := 1;
+ while (aMask > 0) do begin
+ aRange := aRange shl 1;
+ aMask := aMask shr 1;
+ end;
+ dec(aRange);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
+var
+ data: UInt64;
+ s: Integer;
+type
+ PUInt64 = ^UInt64;
+begin
+ data :=
+ ((aPixel.Red and fRedRange) shl fRedShift) or
+ ((aPixel.Green and fGreenRange) shl fGreenShift) or
+ ((aPixel.Blue and fBlueRange) shl fBlueShift) or
+ ((aPixel.Alpha and fAlphaRange) shl fAlphaShift);
+ s := Size;
+ case s of
+ 1: aData^ := data;
+ 2: PWord(aData)^ := data;
+ 4: PCardinal(aData)^ := data;
+ 8: PUInt64(aData)^ := data;
+ end;
+ inc(aData, s);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
+var
+ data: UInt64;
+ s: Integer;
+type
+ PUInt64 = ^UInt64;
+begin
+ s := Size;
+ case s of
+ 1: data := aData^;
+ 2: data := PWord(aData)^;
+ 4: data := PCardinal(aData)^;
+ 8: data := PUInt64(aData)^;
+ end;
+ Unmap(data, aPixel);
+ inc(aData, s);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.Unmap(const aData: UInt64; var aPixel: TglBitmapPixelData);
+begin
+ aPixel.Red := (aData shr fRedShift) and fRedRange;
+ aPixel.Green := (aData shr fGreenShift) and fGreenRange;
+ aPixel.Blue := (aData shr fBlueShift) and fBlueRange;
+ aPixel.Alpha := (aData shr fAlphaShift) and fAlphaRange;
+end;
+
{$REGION TglBitmapFormatDescriptor}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TglBitmapFormatDescriptor.GetSize: Single;
+var
+ tmp: UInt64;
+begin
+ with GetPixelDesc do begin
+ tmp :=
+ (RedRange shl RedShift) or
+ (GreenRange shl GreenShift) or
+ (BlueRange shl BlueShift) or
+ (AlphaRange shl AlphaShift);
+ end;
+ result := Trunc(GetTopMostBit(tmp) / 4) / 2;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TglBitmapFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
+var
+ w, h: Integer;
+begin
+ if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
+ w := Max(1, aSize.X);
+ h := Max(1, aSize.Y);
+ result := Ceil(w * h * GetSize);
+ end else
+ result := 0;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TglBitmapFormatDescriptor.GetColorCompCount: Integer;
+begin
+ result := 0;
+ with GetPixelDesc do begin
+ if (RedRange > 0) then
+ inc(result);
+ if (GreenRange > 0) then
+ inc(result);
+ if (BlueRange > 0) then
+ inc(result);
+ if (AlphaRange > 0) then
+ inc(result);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TglBitmapFormatDescriptor.IsEmpty: Boolean;
begin
result := (GetFormat = tfEmpty);
var
PixelDesc: TglBitmapPixelDesc;
begin
- result := False;
+ result := false;
if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
if (aAlphaMask <> 0) and (aAlphaMask <> (AlphaRange shl AlphaShift)) then
exit;
end;
- result := True;
+ result := true;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class procedure TglBitmapFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData);
begin
FillChar(aPixel, SizeOf(aPixel), 0);
- with GetPixelDesc do begin
+ aPixel.PixelDesc := GetPixelDesc;
+ with aPixel.PixelDesc do begin
aPixel.Red := RedRange;
aPixel.Green := GreenRange;
aPixel.Blue := BlueRange;
end;
end;
-class procedure TfdEmpty.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdEmpty.Map(const aPixel: TglBitmapPixelData; var aData: PByte );
begin
raise EglBitmapException.Create('format does not support mapping');
end;
-class procedure TfdEmpty.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdEmpty.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
begin
raise EglBitmapException.Create('format does not support unmapping');
end;
result := tfLuminance8Alpha8;
end;
-class procedure TfdLuminance8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdLuminance8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
begin
aData^ := Trunc(
aPixel.Red * LUMINANCE_WEIGHT_R +
inc(aData);
end;
-class procedure TfdLuminance8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdLuminance8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
begin
aPixel.Red := aData^;
aPixel.Green := aData^;
result := tfLuminance8;
end;
-class procedure TfdLuminance8Alpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdLuminance8Alpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
begin
aData^ := Trunc(
aPixel.Red * LUMINANCE_WEIGHT_R +
inc(aData);
end;
-class procedure TfdLuminance8Alpha8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdLuminance8Alpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
begin
aPixel.Red := aData^;
aPixel.Green := aData^;
end;
{$ENDREGION}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGB5/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TfdRGB5.GetFormat: TglBitmapFormat;
+begin
+ result := tfRGB5;
+end;
+
+class function TfdRGB5.GetPixelDesc: TglBitmapPixelDesc;
+begin
+ with result do begin
+ RedRange := $0000001F; RedShift := 0;
+ GreenRange := $0000001F; GreenShift := 5;
+ BlueRange := $0000001F; BlueShift := 10;
+ AlphaRange := $00000000; AlphaShift := 0;
+ end;
+end;
+
+class function TfdRGB5.GetFormatDesc: TglBitmapFormatDesc;
+begin
+ with result do begin
+ Format := GL_RGB;
+ InternalFormat := GL_RGB5;
+ DataType := GL_UNSIGNED_SHORT_5_5_5_1;
+ end;
+end;
+
+class function TfdRGB5.WithAlpha: TglBitmapFormat;
+begin
+ result := tfRGB5A1;
+end;
+
+class procedure TfdRGB5.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
+begin
+ PWord(aData)^ :=
+ ((aPixel.Red and aPixel.PixelDesc.RedRange) shl aPixel.PixelDesc.RedShift) or
+ ((aPixel.Green and aPixel.PixelDesc.GreenRange) shl aPixel.PixelDesc.GreenShift) or
+ ((aPixel.Blue and aPixel.PixelDesc.BlueRange) shl aPixel.PixelDesc.BlueShift);
+ inc(aData, 2);
+end;
+
+class procedure TfdRGB5.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
+begin
+ aPixel.Red := (PWord(aData)^ shr aPixel.PixelDesc.RedShift) and aPixel.PixelDesc.RedRange;
+ aPixel.Green := (PWord(aData)^ shr aPixel.PixelDesc.GreenShift) and aPixel.PixelDesc.GreenRange;
+ aPixel.Blue := (PWord(aData)^ shr aPixel.PixelDesc.BlueShift) and aPixel.PixelDesc.BlueRange;
+ aPixel.Alpha := 0;
+ inc(aData, 2);
+end;
+
{$REGION TfdRGB8}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TfdRGB8/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
result := tfRGBA8;
end;
-class procedure TfdRGB8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdRGB8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
begin
aData^ := aPixel.Red;
inc(aData);
inc(aData);
end;
-class procedure TfdRGB8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdRGB8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
begin
aPixel.Red := aData^;
inc(aData);
end;
{$ENDREGION}
-{$REGION TfdRGBA8}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TfdRGBA8////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGB5A1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class function TfdRGBA8.GetFormat: TglBitmapFormat;
+class function TfdRGB5A1.GetFormat: TglBitmapFormat;
begin
- result := tfRGBA8;
+ result := tfRGB5A1;
end;
-class function TfdRGBA8.GetPixelDesc: TglBitmapPixelDesc;
+class function TfdRGB5A1.GetPixelDesc: TglBitmapPixelDesc;
begin
with result do begin
- RedRange := $000000FF; RedShift := 0;
- GreenRange := $000000FF; GreenShift := 8;
- BlueRange := $000000FF; BlueShift := 16;
- AlphaRange := $000000FF; AlphaShift := 24;
+ RedRange := $0000001F; RedShift := 0;
+ GreenRange := $0000001F; GreenShift := 5;
+ BlueRange := $0000001F; BlueShift := 10;
+ AlphaRange := $00000001; AlphaShift := 15;
end;
end;
-class function TfdRGBA8.GetFormatDesc: TglBitmapFormatDesc;
+class function TfdRGB5A1.GetFormatDesc: TglBitmapFormatDesc;
begin
with result do begin
- Format := GL_RGB;
- InternalFormat := GL_RGB8;
- DataType := GL_UNSIGNED_BYTE;
+ Format := GL_RGBA;
+ InternalFormat := GL_RGB5_A1;
+ DataType := GL_UNSIGNED_SHORT_5_5_5_1;
end;
end;
-class function TfdRGBA8.WithoutAlpha: TglBitmapFormat;
+class function TfdRGB5A1.WithoutAlpha: TglBitmapFormat;
begin
- result := tfRGB8;
+ //TODO result := tfRGB5;
end;
-class procedure TfdRGBA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdRGB5A1.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
begin
- aData^ := aPixel.Red;
- inc(aData);
- aData^ := aPixel.Green;
- inc(aData);
- aData^ := aPixel.Blue;
+ PWord(aData)^ :=
+ ((aPixel.Red and aPixel.PixelDesc.RedRange) shl aPixel.PixelDesc.RedShift) or
+ ((aPixel.Green and aPixel.PixelDesc.GreenRange) shl aPixel.PixelDesc.GreenShift) or
+ ((aPixel.Blue and aPixel.PixelDesc.BlueRange) shl aPixel.PixelDesc.BlueShift) or
+ ((aPixel.Alpha and aPixel.PixelDesc.AlphaRange) shl aPixel.PixelDesc.AlphaShift);
+ inc(aData, 2);
+end;
+
+class procedure TfdRGB5A1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
+begin
+ aPixel.Red := (PWord(aData)^ shr aPixel.PixelDesc.RedShift) and aPixel.PixelDesc.RedRange;
+ aPixel.Green := (PWord(aData)^ shr aPixel.PixelDesc.GreenShift) and aPixel.PixelDesc.GreenRange;
+ aPixel.Blue := (PWord(aData)^ shr aPixel.PixelDesc.BlueShift) and aPixel.PixelDesc.BlueRange;
+ aPixel.Alpha := (PWord(aData)^ shr aPixel.PixelDesc.AlphaShift) and aPixel.PixelDesc.AlphaRange;
+ inc(aData, 2);
+end;
+
+{$REGION TfdRGBA8}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGBA8////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TfdRGBA8.GetFormat: TglBitmapFormat;
+begin
+ result := tfRGBA8;
+end;
+
+class function TfdRGBA8.GetPixelDesc: TglBitmapPixelDesc;
+begin
+ with result do begin
+ RedRange := $000000FF; RedShift := 0;
+ GreenRange := $000000FF; GreenShift := 8;
+ BlueRange := $000000FF; BlueShift := 16;
+ AlphaRange := $000000FF; AlphaShift := 24;
+ end;
+end;
+
+class function TfdRGBA8.GetFormatDesc: TglBitmapFormatDesc;
+begin
+ with result do begin
+ Format := GL_RGB;
+ InternalFormat := GL_RGB8;
+ DataType := GL_UNSIGNED_BYTE;
+ end;
+end;
+
+class function TfdRGBA8.WithoutAlpha: TglBitmapFormat;
+begin
+ result := tfRGB8;
+end;
+
+class procedure TfdRGBA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
+begin
+ aData^ := aPixel.Red;
+ inc(aData);
+ aData^ := aPixel.Green;
+ inc(aData);
+ aData^ := aPixel.Blue;
inc(aData);
aData^ := aPixel.Alpha;
inc(aData);
end;
-class procedure TfdRGBA8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdRGBA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
begin
aPixel.Red := aData^;
inc(aData);
result := tfBGRA8;
end;
-class procedure TfdBGR8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdBGR8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
begin
aData^ := aPixel.Blue;
inc(aData);
inc(aData);
end;
-class procedure TfdBGR8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdBGR8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
begin
aPixel.Blue := aData^;
inc(aData);
result := tfBGR8;
end;
-class procedure TfdBGRA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdBGRA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
begin
aData^ := aPixel.Blue;
inc(aData);
inc(aData);
end;
-class procedure TfdBGRA8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdBGRA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
begin
aPixel.Blue := aData^;
inc(aData);
end;
{$ENDREGION}
-{$REGION TglBitmap }
+{$REGION TglBitmap}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TglBitmap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TglBitmap.GetHeight: Integer;
+procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
begin
- if (ffY in fDimension.Fields) then
- result := fDimension.Y
- else
- result := -1;
+ with aFuncRec do begin
+ if (Source.PixelDesc.RedRange > 0) then
+ Dest.Red := Source.Red;
+ if (Source.PixelDesc.GreenRange > 0) then
+ Dest.Green := Source.Green;
+ if (Source.PixelDesc.BlueRange > 0) then
+ Dest.Blue := Source.Blue;
+ if (Source.PixelDesc.AlphaRange > 0) then
+ Dest.Alpha := Source.Alpha;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
+begin
+ with aFuncRec do begin
+ if (Source.PixelDesc.RedRange > 0) then
+ Dest.Red := Round(Dest.PixelDesc.RedRange * Source.Red / Source.PixelDesc.RedRange);
+ if (Source.PixelDesc.GreenRange > 0) then
+ Dest.Green := Round(Dest.PixelDesc.GreenRange * Source.Green / Source.PixelDesc.GreenRange);
+ if (Source.PixelDesc.BlueRange > 0) then
+ Dest.Blue := Round(Dest.PixelDesc.BlueRange * Source.Blue / Source.PixelDesc.BlueRange);
+ if (Source.PixelDesc.AlphaRange > 0) then
+ Dest.Alpha := Round(Dest.PixelDesc.AlphaRange * Source.Alpha / Source.PixelDesc.AlphaRange);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
+begin
+ with aFuncRec do
+ with PglBitmapPixelDesc(Args)^ do begin
+ if (Source.PixelDesc.RedRange > 0) then
+ Dest.Red := Source.Red shr RedShift;
+ if (Source.PixelDesc.GreenRange > 0) then
+ Dest.Green := Source.Green shr GreenShift;
+ if (Source.PixelDesc.BlueRange > 0) then
+ Dest.Blue := Source.Blue shr BlueShift;
+ if (Source.PixelDesc.AlphaRange > 0) then
+ Dest.Alpha := Source.Alpha shr AlphaShift;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
+begin
+ with aFuncRec do begin
+ Dest.Red := Source.Red;
+ Dest.Green := Source.Green;
+ Dest.Blue := Source.Blue;
+ Dest.Alpha := Source.Alpha;
+ if (Args and $1 > 0) then begin
+ Dest.Red := Dest.Red xor Dest.PixelDesc.RedRange;
+ Dest.Green := Dest.Green xor Dest.PixelDesc.GreenRange;
+ Dest.Blue := Dest.Blue xor Dest.PixelDesc.BlueRange;
+ end;
+ if (Args and $2 > 0) then begin
+ Dest.Alpha := Dest.Alpha xor Dest.PixelDesc.AlphaRange;
+ end;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
+type
+ PglBitmapPixelData = ^TglBitmapPixelData;
+begin
+ with aFuncRec do begin
+ Dest.Red := PglBitmapPixelData(Args)^.Red;
+ Dest.Green := PglBitmapPixelData(Args)^.Green;
+ Dest.Blue := PglBitmapPixelData(Args)^.Blue;
+ Dest.Alpha := PglBitmapPixelData(Args)^.Alpha;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+var
+ Temp: Single;
+begin
+ with FuncRec do begin
+ if (FuncRec.Args = 0) then begin //source has no alpha
+ Temp :=
+ Source.Red / Source.PixelDesc.RedRange * ALPHA_WEIGHT_R +
+ Source.Green / Source.PixelDesc.GreenRange * ALPHA_WEIGHT_G +
+ Source.Blue / Source.PixelDesc.BlueRange * ALPHA_WEIGHT_B;
+ Dest.Alpha := Round(Dest.PixelDesc.AlphaRange * Temp);
+ end else
+ Dest.Alpha := Round(Source.Alpha / Source.PixelDesc.AlphaRange * Dest.PixelDesc.AlphaRange);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+type
+ PglBitmapPixelData = ^TglBitmapPixelData;
+begin
+ with FuncRec do begin
+ Dest.Red := Source.Red;
+ Dest.Green := Source.Green;
+ Dest.Blue := Source.Blue;
+
+ with PglBitmapPixelData(Args)^ do
+ if ((Dest.Red <= Red ) and (Dest.Red >= PixelDesc.RedRange ) and
+ (Dest.Green <= Green) and (Dest.Green >= PixelDesc.GreenRange) and
+ (Dest.Blue <= Blue ) and (Dest.Blue >= PixelDesc.BlueRange )) then
+ Dest.Alpha := 0
+ else
+ Dest.Alpha := Dest.PixelDesc.AlphaRange;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+type
+ PglBitmapPixelData = ^TglBitmapPixelData;
+begin
+ with FuncRec do begin
+ Dest.Red := Source.Red;
+ Dest.Green := Source.Green;
+ Dest.Blue := Source.Blue;
+ with PglBitmapPixelData(Args)^ do
+ Dest.Alpha := Alpha;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
+type
+ PRGBPix = ^TRGBPix;
+ TRGBPix = array [0..2] of byte;
+var
+ Temp: Byte;
+begin
+ while aWidth > 0 do begin
+ Temp := PRGBPix(aData)^[0];
+ PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
+ PRGBPix(aData)^[2] := Temp;
+
+ if aHasAlpha then
+ Inc(aData, 4)
+ else
+ Inc(aData, 3);
+ dec(aWidth);
+ end;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{$REGION Getter}
function TglBitmap.GetWidth: Integer;
begin
if (ffX in fDimension.Fields) then
result := -1;
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetHeight: Integer;
+begin
+ if (ffY in fDimension.Fields) then
+ result := fDimension.Y
+ else
+ result := -1;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetFileWidth: Integer;
+begin
+ result := Max(1, Width);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetFileHeight: Integer;
+begin
+ result := Max(1, Height);
+end;
+{$ENDREGION}
+
{$REGION Setter}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TglBitmap.SetCustomData(const aValue: Pointer);
begin
if fFormat = aValue then
exit;
- fFormat := aValue;
+ if (FORMAT_DESCRIPTORS[Format].GetSize <> FORMAT_DESCRIPTORS[aValue].GetSize) then
+ raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT);
+ SetDataPointer(Data, aValue, Width, Height);
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var
MaxAnisotropic: Integer;
begin
- fAnisotropic := Value;
+ fAnisotropic := aValue;
if (ID > 0) then begin
if GL_EXT_texture_filter_anisotropic then begin
if fAnisotropic > 0 then begin
- Bind(False);
+ Bind(false);
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
if aValue > MaxAnisotropic then
fAnisotropic := MaxAnisotropic;
end;
{$ENDREGION}
-procedure TglBitmap.AfterConstruction;
-begin
- inherited AfterConstruction;
-
- fID := 0;
- fTarget := 0;
- fIsResident := False;
-
- fFormat := glBitmapGetDefaultFormat;
- fMipMap := glBitmapDefaultMipmap;
- fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
- fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
-
- glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
- glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
-end;
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TglBitmap.BeforeDestruction;
-begin
- SetDataPointer(nil, ifEmpty);
- if (ID > 0) and fDeleteTextureOnFree then
- glDeleteTextures(1, @ID);
- inherited BeforeDestruction;
-end;
-
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TglBitmap.CreateID;
begin
- if ID <> 0 then
- glDeleteTextures(1, @ID);
- glGenTextures(1, @ID);
+ if (ID <> 0) then
+ glDeleteTextures(1, @fID);
+ glGenTextures(1, @fID);
Bind(false);
end;
SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
// Mip Maps Generation Mode
- aBuildWithGlu := False;
+ aBuildWithGlu := false;
if (MipMap = mmMipmap) then begin
if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
else
- BuildWithGlu := True;
+ aBuildWithGlu := true;
end else if (MipMap = mmMipmapGlu) then
- BuildWithGlu := True;
+ aBuildWithGlu := true;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TglBitmap.SelectFormat(const aFormat: TglBitmapFormat; var glFormat, glInternalFormat, glType: Cardinal);
+procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
+ const aWidth: Integer; const aHeight: Integer);
+var
+ s: Single;
+begin
+ if (Data <> aData) then begin
+ if (Assigned(Data)) then
+ FreeMem(Data);
+ fData := aData;
+ end;
- procedure Check12;
- begin
- if not GL_VERSION_1_2 then
- raise EglBitmapUnsupportedFormatFormat.Create('SelectFormat - You need at least OpenGL 1.2 to support these format.');
+ FillChar(fDimension, SizeOf(fDimension), 0);
+ if not Assigned(fData) then begin
+ fFormat := tfEmpty;
+ fPixelSize := 0;
+ fRowSize := 0;
+ end else begin
+ 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;
+
+ s := FORMAT_DESCRIPTORS[aFormat].GetSize;
+ fFormat := aFormat;
+ fPixelSize := Ceil(s);
+ fRowSize := Ceil(s * aWidth);
end;
+end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.FlipHorz: Boolean;
begin
- PIXEL_DESC_ALPHA12;
- glType := GL_UNSIGNED_BYTE;
- glInternalFormat := Cardinal(aFormat);
+ result := false;
+end;
- case aFormat of
- tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16:
- glFormat := GL_ALPHA;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.FlipVert: Boolean;
+begin
+ result := false;
+end;
- tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16:
- glFormat := GL_LUMINANCE;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.AfterConstruction;
+begin
+ inherited AfterConstruction;
- tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8,
- tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16:
- glFormat := GL_LUMINANCE_ALPHA;
+ fID := 0;
+ fTarget := 0;
+ fIsResident := false;
- tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16:
- glFormat := GL_RGB;
+ fFormat := glBitmapGetDefaultFormat;
+ fMipMap := glBitmapDefaultMipmap;
+ fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
+ fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
- tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16:
- glFormat := GL_RGBA;
+ glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
+ glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
+end;
- tfDepth16, tfDepth24, tfDepth32:
- glFormat := GL_DEPTH_COMPONENT;
- else
- glFormat := 0;
- end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.BeforeDestruction;
+begin
+ SetDataPointer(nil, tfEmpty);
+ if (fID > 0) and fDeleteTextureOnFree then
+ glDeleteTextures(1, @fID);
+ inherited BeforeDestruction;
+end;
- case aFormat of
- tfRGBA4:
- glType := GL_UNSIGNED_SHORT_4_4_4_4;
- tfRGB5A1:
- glType := GL_UNSIGNED_SHORT_5_5_5_1;
- tfRG
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.LoadFromFile(const aFilename: String);
+var
+ fs: TFileStream;
+begin
+ fFilename := aFilename;
+ fs := TFileStream.Create(fFilename, fmOpenRead);
+ try
+ fs.Position := 0;
+ LoadFromStream(fs);
+ finally
+ fs.Free;
end;
+end;
-
- // selecting Format
- case DataFormat of
- ifAlpha:
- glFormat := GL_ALPHA;
- ifLuminance:
- glFormat := GL_LUMINANCE;
- ifDepth8:
- glFormat := GL_DEPTH_COMPONENT;
- ifLuminanceAlpha:
- glFormat := GL_LUMINANCE_ALPHA;
- ifBGR8:
- begin
- if (GL_VERSION_1_2 or GL_EXT_bgra) then begin
- glFormat := GL_BGR;
- end else begin
- if CanConvertImage then
- ConvertTo(tfRGB8);
- glFormat := GL_RGB;
- end;
- end;
- ifBGRA8:
- begin
- if (GL_VERSION_1_2 or GL_EXT_bgra) then begin
- glFormat := GL_BGRA;
- end else begin
- if CanConvertImage then
- ConvertTo(tfRGBA8);
- glFormat := GL_RGBA;
- end;
- end;
- tfRGB8:
- glFormat := GL_RGB;
- tfRGBA8:
- glFormat := GL_RGBA;
- tfRGBA4:
- begin
- Check12;
- glFormat := GL_BGRA;
- glType := GL_UNSIGNED_SHORT_4_4_4_4_REV;
- end;
- tfRGB5A1:
- begin
- Check12;
- glFormat := GL_BGRA;
- glType := GL_UNSIGNED_SHORT_1_5_5_5_REV;
- end;
- tfRGB10A2:
- begin
- Check12;
- glFormat := GL_BGRA;
- glType := GL_UNSIGNED_INT_2_10_10_10_REV;
- end;
- ifR5G6B5:
- begin
- Check12;
- glFormat := GL_RGB;
- glType := GL_UNSIGNED_SHORT_5_6_5;
- end;
- else
- glFormat := 0;
- end;
-
- // Selecting InternalFormat
- case DataFormat of
- ifDXT1, ifDXT3, ifDXT5:
- begin
- if GL_EXT_texture_compression_s3tc then begin
- case DataFormat of
- ifDXT1:
- glInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
- ifDXT3:
- glInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
- ifDXT5:
- glInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
- end;
- end else begin
- // Compression isn't supported so convert to RGBA
- if CanConvertImage then
- ConvertTo(tfRGBA8);
- glFormat := GL_RGBA;
- glInternalFormat := GL_RGBA8;
- end;
- end;
- ifAlpha:
- begin
- case Format of
- tf4BitsPerChanel:
- glInternalFormat := GL_ALPHA4;
- tf8BitsPerChanel:
- glInternalFormat := GL_ALPHA8;
- tfCompressed:
- begin
- if (GL_ARB_texture_compression or GL_VERSION_1_3) then
- glInternalFormat := GL_COMPRESSED_ALPHA
- else
- glInternalFormat := GL_ALPHA;
- end;
- else
- glInternalFormat := GL_ALPHA;
- end;
- end;
- ifLuminance:
- begin
- case Format of
- tf4BitsPerChanel:
- glInternalFormat := GL_LUMINANCE4;
- tf8BitsPerChanel:
- glInternalFormat := GL_LUMINANCE8;
- tfCompressed:
- begin
- if (GL_ARB_texture_compression or GL_VERSION_1_3) then
- glInternalFormat := GL_COMPRESSED_LUMINANCE
- else
- glInternalFormat := GL_LUMINANCE;
- end;
- else
- glInternalFormat := GL_LUMINANCE;
- end;
- end;
- ifDepth8:
- begin
- glInternalFormat := GL_DEPTH_COMPONENT;
- end;
- ifLuminanceAlpha:
- begin
- case Format of
- tf4BitsPerChanel:
- glInternalFormat := GL_LUMINANCE4_ALPHA4;
- tf8BitsPerChanel:
- glInternalFormat := GL_LUMINANCE8_ALPHA8;
- tfCompressed:
- begin
- if (GL_ARB_texture_compression or GL_VERSION_1_3) then
- glInternalFormat := GL_COMPRESSED_LUMINANCE_ALPHA
- else
- glInternalFormat := GL_LUMINANCE_ALPHA;
- end;
- else
- glInternalFormat := GL_LUMINANCE_ALPHA;
- end;
- end;
- ifBGR8, tfRGB8:
- begin
- case Format of
- tf4BitsPerChanel:
- glInternalFormat := GL_RGB4;
- tf8BitsPerChanel:
- glInternalFormat := GL_RGB8;
- tfCompressed:
- begin
- if (GL_ARB_texture_compression or GL_VERSION_1_3) then begin
- glInternalFormat := GL_COMPRESSED_RGB
- end else begin
- if (GL_EXT_texture_compression_s3tc) then
- glInternalFormat := GL_COMPRESSED_RGB_S3TC_DXT1_EXT
- else
- glInternalFormat := GL_RGB;
- end;
- end;
- else
- glInternalFormat := GL_RGB;
- end;
- end;
- ifBGRA8, tfRGBA8, tfRGBA4, tfRGB5A1, tfRGB10A2, ifR5G6B5:
- begin
- case Format of
- tf4BitsPerChanel:
- glInternalFormat := GL_RGBA4;
- tf8BitsPerChanel:
- glInternalFormat := GL_RGBA8;
- tfCompressed:
- begin
- if (GL_ARB_texture_compression or GL_VERSION_1_3) then begin
- glInternalFormat := GL_COMPRESSED_RGBA
- end else begin
- if (GL_EXT_texture_compression_s3tc) then
- glInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
- else
- glInternalFormat := GL_RGBA;
- end;
- end;
- else
- glInternalFormat := GL_RGBA;
- end;
- end;
- end;
-end;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.LoadFromStream(const aStream: TStream);
+begin
+ {$IFDEF GLB_SUPPORT_PNG_READ}
+ if not LoadPNG(aStream) then
+ {$ENDIF}
+ {$IFDEF GLB_SUPPORT_JPEG_READ}
+ if not LoadJPEG(aStream) then
+ {$ENDIF}
+ if not LoadDDS(aStream) then
+ if not LoadTGA(aStream) then
+ if not LoadBMP(aStream) then
+ raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
+end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TglBitmap.Create;
-begin
- {$IFNDEF GLB_NO_NATIVE_GL}
- ReadOpenGLExtensions;
- {$ENDIF}
-
- if (ClassType = TglBitmap) then
- raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
-
- inherited Create;
-end;
-
-
-constructor TglBitmap.Create(FileName: String);
-begin
- Create;
- LoadFromFile(FileName);
-end;
-
-
-constructor TglBitmap.Create(Stream: TStream);
-begin
- Create;
- LoadFromStream(Stream);
-end;
-
-
-{$IFDEF GLB_DELPHI}
-constructor TglBitmap.CreateFromResourceName(Instance: Cardinal; Resource: String; ResType: PChar);
-begin
- Create;
- LoadFromResource(Instance, Resource, ResType);
-end;
-
-
-constructor TglBitmap.Create(Instance: Cardinal; Resource: String; ResType: PChar);
-begin
- Create;
- LoadFromResource(Instance, Resource, ResType);
-end;
-
-
-
-constructor TglBitmap.Create(Instance: Cardinal; ResourceID: Integer; ResType: PChar);
-begin
- Create;
- LoadFromResourceID(Instance, ResourceID, ResType);
-end;
-{$ENDIF}
-
-
-constructor TglBitmap.Create(Size: TglBitmapPixelPosition;
- Format: TglBitmapFormat);
-var
- Image: pByte;
- ImageSize: Integer;
-begin
- Create;
-
- ImageSize := FormatGetImageSize(Size, Format);
- GetMem(Image, ImageSize);
- try
- FillChar(Image^, ImageSize, #$FF);
-
- SetDataPointer(Image, Format, Size.X, Size.Y);
- except
- FreeMem(Image);
- raise;
- end;
-end;
-
-
-constructor TglBitmap.Create(Size: TglBitmapPixelPosition;
- Format: TglBitmapFormat; Func: TglBitmapFunction; CustomData: Pointer);
-begin
- Create;
- LoadFromFunc(Size, Func, Format, CustomData);
-end;
-
-
-function TglBitmap.Clone: TglBitmap;
+procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
+ const aFormat: TglBitmapFormat; const aArgs: PtrInt);
var
- Temp: TglBitmap;
- TempPtr: pByte;
- Size: Integer;
+ tmpData: PByte;
+ size: Integer;
begin
- Temp := ClassType.Create as TglBitmap;
+ size := FORMAT_DESCRIPTORS[aFormat].GetSize(aSize);
+ GetMem(tmpData, size);
try
- // copy texture data if assigned
- if Assigned(Data) then begin
- Size := FormatGetImageSize(glBitmapPosition(Width, Height), InternalFormat);
-
- GetMem(TempPtr, Size);
- try
- Move(Data^, TempPtr^, Size);
- Temp.SetDataPointer(TempPtr, InternalFormat, Width, Height);
- except
- FreeMem(TempPtr);
- raise;
- end;
- end else
- Temp.SetDataPointer(nil, InternalFormat, Width, Height);
-
- // copy properties
- Temp.fID := ID;
- Temp.fTarget := Target;
- Temp.fFormat := Format;
- Temp.fMipMap := MipMap;
- Temp.fAnisotropic := Anisotropic;
- Temp.fBorderColor := fBorderColor;
- Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
- Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
- Temp.fFilterMin := fFilterMin;
- Temp.fFilterMag := fFilterMag;
- Temp.fWrapS := fWrapS;
- Temp.fWrapT := fWrapT;
- Temp.fWrapR := fWrapR;
- Temp.fFilename := fFilename;
- Temp.fCustomName := fCustomName;
- Temp.fCustomNameW := fCustomNameW;
- Temp.fCustomDataPointer := fCustomDataPointer;
-
- Result := Temp;
+ FillChar(tmpData^, size, #$FF);
+ SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
except
- FreeAndNil(Temp);
+ FreeMem(tmpData);
raise;
end;
+ AddFunc(Self, aFunc, false, Format, aArgs);
end;
-
-procedure TglBitmap.LoadFromFile(const aFileName: String);
-var
- FS: TFileStream;
-begin
- fFilename := FileName;
-
- FS := TFileStream.Create(FileName, fmOpenRead);
- try
- FS.Position := 0;
-
- LoadFromStream(FS);
- finally
- FS.Free;
- end;
-end;
-
-
-procedure TglBitmap.LoadFromStream(const aStream: TStream);
-begin
- {$IFDEF GLB_SUPPORT_PNG_READ}
- if not LoadPNG(Stream) then
- {$ENDIF}
- {$IFDEF GLB_SUPPORT_JPEG_READ}
- if not LoadJPEG(Stream) then
- {$ENDIF}
- if not LoadDDS(Stream) then
- if not LoadTGA(Stream) then
- if not LoadBMP(Stream) then
- raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
-end;
-
-
{$IFDEF GLB_DELPHI}
-procedure TglBitmap.LoadFromResource(Instance: Cardinal; Resource: String; ResType: PChar);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
var
- RS: TResourceStream;
+ rs: TResourceStream;
TempPos: Integer;
ResTypeStr: String;
TempResType: PChar;
begin
- if Assigned(ResType) then
+ if not Assigned(ResType) then begin
+ TempPos := Pos('.', Resource);
+ ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
+ Resource := UpperCase(Copy(Resource, 0, TempPos -1));
+ TempResType := PChar(ResTypeStr);
+ end else
TempResType := ResType
- else
- begin
- TempPos := Pos('.', Resource);
- ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
- Resource := UpperCase(Copy(Resource, 0, TempPos -1));
- TempResType := PChar(ResTypeStr);
- end;
- RS := TResourceStream.Create(Instance, Resource, TempResType);
+ rs := TResourceStream.Create(Instance, Resource, TempResType);
try
- LoadFromStream(RS);
+ LoadFromStream(rs);
finally
- RS.Free;
+ rs.Free;
end;
end;
-
-procedure TglBitmap.LoadFromResourceID(Instance: Cardinal; ResourceID: Integer; ResType: PChar);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
var
- RS: TResourceStream;
+ rs: TResourceStream;
begin
- RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
+ rs := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
try
- LoadFromStream(RS);
+ LoadFromStream(rs);
finally
- RS.Free;
+ rs.Free;
end;
end;
{$ENDIF}
-
-
-procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition;
- const aFunc: TglBitmapFunction; const aFormat: TglBitmapFormat;
- const aArgs: PtrInt);
-var
- Image: pByte;
- ImageSize: Integer;
-begin
- ImageSize := FormatGetImageSize(Size, Format);
- GetMem(Image, ImageSize);
- try
- FillChar(Image^, ImageSize, #$FF);
-
- SetDataPointer(Image, Format, Size.X, Size.Y);
- except
- FreeMem(Image);
- raise;
- end;
-
- AddFunc(Self, Func, False, Format, CustomData)
-end;
-
-
-procedure TglBitmap.SaveToFile(const aFileName: String;
- const aFileType: TglBitmapFileType);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
var
- FS: TFileStream;
+ fs: TFileStream;
begin
- FS := TFileStream.Create(FileName, fmCreate);
+ fs := TFileStream.Create(aFileName, fmCreate);
try
- FS.Position := 0;
- SaveToStream(FS, FileType);
+ fs.Position := 0;
+ SaveToStream(fs, aFileType);
finally
- FS.Free;
+ fs.Free;
end;
end;
-
-procedure TglBitmap.SaveToStream(const aStream: TStream;
- const aFileType: TglBitmapFileType);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
begin
- case FileType of
+ case aFileType of
{$IFDEF GLB_SUPPORT_PNG_WRITE}
- ftPNG: SavePng(Stream);
+ ftPNG: SavePng(aStream);
{$ENDIF}
{$IFDEF GLB_SUPPORT_JPEG_WRITE}
- ftJPEG: SaveJPEG(Stream);
+ ftJPEG: SaveJPEG(aStream);
{$ENDIF}
- ftDDS: SaveDDS(Stream);
- ftTGA: SaveTGA(Stream);
- ftBMP: SaveBMP(Stream);
+ ftDDS: SaveDDS(aStream);
+ ftTGA: SaveTGA(aStream);
+ ftBMP: SaveBMP(aStream);
end;
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt): Boolean;
+begin
+ result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
+end;
-{$IFDEF GLB_SDL}
-function TglBitmap.AssignToSurface(out Surface: PSDL_Surface): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
+ const aFormat: TglBitmapFormat; const aArgs: PtrInt): Boolean;
var
- Row, RowSize: Integer;
- pSource, pData: PByte;
- TempDepth: Integer;
- Pix: TglBitmapPixelData;
-
- function GetRowPointer(Row: Integer): pByte;
- begin
- Result := Surface.pixels;
- Inc(Result, Row * RowSize);
- end;
+ DestData, TmpData, SourceData: pByte;
+ TempHeight, TempWidth: Integer;
+ SourceFD, DestFD: TglBitmapFormatDescClass;
+ FuncRec: TglBitmapFunctionRec;
begin
- Result := False;
-
- if not FormatIsUncompressed(InternalFormat) then
- raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- if Assigned(Data) then begin
- case Trunc(FormatGetSize(InternalFormat)) of
- 1: TempDepth := 8;
- 2: TempDepth := 16;
- 3: TempDepth := 24;
- 4: TempDepth := 32;
- else
- raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
- end;
-
- FormatPreparePixel(Pix, InternalFormat);
+ Assert(Assigned(Data));
+ Assert(Assigned(aSource));
+ Assert(Assigned(aSource.Data));
- with Pix.PixelDesc do
- Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth, RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
+ result := false;
+ if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
+ SourceFD := FORMAT_DESCRIPTORS[aSource.Format];
+ DestFD := FORMAT_DESCRIPTORS[aFormat];
- pSource := Data;
- RowSize := Trunc(FileWidth * FormatGetSize(InternalFormat));
+ // inkompatible Formats so CreateTemp
+ if (SourceFD.GetSize <> DestFD.GetSize) then
+ aCreateTemp := true;
- for Row := 0 to FileHeight -1 do begin
- pData := GetRowPointer(Row);
+ // Values
+ TempHeight := Max(1, aSource.Height);
+ TempWidth := Max(1, aSource.Width);
- if Assigned(pData) then begin
- Move(pSource^, pData^, RowSize);
- Inc(pSource, RowSize);
- end;
- end;
+ FuncRec.Sender := Self;
+ FuncRec.Args := aArgs;
- Result := True;
- end;
-end;
+ TmpData := nil;
+ if aCreateTemp then begin
+ GetMem(TmpData, Ceil(FORMAT_DESCRIPTORS[aFormat].GetSize * TempHeight * TempWidth));
+ DestData := TmpData;
+ end else
+ DestData := Data;
+ try
+ SourceFD.PreparePixel(FuncRec.Source);
+ DestFD.PreparePixel (FuncRec.Dest);
-function TglBitmap.AssignFromSurface(const Surface: PSDL_Surface): boolean;
-var
- pSource, pData, pTempData: PByte;
- Row, RowSize, TempWidth, TempHeight: Integer;
- IntFormat: TglBitmapInternalFormat;
+ FuncRec.Size := aSource.Dimension;
+ FuncRec.Position.Fields := FuncRec.Size.Fields;
- function GetRowPointer(Row: Integer): pByte;
- begin
- Result := Surface^.pixels;
- Inc(Result, Row * RowSize);
- end;
+ if {FormatIsUncompressed(Source.InternalFormat)} true then begin
+ SourceData := aSource.Data;
+ 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);
+ aFunc(FuncRec);
+ DestFD.Map(FuncRec.Dest, DestData);
+ inc(FuncRec.Position.X);
+ end;
+ inc(FuncRec.Position.Y);
+ end;
+ end else begin
+ (* TODO
+ // Compressed Images
+ FuncRec.Position.Y := 0;
+ while FuncRec.Position.Y < TempHeight do begin
+ FuncRec.Position.X := 0;
+ while FuncRec.Position.X < TempWidth do begin
+ // Get Data
+ fGetPixelFunc(FuncRec.Position, FuncRec.Source);
+ // Func
+ Func(FuncRec);
+ // Set Data
+ MapFunc(FuncRec.Dest, dest);
+ Inc(FuncRec.Position.X);
+ end;
+ Inc(FuncRec.Position.Y);
+ end;
+ *)
+ end;
-begin
- Result := False;
+ // Updating Image or InternalFormat
+ if aCreateTemp then
+ SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
+ else if (aFormat <> fFormat) then
+ Format := aFormat;
- if (Assigned(Surface)) then begin
- with Surface^.format^ do begin
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifLuminance) then
- IntFormat := ifLuminance
- else
+ result := true;
+ except
+ if aCreateTemp then
+ FreeMem(TmpData);
+ raise;
+ end;
+ end;
+end;
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifLuminanceAlpha) then
- IntFormat := ifLuminanceAlpha
- else
+{$IFDEF GLB_SDL}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
+var
+ Row, RowSize: Integer;
+ SourceData, TmpData: PByte;
+ TempDepth: Integer;
+ Pix: TglBitmapPixelData;
+ FormatDesc: TglBitmapFormatDescriptor;
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGBA4) then
- IntFormat := ifRGBA4
- else
+ function GetRowPointer(Row: Integer): pByte;
+ begin
+ result := Surface.pixels;
+ Inc(result, Row * RowSize);
+ end;
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifR5G6B5) then
- IntFormat := ifR5G6B5
- else
+begin
+ result := false;
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGB5A1) then
- IntFormat := ifRGB5A1
- else
+ (* TODO
+ if not FormatIsUncompressed(InternalFormat) then
+ raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ *)
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifBGR8) then
- IntFormat := ifBGR8
- else
+ FormatDesc := FORMAT_DESCRIPTORS[Format];
+ if Assigned(Data) then begin
+ case Trunc(FormatDesc.GetSize) of
+ 1: TempDepth := 8;
+ 2: TempDepth := 16;
+ 3: TempDepth := 24;
+ 4: TempDepth := 32;
+ else
+ raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ end;
+ FormatDesc.PreparePixel(Pix);
+ with Pix.PixelDesc do
+ Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
+ RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGB8) then
- IntFormat := ifRGB8
- else
+ SourceData := Data;
+ RowSize := Ceil(FileWidth * FormatDesc.GetSize);
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifBGRA8) then
- IntFormat := ifBGRA8
- else
+ for Row := 0 to FileHeight -1 do begin
+ TmpData := GetRowPointer(Row);
+ if Assigned(TmpData) then begin
+ Move(SourceData^, TmpData^, RowSize);
+ inc(SourceData, RowSize);
+ end;
+ end;
+ result := true;
+ end;
+end;
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGBA8) then
- IntFormat := ifRGBA8
- else
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
+var
+ pSource, pData, pTempData: PByte;
+ Row, RowSize, TempWidth, TempHeight: Integer;
+ IntFormat, f: TglBitmapInternalFormat;
+ FormatDesc: TglBitmapFormatDescriptor;
- if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGB10A2) then
- IntFormat := ifRGB10A2
- else
+ function GetRowPointer(Row: Integer): pByte;
+ begin
+ result := Surface^.pixels;
+ Inc(result, Row * RowSize);
+ end;
+
+begin
+ result := false;
+ if (Assigned(Surface)) then begin
+ with Surface^.format^ do begin
+ IntFormat := tfEmpty;
+ for f := Low(f) to High(f) do begin
+ if FORMAT_DESCRIPTORS[f].MaskMatch(RMask, GMask, BMask, AMask) then begin
+ IntFormat := f;
+ break;
+ end;
+ end;
+ if (IntFormat = tfEmpty) then
raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
end;
- TempWidth := Surface^.w;
+ FormatDesc := FORMAT_DESCRIPTORS[IntFormat];
+ TempWidth := Surface^.w;
TempHeight := Surface^.h;
-
- RowSize := Trunc(TempWidth * FormatGetSize(IntFormat));
-
+ RowSize := Trunc(TempWidth * FormatDesc.GetSize);
GetMem(pData, TempHeight * RowSize);
try
pTempData := pData;
-
for Row := 0 to TempHeight -1 do begin
pSource := GetRowPointer(Row);
-
if (Assigned(pSource)) then begin
Move(pSource^, pTempData^, RowSize);
Inc(pTempData, RowSize);
end;
end;
-
SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
-
- Result := True;
+ result := true;
except
FreeMem(pData);
raise;
end;
end;
-
-function TglBitmap.AssignAlphaToSurface(out Surface: PSDL_Surface): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
var
Row, Col, AlphaInterleave: Integer;
pSource, pDest: PByte;
function GetRowPointer(Row: Integer): pByte;
begin
- Result := Surface.pixels;
- Inc(Result, Row * Width);
+ result := aSurface.pixels;
+ Inc(result, Row * Width);
end;
begin
- Result := False;
-
+ result := false;
if Assigned(Data) then begin
- if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifBGRA8, ifRGBA8] then begin
- Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
+ if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
+ aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
- case InternalFormat of
- ifLuminanceAlpha:
+ AlphaInterleave := 0;
+ case Format of
+ ifLuminance8Alpha8:
AlphaInterleave := 1;
ifBGRA8, ifRGBA8:
AlphaInterleave := 3;
- else
- AlphaInterleave := 0;
end;
- // Copy Data
pSource := Data;
-
for Row := 0 to Height -1 do begin
pDest := GetRowPointer(Row);
-
if Assigned(pDest) then begin
for Col := 0 to Width -1 do begin
Inc(pSource, AlphaInterleave);
end;
end;
end;
-
- Result := True;
+ result := true;
end;
end;
end;
-
-function TglBitmap.AddAlphaFromSurface(Surface: PSDL_Surface; Func: TglBitmapFunction; CustomData: Pointer): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
var
- glBitmap: TglBitmap2D;
+ bmp: TglBitmap2D;
begin
- glBitmap := TglBitmap2D.Create;
+ bmp := TglBitmap2D.Create;
try
- glBitmap.AssignFromSurface(Surface);
-
- Result := AddAlphaFromglBitmap(glBitmap, Func, CustomData);
+ bmp.AssignFromSurface(Surface);
+ result := AddAlphaFromGlBitmap(bmp, Func, CustomData);
finally
- glBitmap.Free;
+ bmp.Free;
end;
end;
{$ENDIF}
-
{$IFDEF GLB_DELPHI}
-function TglBitmap.AssignFromBitmap(const Bitmap: TBitmap): boolean;
+//TODO rework & test
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
+var
+ Row: Integer;
+ pSource, pData: PByte;
+begin
+ result := false;
+ if Assigned(Data) then begin
+ if Assigned(aBitmap) then begin
+ aBitmap.Width := Width;
+ aBitmap.Height := Height;
+
+ case Format of
+ tfAlpha8, ifLuminance, ifDepth8:
+ begin
+ Bitmap.PixelFormat := pf8bit;
+ Bitmap.Palette := CreateGrayPalette;
+ end;
+ ifRGB5A1:
+ Bitmap.PixelFormat := pf15bit;
+ ifR5G6B5:
+ Bitmap.PixelFormat := pf16bit;
+ ifRGB8, ifBGR8:
+ Bitmap.PixelFormat := pf24bit;
+ ifRGBA8, ifBGRA8:
+ Bitmap.PixelFormat := pf32bit;
+ else
+ raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
+ end;
+
+ pSource := Data;
+ for Row := 0 to FileHeight -1 do begin
+ pData := Bitmap.Scanline[Row];
+
+ Move(pSource^, pData^, fRowSize);
+ Inc(pSource, fRowSize);
+
+ // swap RGB(A) to BGR(A)
+ if InternalFormat in [ifRGB8, ifRGBA8] then
+ SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
+ end;
+
+ result := true;
+ end;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
var
pSource, pData, pTempData: PByte;
Row, RowSize, TempWidth, TempHeight: Integer;
IntFormat: TglBitmapInternalFormat;
begin
- Result := False;
+ result := false;
if (Assigned(Bitmap)) then begin
case Bitmap.PixelFormat of
SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
- Result := True;
+ result := true;
except
FreeMem(pData);
raise;
end;
end;
-
-function TglBitmap.AssignToBitmap(const Bitmap: TBitmap): boolean;
-var
- Row: Integer;
- pSource, pData: PByte;
-begin
- Result := False;
-
- if Assigned(Data) then begin
- if Assigned(Bitmap) then begin
- Bitmap.Width := Width;
- Bitmap.Height := Height;
-
- case InternalFormat of
- ifAlpha, ifLuminance, ifDepth8:
- begin
- Bitmap.PixelFormat := pf8bit;
- Bitmap.Palette := CreateGrayPalette;
- end;
- ifRGB5A1:
- Bitmap.PixelFormat := pf15bit;
- ifR5G6B5:
- Bitmap.PixelFormat := pf16bit;
- ifRGB8, ifBGR8:
- Bitmap.PixelFormat := pf24bit;
- ifRGBA8, ifBGRA8:
- Bitmap.PixelFormat := pf32bit;
- else
- raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
- end;
-
- pSource := Data;
- for Row := 0 to FileHeight -1 do begin
- pData := Bitmap.Scanline[Row];
-
- Move(pSource^, pData^, fRowSize);
- Inc(pSource, fRowSize);
-
- // swap RGB(A) to BGR(A)
- if InternalFormat in [ifRGB8, ifRGBA8] then
- SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
- end;
-
- Result := True;
- end;
- end;
-end;
-
-
-function TglBitmap.AssignAlphaToBitmap(const Bitmap: TBitmap): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
var
Row, Col, AlphaInterleave: Integer;
pSource, pDest: PByte;
begin
- Result := False;
+ result := false;
if Assigned(Data) then begin
if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifRGBA8, ifBGRA8] then begin
end;
end;
- Result := True;
+ result := true;
end;
end;
end;
end;
-
-function TglBitmap.AddAlphaFromBitmap(Bitmap: TBitmap; Func: TglBitmapFunction; CustomData: Pointer): boolean;
-var
- glBitmap: TglBitmap2D;
-begin
- glBitmap := TglBitmap2D.Create;
- try
- glBitmap.AssignFromBitmap(Bitmap);
-
- Result := AddAlphaFromglBitmap(glBitmap, Func, CustomData);
- finally
- glBitmap.Free;
- end;
-end;
-{$ENDIF}
-
-
-function TglBitmap.AddAlphaFromFile(FileName: String; Func: TglBitmapFunction; CustomData: Pointer): boolean;
-var
- FS: TFileStream;
-begin
- FS := TFileStream.Create(FileName, fmOpenRead);
- try
- Result := AddAlphaFromStream(FS, Func, CustomData);
- finally
- FS.Free;
- end;
-end;
-
-
-function TglBitmap.AddAlphaFromStream(Stream: TStream; Func: TglBitmapFunction; CustomData: Pointer): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
var
- glBitmap: TglBitmap2D;
+ tex: TglBitmap2D;
begin
- glBitmap := TglBitmap2D.Create(Stream);
+ tex := TglBitmap2D.Create;
try
- Result := AddAlphaFromglBitmap(glBitmap, Func, CustomData);
+ tex.AssignFromBitmap(Bitmap);
+ result := AddAlphaFromglBitmap(tex, Func, CustomData);
finally
- glBitmap.Free;
+ tex.Free;
end;
end;
-
-{$IFDEF GLB_DELPHI}
-function TglBitmap.AddAlphaFromResource(Instance: Cardinal; Resource: String;
- ResType: PChar; Func: TglBitmapFunction; CustomData: Pointer): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar;
+ const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
var
RS: TResourceStream;
TempPos: Integer;
RS := TResourceStream.Create(Instance, Resource, TempResType);
try
- Result := AddAlphaFromStream(RS, Func, CustomData);
+ result := AddAlphaFromStream(RS, Func, CustomData);
finally
RS.Free;
end;
end;
-
-function TglBitmap.AddAlphaFromResourceID(Instance: Cardinal; ResourceID: Integer;
- ResType: PChar; Func: TglBitmapFunction; CustomData: Pointer): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
+ const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
var
RS: TResourceStream;
begin
RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
try
- Result := AddAlphaFromStream(RS, Func, CustomData);
+ result := AddAlphaFromStream(RS, Func, CustomData);
finally
RS.Free;
end;
end;
{$ENDIF}
-
-procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
begin
- with FuncRec do begin
- Dest.Red := Source.Red;
- Dest.Green := Source.Green;
- Dest.Blue := Source.Blue;
+ (* TODO
+ if not FormatIsUncompressed(InternalFormat) then
+ raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT);
+ *)
+ result := AddFunc(Self, aFunc, false, FORMAT_DESCRIPTORS[Format].WithAlpha, aArgs);
+end;
- with TglBitmapPixelData(CustomData^) do
- if ((Dest.Red <= Red ) and (Dest.Red >= PixelDesc.RedRange ) and
- (Dest.Green <= Green) and (Dest.Green >= PixelDesc.GreenRange) and
- (Dest.Blue <= Blue ) and (Dest.Blue >= PixelDesc.BlueRange )) then
- Dest.Alpha := 0
- else
- Dest.Alpha := Dest.PixelDesc.AlphaRange;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
+var
+ FS: TFileStream;
+begin
+ FS := TFileStream.Create(FileName, fmOpenRead);
+ try
+ result := AddAlphaFromStream(FS, aFunc, aArgs);
+ finally
+ FS.Free;
end;
end;
-
-function TglBitmap.AddAlphaFromColorKey(Red, Green, Blue: Byte; Deviation: Byte
- ): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
+var
+ tex: TglBitmap2D;
begin
- Result := AddAlphaFromColorKeyFloat(Red / $FF, Green / $FF, Blue / $FF, Deviation / $FF);
+ tex := TglBitmap2D.Create(aStream);
+ try
+ result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
+ finally
+ tex.Free;
+ end;
end;
-
-function TglBitmap.AddAlphaFromColorKeyRange(Red, Green, Blue: Cardinal; Deviation: Cardinal = 0): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
var
- PixelData: TglBitmapPixelData;
+ DestData, DestData2, SourceData: pByte;
+ TempHeight, TempWidth: Integer;
+ SourceFD, DestFD: TglBitmapFormatDescClass;
+
+ FuncRec: TglBitmapFunctionRec;
begin
- FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
+ result := false;
- Result := AddAlphaFromColorKeyFloat(
- Red / PixelData.PixelDesc.RedRange,
- Green / PixelData.PixelDesc.GreenRange,
- Blue / PixelData.PixelDesc.BlueRange,
- Deviation / Max(PixelData.PixelDesc.RedRange, Max(PixelData.PixelDesc.GreenRange, PixelData.PixelDesc.BlueRange)));
-end;
+ Assert(Assigned(Data));
+ Assert(Assigned(aBitmap));
+ Assert(Assigned(aBitmap.Data));
+ if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
+ result := ConvertTo(FORMAT_DESCRIPTORS[Format].WithAlpha);
+ if not Assigned(aFunc) then
+ aFunc := glBitmapAlphaFunc;
-function TglBitmap.AddAlphaFromColorKeyFloat(Red, Green, Blue: Single; Deviation: Single = 0): Boolean;
-var
- TempR, TempG, TempB: Cardinal;
- PixelData: TglBitmapPixelData;
-begin
- FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
+ SourceFD := FORMAT_DESCRIPTORS[aBitmap.Format];
+ DestFD := FORMAT_DESCRIPTORS[Format];
- // Calculate Colorrange
- with PixelData.PixelDesc do begin
- TempR := Trunc(RedRange * Deviation);
- TempG := Trunc(GreenRange * Deviation);
- TempB := Trunc(BlueRange * Deviation);
-
- PixelData.Red := Min(RedRange, Trunc(RedRange * Red) + TempR);
- RedRange := Max(0, Trunc(RedRange * Red) - TempR);
- PixelData.Green := Min(GreenRange, Trunc(GreenRange * Green) + TempG);
- GreenRange := Max(0, Trunc(GreenRange * Green) - TempG);
- PixelData.Blue := Min(BlueRange, Trunc(BlueRange * Blue) + TempB);
- BlueRange := Max(0, Trunc(BlueRange * Blue) - TempB);
- PixelData.Alpha := 0;
- AlphaRange := 0;
- end;
+ // Values
+ TempHeight := aBitmap.FileHeight;
+ TempWidth := aBitmap.FileWidth;
- Result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
-end;
+ FuncRec.Sender := Self;
+ FuncRec.Args := aArgs;
+ FuncRec.Size := Dimension;
+ FuncRec.Position.Fields := FuncRec.Size.Fields;
+ FuncRec.Args := PtrInt(SourceFD.HasAlpha) and 1;
+ DestData := Data;
+ DestData2 := Data;
+ SourceData := aBitmap.Data;
-procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
-begin
- with FuncRec do begin
- Dest.Red := Source.Red;
- Dest.Green := Source.Green;
- Dest.Blue := Source.Blue;
+ // Mapping
+ SourceFD.PreparePixel(FuncRec.Source);
+ DestFD.PreparePixel (FuncRec.Dest);
- with TglBitmapPixelData(CustomData^) do
- Dest.Alpha := Alpha;
+ 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);
+ DestFD.Unmap (DestData, FuncRec.Dest);
+ aFunc(FuncRec);
+ DestFD.Map(FuncRec.Dest, DestData2);
+ inc(FuncRec.Position.X);
+ end;
+ inc(FuncRec.Position.Y);
+ end;
end;
end;
-function TglBitmap.AddAlphaFromValue(Alpha: Byte): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
begin
- Result := AddAlphaFromValueFloat(Alpha / $FF);
+ result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
end;
-
-function TglBitmap.AddAlphaFromValueFloat(Alpha: Single): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
var
PixelData: TglBitmapPixelData;
begin
- FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
-
- with PixelData.PixelDesc do
- PixelData.Alpha := Min(AlphaRange, Max(0, Round(AlphaRange * Alpha)));
+ FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+ result := AddAlphaFromColorKeyFloat(
+ aRed / PixelData.PixelDesc.RedRange,
+ aGreen / PixelData.PixelDesc.GreenRange,
+ aBlue / PixelData.PixelDesc.BlueRange,
+ aDeviation / Max(PixelData.PixelDesc.RedRange, Max(PixelData.PixelDesc.GreenRange, PixelData.PixelDesc.BlueRange)));
+end;
- Result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
+var
+ TempR, TempG, TempB: Cardinal;
+ PixelData: TglBitmapPixelData;
+begin
+ FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+ with PixelData.PixelDesc do begin
+ TempR := Trunc(RedRange * aDeviation);
+ TempG := Trunc(GreenRange * aDeviation);
+ TempB := Trunc(BlueRange * aDeviation);
+
+ PixelData.Red := Min(RedRange, Trunc(RedRange * aRed) + TempR);
+ RedRange := Max(0, Trunc(RedRange * aRed) - TempR);
+ PixelData.Green := Min(GreenRange, Trunc(GreenRange * aGreen) + TempG);
+ GreenRange := Max(0, Trunc(GreenRange * aGreen) - TempG);
+ PixelData.Blue := Min(BlueRange, Trunc(BlueRange * aBlue) + TempB);
+ BlueRange := Max(0, Trunc(BlueRange * aBlue) - TempB);
+ PixelData.Alpha := 0;
+ AlphaRange := 0;
+ end;
+ result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData));
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
+begin
+ result := AddAlphaFromValueFloat(aAlpha / $FF);
+end;
-function TglBitmap.AddAlphaFromValueRange(Alpha: Cardinal): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
var
PixelData: TglBitmapPixelData;
begin
- FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
+ FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+ result := AddAlphaFromValueFloat(aAlpha / PixelData.PixelDesc.AlphaRange);
+end;
- Result := AddAlphaFromValueFloat(Alpha / PixelData.PixelDesc.AlphaRange);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
+var
+ PixelData: TglBitmapPixelData;
+begin
+ FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+ with PixelData.PixelDesc do
+ PixelData.Alpha := Min(AlphaRange, Max(0, Round(AlphaRange * aAlpha)));
+ result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData));
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.RemoveAlpha: Boolean;
+var
+ FormatDesc: TglBitmapFormatDescClass;
+begin
+ result := false;
+ FormatDesc := FORMAT_DESCRIPTORS[Format];
+ if Assigned(Data) then begin
+ if not ({FormatDesc.IsUncompressed or }FormatDesc.HasAlpha) then
+ raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT);
+ result := ConvertTo(FormatDesc.WithoutAlpha);
+ end;
+end;
-procedure glBitmapInvertFunc(var FuncRec: TglBitmapFunctionRec);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.Clone: TglBitmap;
+var
+ Temp: TglBitmap;
+ TempPtr: PByte;
+ Size: Integer;
begin
- with FuncRec do begin
- Dest.Red := Source.Red;
- Dest.Green := Source.Green;
- Dest.Blue := Source.Blue;
- Dest.Alpha := Source.Alpha;
+ result := nil;
+ Temp := (ClassType.Create as TglBitmap);
+ try
+ // copy texture data if assigned
+ if Assigned(Data) then begin
+ Size := FORMAT_DESCRIPTORS[Format].GetSize(fDimension);
+ GetMem(TempPtr, Size);
+ try
+ Move(Data^, TempPtr^, Size);
+ Temp.SetDataPointer(TempPtr, Format, Width, Height);
+ except
+ FreeMem(TempPtr);
+ raise;
+ end;
+ end else
+ Temp.SetDataPointer(nil, Format, Width, Height);
- if (Integer(CustomData) and $1 > 0) then begin
- Dest.Red := Dest.Red xor Dest.PixelDesc.RedRange;
- Dest.Green := Dest.Green xor Dest.PixelDesc.GreenRange;
- Dest.Blue := Dest.Blue xor Dest.PixelDesc.BlueRange;
- end;
+ // copy properties
+ Temp.fID := ID;
+ Temp.fTarget := Target;
+ Temp.fFormat := Format;
+ Temp.fMipMap := MipMap;
+ Temp.fAnisotropic := Anisotropic;
+ Temp.fBorderColor := fBorderColor;
+ Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
+ Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
+ Temp.fFilterMin := fFilterMin;
+ Temp.fFilterMag := fFilterMag;
+ Temp.fWrapS := fWrapS;
+ Temp.fWrapT := fWrapT;
+ Temp.fWrapR := fWrapR;
+ Temp.fFilename := fFilename;
+ Temp.fCustomName := fCustomName;
+ Temp.fCustomNameW := fCustomNameW;
+ Temp.fCustomData := fCustomData;
+
+ result := Temp;
+ except
+ FreeAndNil(Temp);
+ raise;
+ end;
+end;
- if (Integer(CustomData) and $2 > 0) then begin
- Dest.Alpha := Dest.Alpha xor Dest.PixelDesc.AlphaRange;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
+var
+ SourceFD, DestFD: TglBitmapFormatDescClass;
+ SourcePD, DestPD: TglBitmapPixelData;
+ PixelDesc: TglBitmapPixelDesc;
+
+ function CanCopyDirect: Boolean;
+ begin
+ result :=
+ ((SourcePD.PixelDesc.RedRange = DestPD.PixelDesc.RedRange) or (SourcePD.PixelDesc.RedRange = 0) or (DestPD.PixelDesc.RedRange = 0)) and
+ ((SourcePD.PixelDesc.GreenRange = DestPD.PixelDesc.GreenRange) or (SourcePD.PixelDesc.GreenRange = 0) or (DestPD.PixelDesc.GreenRange = 0)) and
+ ((SourcePD.PixelDesc.BlueRange = DestPD.PixelDesc.BlueRange) or (SourcePD.PixelDesc.BlueRange = 0) or (DestPD.PixelDesc.BlueRange = 0)) and
+ ((SourcePD.PixelDesc.AlphaRange = DestPD.PixelDesc.AlphaRange) or (SourcePD.PixelDesc.AlphaRange = 0) or (DestPD.PixelDesc.AlphaRange = 0));
+ end;
+
+ function CanShift: Boolean;
+ begin
+ result :=
+ ((SourcePD.PixelDesc.RedRange >= DestPD.PixelDesc.RedRange ) or (SourcePD.PixelDesc.RedRange = 0) or (DestPD.PixelDesc.RedRange = 0)) and
+ ((SourcePD.PixelDesc.GreenRange >= DestPD.PixelDesc.GreenRange) or (SourcePD.PixelDesc.GreenRange = 0) or (DestPD.PixelDesc.GreenRange = 0)) and
+ ((SourcePD.PixelDesc.BlueRange >= DestPD.PixelDesc.BlueRange ) or (SourcePD.PixelDesc.BlueRange = 0) or (DestPD.PixelDesc.BlueRange = 0)) and
+ ((SourcePD.PixelDesc.AlphaRange >= DestPD.PixelDesc.AlphaRange) or (SourcePD.PixelDesc.AlphaRange = 0) or (DestPD.PixelDesc.AlphaRange = 0));
+ end;
+
+ function GetShift(aSource, aDest: Cardinal) : ShortInt;
+ begin
+ result := 0;
+ while (aSource > aDest) and (aSource > 0) do begin
+ inc(result);
+ aSource := aSource shr 1;
end;
end;
+
+begin
+ if aFormat <> fFormat then begin
+ SourceFD := FORMAT_DESCRIPTORS[Format];
+ DestFD := FORMAT_DESCRIPTORS[aFormat];
+
+ SourceFD.PreparePixel(SourcePD);
+ DestFD.PreparePixel (DestPD);
+
+ if CanCopyDirect then
+ result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
+ else if CanShift then begin
+ PixelDesc.RedShift := GetShift(SourcePD.PixelDesc.RedRange, DestPD.PixelDesc.RedRange);
+ PixelDesc.GreenShift := GetShift(SourcePD.PixelDesc.GreenRange, DestPD.PixelDesc.GreenRange);
+ PixelDesc.BlueShift := GetShift(SourcePD.PixelDesc.BlueRange, DestPD.PixelDesc.BlueRange);
+ PixelDesc.AlphaShift := GetShift(SourcePD.PixelDesc.AlphaRange, DestPD.PixelDesc.AlphaRange);
+ result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@PixelDesc));
+ end else
+ result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
+ end else
+ result := true;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
+begin
+ if aUseRGB or aUseAlpha then
+ AddFunc(glBitmapInvertFunc, false, ((PtrInt(aUseAlpha) and 1) shl 1) or (PtrInt(aUseRGB) and 1));
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+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;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.FreeData;
+begin
+ SetDataPointer(nil, tfEmpty);
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
+ const aAlpha: Byte);
+begin
+ FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
+end;
-procedure TglBitmap.Invert(UseRGB: Boolean; UseAlpha: Boolean);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
+var
+ PixelData: TglBitmapPixelData;
begin
- if ((UseRGB) or (UseAlpha)) then
- AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha) shl 1 or Integer(UseRGB)));
+ FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+ FillWithColorFloat(
+ aRed / PixelData.PixelDesc.RedRange,
+ aGreen / PixelData.PixelDesc.GreenRange,
+ aBlue / PixelData.PixelDesc.BlueRange,
+ aAlpha / PixelData.PixelDesc.AlphaRange);
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
+var
+ PixelData: TglBitmapPixelData;
+begin
+ FORMAT_DESCRIPTORS[Format].PreparePixel(PixelData);
+ PixelData.Red := Max(0, Min(PixelData.PixelDesc.RedRange, Trunc(PixelData.PixelDesc.RedRange * aRed)));
+ PixelData.Green := Max(0, Min(PixelData.PixelDesc.GreenRange, Trunc(PixelData.PixelDesc.GreenRange * aGreen)));
+ PixelData.Blue := Max(0, Min(PixelData.PixelDesc.BlueRange, Trunc(PixelData.PixelDesc.BlueRange * aBlue)));
+ PixelData.Alpha := Max(0, Min(PixelData.PixelDesc.AlphaRange, Trunc(PixelData.PixelDesc.AlphaRange * aAlpha)));
+ AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData));
+end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
begin
- case Min of
+ //check MIN filter
+ case aMin of
GL_NEAREST:
fFilterMin := GL_NEAREST;
GL_LINEAR:
GL_LINEAR_MIPMAP_LINEAR:
fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
else
- raise EglBitmapException.Create('SetFilter - Unknow Minfilter.');
+ raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
end;
- case Mag of
+ //check MAG filter
+ case aMag of
GL_NEAREST:
fFilterMag := GL_NEAREST;
GL_LINEAR:
fFilterMag := GL_LINEAR;
else
- raise EglBitmapException.Create('SetFilter - Unknow Magfilter.');
+ raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
end;
- // If texture is created then assign filter
- if ID > 0 then begin
- Bind(False);
-
+ //apply filter
+ if (ID > 0) then begin
+ Bind(false);
glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
- if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE_ARB) then begin
+ if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
case fFilterMin of
GL_NEAREST, GL_LINEAR:
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
end;
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
-procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal;
- const R: Cardinal);
-begin
- case S of
- GL_CLAMP:
- fWrapS := GL_CLAMP;
- GL_REPEAT:
- fWrapS := GL_REPEAT;
- GL_CLAMP_TO_EDGE:
- begin
+ procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
+ begin
+ case aValue of
+ GL_CLAMP:
+ aTarget := GL_CLAMP;
+
+ GL_REPEAT:
+ aTarget := GL_REPEAT;
+
+ GL_CLAMP_TO_EDGE: begin
if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
- fWrapS := GL_CLAMP_TO_EDGE
+ aTarget := GL_CLAMP_TO_EDGE
else
- fWrapS := GL_CLAMP;
+ aTarget := GL_CLAMP;
end;
- GL_CLAMP_TO_BORDER:
- begin
+
+ GL_CLAMP_TO_BORDER: begin
if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
- fWrapS := GL_CLAMP_TO_BORDER
+ aTarget := GL_CLAMP_TO_BORDER
else
- fWrapS := GL_CLAMP;
+ aTarget := GL_CLAMP;
end;
- GL_MIRRORED_REPEAT:
- begin
+
+ GL_MIRRORED_REPEAT: begin
if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
- fWrapS := GL_MIRRORED_REPEAT
+ aTarget := GL_MIRRORED_REPEAT
else
raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
end;
else
raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
+ end;
end;
- case T of
- GL_CLAMP:
- fWrapT := GL_CLAMP;
- GL_REPEAT:
- fWrapT := GL_REPEAT;
- GL_CLAMP_TO_EDGE:
- begin
- if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
- fWrapT := GL_CLAMP_TO_EDGE
- else
- fWrapT := GL_CLAMP;
- end;
- GL_CLAMP_TO_BORDER:
- begin
- if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
- fWrapT := GL_CLAMP_TO_BORDER
- else
- fWrapT := GL_CLAMP;
- end;
- GL_MIRRORED_REPEAT:
- begin
- if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
- fWrapT := GL_MIRRORED_REPEAT
- else
- raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (T).');
- end;
- else
- raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (T).');
- end;
-
- case R of
- GL_CLAMP:
- fWrapR := GL_CLAMP;
- GL_REPEAT:
- fWrapR := GL_REPEAT;
- GL_CLAMP_TO_EDGE:
- begin
- if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
- fWrapR := GL_CLAMP_TO_EDGE
- else
- fWrapR := GL_CLAMP;
- end;
- GL_CLAMP_TO_BORDER:
- begin
- if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
- fWrapR := GL_CLAMP_TO_BORDER
- else
- fWrapR := GL_CLAMP;
- end;
- GL_MIRRORED_REPEAT:
- begin
- if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
- fWrapR := GL_MIRRORED_REPEAT
- else
- raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (R).');
- end;
- else
- raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (R).');
- end;
+begin
+ CheckAndSetWrap(S, fWrapS);
+ CheckAndSetWrap(T, fWrapT);
+ CheckAndSetWrap(R, fWrapR);
- if ID > 0 then begin
- Bind (False);
+ if (ID > 0) then begin
+ Bind(false);
glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
end;
end;
-
-procedure TglBitmap.SetDataPointer(NewData: pByte;
- Format: TglBitmapFormat; Width: Integer; Height: Integer);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);
begin
- // Data
- if Data <> NewData then begin
- if (Assigned(Data))
- then FreeMem(Data);
+ { TODO delete?
+ if Assigned (fGetPixelFunc) then
+ fGetPixelFunc(aPos, aPixel);
+ }
+end;
- fData := NewData;
- end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData);
+begin
+ {TODO delete?
+ if Assigned (fSetPixelFunc) then
+ fSetPixelFuc(aPos, aPixel);
+ }
+end;
- if Data = nil then begin
- fInternalFormat := ifEmpty;
- fPixelSize := 0;
- fRowSize := 0;
- end else begin
- if Width <> -1 then begin
- fDimension.Fields := fDimension.Fields + [ffX];
- fDimension.X := Width;
- end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
+begin
+ if aEnableTextureUnit then
+ glEnable(Target);
+ if (ID > 0) then
+ glBindTexture(Target, ID);
+end;
- if Height <> -1 then begin
- fDimension.Fields := fDimension.Fields + [ffY];
- fDimension.Y := Height;
- end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
+begin
+ if aDisableTextureUnit then
+ glDisable(Target);
+ glBindTexture(Target, 0);
+end;
- fInternalFormat := Format;
- fPixelSize := Trunc(FormatGetSize(InternalFormat));
- fRowSize := Trunc(FormatGetSize(InternalFormat) * Self.Width);
- end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create;
+begin
+{$IFNDEF GLB_NO_NATIVE_GL}
+ ReadOpenGLExtensions;
+{$ENDIF}
+ if (ClassType = TglBitmap) then
+ raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
+ inherited Create;
end;
-{$IFDEF GLB_SUPPORT_PNG_READ}
-{$IFDEF GLB_LIB_PNG}
-procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aFileName: String);
begin
- TStream(png_get_io_ptr(png)).Read(buffer^, size);
+ Create;
+ LoadFromFile(FileName);
end;
-{$ENDIF}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aStream: TStream);
+begin
+ Create;
+ LoadFromStream(aStream);
+end;
-function TglBitmap.LoadPNG(Stream: TStream): Boolean;
-{$IFDEF GLB_SDL_IMAGE}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
var
- Surface: PSDL_Surface;
- RWops: PSDL_RWops;
+ Image: PByte;
+ ImageSize: Integer;
begin
- Result := False;
-
- RWops := glBitmapCreateRWops(Stream);
+ Create;
+ ImageSize := FORMAT_DESCRIPTORS[aFormat].GetSize(aSize);
+ GetMem(Image, ImageSize);
try
- if IMG_isPNG(RWops) > 0 then begin
- Surface := IMG_LoadPNG_RW(RWops);
- try
- AssignFromSurface(Surface);
- Result := True;
- finally
- SDL_FreeSurface(Surface);
- end;
- end;
- finally
- SDL_FreeRW(RWops);
+ FillChar(Image^, ImageSize, #$FF);
+ SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
+ except
+ FreeMem(Image);
+ raise;
end;
end;
-{$ENDIF}
-{$IFDEF GLB_LIB_PNG}
-var
- StreamPos: Int64;
- signature: array [0..7] of byte;
- png: png_structp;
- png_info: png_infop;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
+ const aFunc: TglBitmapFunction; const aArgs: PtrInt);
+begin
+ Create;
+ LoadFromFunc(aSize, aFunc, aFormat, aArgs);
+end;
+
+{$IFDEF GLB_DELPHI}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
+begin
+ Create;
+ LoadFromResource(aInstance, aResource, aResType);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
+begin
+ Create;
+ LoadFromResourceID(aInstance, aResourceID, aResType);
+end;
+{$ENDIF}
+
+{$IFDEF GLB_SUPPORT_PNG_READ}
+{$IF DEFINED(GLB_SDL_IMAGE)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
+var
+ Surface: PSDL_Surface;
+ RWops: PSDL_RWops;
+begin
+ result := false;
+ RWops := glBitmapCreateRWops(aStream);
+ try
+ if IMG_isPNG(RWops) > 0 then begin
+ Surface := IMG_LoadPNG_RW(RWops);
+ try
+ AssignFromSurface(Surface);
+ Rresult := true;
+ finally
+ SDL_FreeSurface(Surface);
+ end;
+ end;
+ finally
+ SDL_FreeRW(RWops);
+ end;
+end;
+
+{$ELSEIF DEFINED(GLB_LIB_PNG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
+begin
+ TStream(png_get_io_ptr(png)).Read(buffer^, size);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
+var
+ StreamPos: Int64;
+ signature: array [0..7] of byte;
+ png: png_structp;
+ png_info: png_infop;
TempHeight, TempWidth: Integer;
Format: TglBitmapInternalFormat;
png_rows: array of pByte;
Row, LineSize: Integer;
begin
- Result := False;
+ result := false;
if not init_libPNG then
raise Exception.Create('LoadPNG - unable to initialize libPNG.');
// format
case png_get_color_type(png, png_info) of
PNG_COLOR_TYPE_GRAY:
- Format := ifLuminance;
+ Format := tfLuminance8;
PNG_COLOR_TYPE_GRAY_ALPHA:
- Format := ifLuminanceAlpha;
+ Format := tfLuminance8Alpha8;
PNG_COLOR_TYPE_RGB:
- Format := ifRGB8;
+ Format := tfRGB8;
PNG_COLOR_TYPE_RGB_ALPHA:
- Format := ifRGBA8;
+ Format := tfRGBA8;
else
raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
end;
// set new data
SetDataPointer(png_data, Format, TempWidth, TempHeight);
- Result := True;
+ result := true;
except
FreeMem(png_data);
raise;
quit_libPNG;
end;
end;
-{$ENDIF}
-{$IFDEF GLB_PNGIMAGE}
+
+{$ELSEIF DEFINED(GLB_PNGIMAGE)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
var
StreamPos: Int64;
Png: TPNGObject;
PngHeader: Array[0..7] of Byte = (#137, #80, #78, #71, #13, #10, #26, #10);
begin
- Result := False;
+ result := false;
StreamPos := Stream.Position;
Stream.Read(Header[0], SizeOf(Header));
SetDataPointer(NewImage, Format, Png.Header.Width, Png.Header.Height);
- Result := True;
+ result := true;
except
FreeMem(NewImage);
raise;
end;
end;
end;
+{$IFEND}
{$ENDIF}
+
+{$IFDEF GLB_SUPPORT_PNG_WRITE}
+{$IFDEF GLB_LIB_PNG}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
+begin
+ TStream(png_get_io_ptr(png)).Write(buffer^, size);
+end;
{$ENDIF}
+{$IF DEFINED(GLB_LIB_PNG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SavePNG(const aStream: TStream);
+var
+ png: png_structp;
+ png_info: png_infop;
+ png_rows: array of pByte;
+ LineSize: Integer;
+ ColorType: Integer;
+ Row: Integer;
+begin
+ if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
+ raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+
+ if not init_libPNG then
+ raise Exception.Create('SavePNG - unable to initialize libPNG.');
+
+ try
+ case FInternalFormat of
+ ifAlpha, ifLuminance, ifDepth8:
+ ColorType := PNG_COLOR_TYPE_GRAY;
+ ifLuminanceAlpha:
+ ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
+ ifBGR8, ifRGB8:
+ ColorType := PNG_COLOR_TYPE_RGB;
+ ifBGRA8, ifRGBA8:
+ ColorType := PNG_COLOR_TYPE_RGBA;
+ else
+ raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ end;
+ LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
+
+ // creating array for scanline
+ SetLength(png_rows, Height);
+ try
+ for Row := 0 to Height - 1 do begin
+ png_rows[Row] := Data;
+ Inc(png_rows[Row], Row * LineSize)
+ end;
+
+ // write struct
+ png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
+ if png = nil then
+ raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
+
+ // create png info
+ png_info := png_create_info_struct(png);
+ if png_info = nil then begin
+ png_destroy_write_struct(@png, nil);
+ raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
+ end;
+
+ // set read callback
+ png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
+
+ // set compression
+ png_set_compression_level(png, 6);
+
+ if InternalFormat in [ifBGR8, ifBGRA8] then
+ png_set_bgr(png);
+
+ png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ png_write_info(png, png_info);
+ png_write_image(png, @png_rows[0]);
+ png_write_end(png, png_info);
+ png_destroy_write_struct(@png, @png_info);
+ finally
+ SetLength(png_rows, 0);
+ end;
+ finally
+ quit_libPNG;
+ end;
+end;
+
+{$ELSEIF DEFINED(GLB_PNGIMAGE)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SavePNG(const aStream: TStream);
+var
+ Png: TPNGObject;
+
+ pSource, pDest: pByte;
+ X, Y, PixSize: Integer;
+ ColorType: Cardinal;
+ Alpha: Boolean;
+
+ pTemp: pByte;
+ Temp: Byte;
+begin
+ if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
+ raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+
+ case FInternalFormat of
+ ifAlpha, ifLuminance, ifDepth8: begin
+ ColorType := COLOR_GRAYSCALE;
+ PixSize := 1;
+ Alpha := false;
+ end;
+ ifLuminanceAlpha: begin
+ ColorType := COLOR_GRAYSCALEALPHA;
+ PixSize := 1;
+ Alpha := true;
+ end;
+ ifBGR8, ifRGB8: begin
+ ColorType := COLOR_RGB;
+ PixSize := 3;
+ Alpha := false;
+ end;
+ ifBGRA8, ifRGBA8: begin
+ ColorType := COLOR_RGBALPHA;
+ PixSize := 3;
+ Alpha := true
+ end;
+ else
+ raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ end;
+
+ Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
+ try
+ // Copy ImageData
+ pSource := Data;
+ for Y := 0 to Height -1 do begin
+ pDest := png.ScanLine[Y];
+ for X := 0 to Width -1 do begin
+ Move(pSource^, pDest^, PixSize);
+ Inc(pDest, PixSize);
+ Inc(pSource, PixSize);
+ if Alpha then begin
+ png.AlphaScanline[Y]^[X] := pSource^;
+ Inc(pSource);
+ end;
+ end;
+
+ // convert RGB line to BGR
+ if InternalFormat in [ifRGB8, ifRGBA8] then begin
+ pTemp := png.ScanLine[Y];
+ for X := 0 to Width -1 do begin
+ Temp := pByteArray(pTemp)^[0];
+ pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
+ pByteArray(pTemp)^[2] := Temp;
+ Inc(pTemp, 3);
+ end;
+ end;
+ end;
+
+ // Save to Stream
+ Png.CompressionLevel := 6;
+ Png.SaveToStream(Stream);
+ finally
+ FreeAndNil(Png);
+ end;
+end;
+{$IFEND}
+{$ENDIF}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{$IFDEF GLB_LIB_JPEG}
type
glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
SrcBuffer: array [1..4096] of byte;
end;
-
glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
glBitmap_libJPEG_dest_mgr = record
pub: jpeg_destination_mgr;
DestBuffer: array [1..4096] of byte;
end;
-
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
-//var
-// Msg: String;
+var
+ Msg: String;
begin
-// SetLength(Msg, 256);
-// cinfo^.err^.format_message(cinfo, pChar(Msg));
-
-// Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
-
-// cinfo^.global_state := 0;
-
-// jpeg_abort(cinfo);
+ SetLength(Msg, 256);
+ cinfo^.err^.format_message(cinfo, pChar(Msg));
+ Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
+ cinfo^.global_state := 0;
+ jpeg_abort(cinfo);
end;
+}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
-//var
-// Msg: String;
+var
+ Msg: String;
begin
-// SetLength(Msg, 256);
-// cinfo^.err^.format_message(cinfo, pChar(Msg));
-
-// Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
-
-// cinfo^.global_state := 0;
+ SetLength(Msg, 256);
+ cinfo^.err^.format_message(cinfo, pChar(Msg));
+ Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
+ cinfo^.global_state := 0;
end;
+}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
begin
end;
+}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
var
src: glBitmap_libJPEG_source_mgr_ptr;
result := true;
end;
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
var
src: glBitmap_libJPEG_source_mgr_ptr;
end;
end;
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
begin
end;
+}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
begin
end;
+}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
var
dest: glBitmap_libJPEG_dest_mgr_ptr;
dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
end;
- Result := True;
+ result := true;
end;
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
var
Idx: Integer;
dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
// leave
- Break;
+ break;
end else
dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
end;
end;
{$ENDIF}
-
{$IFDEF GLB_SUPPORT_JPEG_READ}
-function TglBitmap.LoadJPEG(Stream: TStream): Boolean;
-{$IFDEF GLB_SDL_IMAGE}
+{$IF DEFINED(GLB_SDL_IMAGE)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
var
Surface: PSDL_Surface;
RWops: PSDL_RWops;
begin
- Result := False;
+ result := false;
RWops := glBitmapCreateRWops(Stream);
try
Surface := IMG_LoadJPG_RW(RWops);
try
AssignFromSurface(Surface);
- Result := True;
+ result := true;
finally
SDL_FreeSurface(Surface);
end;
SDL_FreeRW(RWops);
end;
end;
-{$ENDIF}
-{$IFDEF GLB_LIB_JPEG}
+
+{$ELSEIF DEFINED(GLB_LIB_JPEG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
var
StreamPos: Int64;
Temp: array[0..1]of Byte;
pTemp: pByte;
Row: Integer;
begin
- Result := False;
+ result := false;
if not init_libJPEG then
raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
jpeg.global_state := DSTATE_START;
// read header of jpeg
- jpeg_read_header(@jpeg, False);
+ jpeg_read_header(@jpeg, false);
// setting output parameter
case jpeg.jpeg_color_space of
SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
- Result := True;
+ result := true;
except
FreeMem(pImage);
raise;
quit_libJPEG;
end;
end;
-{$ENDIF}
-{$IFDEF GLB_DELPHI_JPEG}
+
+{$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
var
bmp: TBitmap;
jpg: TJPEGImage;
StreamPos: Int64;
Temp: array[0..1]of Byte;
begin
- Result := False;
+ result := false;
// reading first two bytes to test file and set cursor back to begin
StreamPos := Stream.Position;
try
jpg.LoadFromStream(Stream);
bmp.Assign(jpg);
- Result := AssignFromBitmap(bmp);
+ result := AssignFromBitmap(bmp);
finally
jpg.Free;
end;
end;
end;
end;
+{$IFEND}
{$ENDIF}
-{$ENDIF}
-
-
-const
- BMP_MAGIC = $4D42;
- BMP_COMP_RGB = 0;
- BMP_COMP_RLE8 = 1;
- BMP_COMP_RLE4 = 2;
- BMP_COMP_BITFIELDS = 3;
+{$IFDEF GLB_SUPPORT_JPEG_WRITE}
+{$IF DEFEFINED(GLB_LIB_JPEG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveJPEG(Stream: TStream);
+var
+ jpeg: jpeg_compress_struct;
+ jpeg_err: jpeg_error_mgr;
+ Row: Integer;
+ pTemp, pTemp2: pByte;
-type
- TBMPHeader = packed record
+ procedure CopyRow(pDest, pSource: pByte);
+ var
+ X: Integer;
+ begin
+ for X := 0 to Width - 1 do begin
+ pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
+ pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
+ pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
+ Inc(pDest, 3);
+ Inc(pSource, 3);
+ end;
+ end;
+
+begin
+ if not (ftJPEG in FormatGetSupportedFiles(Format)) then
+ raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
+
+ if not init_libJPEG then
+ raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
+
+ try
+ FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
+ FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
+
+ // error managment
+ jpeg.err := jpeg_std_error(@jpeg_err);
+ jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
+ jpeg_err.output_message := glBitmap_libJPEG_output_message;
+
+ // compression struct
+ jpeg_create_compress(@jpeg);
+
+ // allocation space for streaming methods
+ jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
+
+ // seeting up custom functions
+ with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
+ pub.init_destination := glBitmap_libJPEG_init_destination;
+ pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
+ pub.term_destination := glBitmap_libJPEG_term_destination;
+
+ pub.next_output_byte := @DestBuffer[1];
+ pub.free_in_buffer := Length(DestBuffer);
+
+ DestStream := Stream;
+ end;
+
+ // very important state
+ jpeg.global_state := CSTATE_START;
+ jpeg.image_width := Width;
+ jpeg.image_height := Height;
+ case InternalFormat of
+ ifAlpha, ifLuminance, ifDepth8: begin
+ jpeg.input_components := 1;
+ jpeg.in_color_space := JCS_GRAYSCALE;
+ end;
+ ifRGB8, ifBGR8: begin
+ jpeg.input_components := 3;
+ jpeg.in_color_space := JCS_RGB;
+ end;
+ end;
+
+ jpeg_set_defaults(@jpeg);
+ jpeg_set_quality(@jpeg, 95, true);
+ jpeg_start_compress(@jpeg, true);
+ pTemp := Data;
+
+ if InternalFormat = ifBGR8 then
+ GetMem(pTemp2, fRowSize)
+ else
+ pTemp2 := pTemp;
+
+ try
+ for Row := 0 to jpeg.image_height -1 do begin
+ // prepare row
+ if InternalFormat = ifBGR8 then
+ CopyRow(pTemp2, pTemp)
+ else
+ pTemp2 := pTemp;
+
+ // write row
+ jpeg_write_scanlines(@jpeg, @pTemp2, 1);
+ inc(pTemp, fRowSize);
+ end;
+ finally
+ // free memory
+ if InternalFormat = ifBGR8 then
+ FreeMem(pTemp2);
+ end;
+ jpeg_finish_compress(@jpeg);
+ jpeg_destroy_compress(@jpeg);
+ finally
+ quit_libJPEG;
+ end;
+end;
+
+{$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveJPEG(Stream: TStream);
+var
+ Bmp: TBitmap;
+ Jpg: TJPEGImage;
+begin
+ if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
+ raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
+
+ Bmp := TBitmap.Create;
+ try
+ Jpg := TJPEGImage.Create;
+ try
+ AssignToBitmap(Bmp);
+ if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
+ Jpg.Grayscale := true;
+ Jpg.PixelFormat := jf8Bit;
+ end;
+ Jpg.Assign(Bmp);
+ Jpg.SaveToStream(Stream);
+ finally
+ FreeAndNil(Jpg);
+ end;
+ finally
+ FreeAndNil(Bmp);
+ end;
+end;
+{$ENDIF}
+{$ENDIF}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+const
+ BMP_MAGIC = $4D42;
+
+ BMP_COMP_RGB = 0;
+ BMP_COMP_RLE8 = 1;
+ BMP_COMP_RLE4 = 2;
+ BMP_COMP_BITFIELDS = 3;
+
+type
+ TBMPHeader = packed record
bfType: Word;
bfSize: Cardinal;
bfReserved1: Word;
// TBMPPalette = record
// case Boolean of
-// True : (Colors: array[Byte] of TRGBQUAD);
-// False: (redMask, greenMask, blueMask: Cardinal);
+// true : (Colors: array[Byte] of TRGBQUAD);
+// false: (redMask, greenMask, blueMask: Cardinal);
// end;
-function TglBitmap.LoadBMP(Stream: TStream): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
+type
+ TMaskValues = packed record
+ Red: Cardinal;
+ Green: Cardinal;
+ Blue: Cardinal;
+ Alpha: Cardinal;
+ end;
+
var
- StreamPos: Int64;
- Header: TBMPHeader;
- Info: TBMPInfo;
- NewImage, pData: pByte;
+ StartPos: Int64;
- Format: TglBitmapFormat;
- LineSize, Padding, LineIdx: Integer;
- RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ function ReadInfo(var aInfo: TBMPInfo; var aMask: TMaskValues): TglBitmapFormat;
+ begin
+ result := tfEmpty;
+ aStream.Read(aInfo, SizeOf(aInfo));
+ FillChar(aMask, SizeOf(aMask), 0);
- PaddingBuff: Cardinal;
+ //Read Compression
+ if aInfo.biCompression <> BMP_COMP_RGB then begin
+ if aInfo.biCompression = BMP_COMP_BITFIELDS then begin
+ // Read Bitmasks for 16 or 32 Bit (24 Bit dosn't support Bitmasks!)
+ if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
+ aStream.Read(aMask.Red, SizeOf(Cardinal));
+ aStream.Read(aMask.Green, SizeOf(Cardinal));
+ aStream.Read(aMask.Blue, SizeOf(Cardinal));
+ aStream.Read(aMask.Alpha, SizeOf(Cardinal));
+ end else
+ raise EglBitmapException.Create('Bitmask is not supported for 24bit formats');
+ end else begin
+ aStream.Position := StartPos;
+ raise EglBitmapException.Create('RLE compression is not supported');
+ end;
+ end;
+ //get suitable format
+ case aInfo.biBitCount of
+ 8: result := tfLuminance8;
+ 16: result := tfRGB5A1;
+ 24: result := tfBGR8;
+ 32: result := tfBGRA8;
+ end;
+ end;
- function GetLineWidth : Integer;
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TMaskValues): TBitfieldFormat;
+ var
+ TmpFormat: TglBitmapFormat;
+ FormatDesc: TglBitmapFormatDescClass;
begin
- Result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
- end;
+ result := nil;
+ if (aMask.Red <> 0) or (aMask.Green <> 0) or (aMask.Blue <> 0) or (aMask.Alpha <> 0) then begin
+ for TmpFormat := High(FORMAT_DESCRIPTORS) downto Low(FORMAT_DESCRIPTORS) do begin
+ FormatDesc := FORMAT_DESCRIPTORS[TmpFormat];
+ if FormatDesc.MaskMatch(aMask.Red, aMask.Green, aMask.Blue, aMask.Alpha) then begin
+ aFormat := FormatDesc.GetFormat;
+ exit;
+ end;
+ end;
-
-begin
- Result := False;
+ if (aMask.Alpha = 0) then
+ aFormat := FORMAT_DESCRIPTORS[aFormat].WithoutAlpha;
- RedMask := 0;
- GreenMask := 0;
- BlueMask := 0;
- Format := ifEmpty;
+ result := TBitfieldFormat.Create;
+ result.RedMask := aMask.Red;
+ result.GreenMask := aMask.Green;
+ result.BlueMask := aMask.Blue;
+ result.AlphaMask := aMask.Alpha;
+ end;
+ end;
- // Header
- StreamPos := Stream.Position;
- Stream.Read(Header, SizeOf(Header));
+var
+ //simple types
+ ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
+ PaddingBuff: Cardinal;
+ LineBuf, ImageData, TmpData: PByte;
+ BmpFormat: TglBitmapFormat;
- if Header.bfType = BMP_MAGIC then begin
- Stream.Read(Info, SizeOf(Info));
+ //records
+ Mask: TMaskValues;
+ Header: TBMPHeader;
+ Info: TBMPInfo;
- // Check for Compression
- if Info.biCompression <> BMP_COMP_RGB then begin
- if Info.biCompression = BMP_COMP_BITFIELDS then begin
- // Read Bitmasks for 16 or 32 Bit (24 Bit dosn't support Bitmasks!)
- if (Info.biBitCount = 16) or (Info.biBitCount = 32) then begin
- Stream.Read(RedMask, SizeOf(Cardinal));
- Stream.Read(GreenMask, SizeOf(Cardinal));
- Stream.Read(BlueMask, SizeOf(Cardinal));
- Stream.Read(AlphaMask, SizeOf(Cardinal));
- end;
- end else begin
- // RLE compression is unsupported
- Stream.Position := StreamPos;
+ //classes
+ BitfieldFormat: TBitfieldFormat;
+ FormatDesc: TglBitmapFormatDescClass;
- Exit;
- end;
- end;
- // Skip palette
- if Info.biBitCount < 16 then
- Stream.Position := Stream.Position + Info.biClrUsed * 4;
+ Tick: QWord;
+{
- // Jump to the data
- Stream.Position := StreamPos + Header.bfOffBits;
- // Select Format
- case Info.biBitCount of
- 8 : Format := ifLuminance;
- 16:
- begin
- if (RedMask = 0) and (GreenMask = 0) and (BlueMask = 0) then begin
- Format := tfRGB5A1;
- end else begin
- if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, ifLuminanceAlpha) then
- Format := ifLuminanceAlpha;
+ ImageData, pData, pTmp, LineBuf, TmpData: PByte;
+ BitOffset: Byte;
+ BmpFormat: TglBitmapFormat;
+ LineSize, Padding, LineIdx, PixelIdx: Integer;
+ RedMask, GreenMask, BlueMask, AlphaMask, FormatSize: Cardinal;
- if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, tfRGBA4) then
- Format := tfRGBA4;
- if FormatCheckFormat(RedMask, GreenMask, BlueMask, 0, tfRGB5A1) then
- Format := tfRGB5A1;
+ Pixel: TglBitmapPixelData;
+ PaddingBuff: Cardinal;
- if FormatCheckFormat(RedMask, GreenMask, BlueMask, 0, ifR5G6B5) then
- Format := ifR5G6B5;
- end;
- end;
- 24: Format := ifBGR8;
- 32:
- begin
- if (RedMask = 0) and (GreenMask = 0) and (BlueMask = 0) then begin
- Format := ifBGRA8;
- end else begin
- if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, tfRGBA8) then
- Format := tfRGBA8;
-
- if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, ifBGRA8) then
- Format := ifBGRA8;
-
- if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, tfRGB10A2) then
- Format := tfRGB10A2;
- end;
- end;
- end;
- if Format <> ifEmpty then begin
- LineSize := Trunc(Info.biWidth * FormatGetSize(Format));
- Padding := GetLineWidth - LineSize;
- // copying data
- GetMem(NewImage, Info.biHeight * LineSize);
- try
- FillChar(NewImage^, Info.biHeight * LineSize, $FF);
+ }
- // Set pData to last Line
- pData := NewImage;
- Inc(pData, LineSize * (Info.biHeight -1));
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ procedure ReadBitfieldLine(aData: PByte; aLineBuf: PByte);
+ var
+ i: Integer;
+ Pixel: TglBitmapPixelData;
- // Copy Image Data
- for LineIdx := 0 to Info.biHeight - 1 do begin
- Stream.Read(pData^, LineSize);
- Dec(pData, LineSize);
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ procedure ChangeRange(var aValue: Cardinal; const aOldRange, aNewRange: Cardinal);
+ begin
+ if (aOldRange = aNewRange) then
+ exit;
+ if (aOldRange > 0) then
+ aValue := Round(aValue / aOldRange * aNewRange)
+ else
+ aValue := 0;
+ end;
- Stream.Read(PaddingBuff, Padding);
- end;
+ begin
+ aStream.Read(aLineBuf^, rbLineSize);
+ for i := 0 to Info.biWidth-1 do begin
+ BitfieldFormat.Unmap(PCardinal(aLineBuf)^, Pixel); //if is 16bit Bitfield only 2 last significant Bytes are taken from Cardinal
+ inc(aLineBuf, Info.biBitCount shr 3);
+ with FormatDesc.GetPixelDesc do begin
+ ChangeRange(Pixel.Red, BitfieldFormat.RedRange, RedRange);
+ ChangeRange(Pixel.Green, BitfieldFormat.GreenRange, GreenRange);
+ ChangeRange(Pixel.Blue, BitfieldFormat.BlueRange, BlueRange);
+ ChangeRange(Pixel.Alpha, BitfieldFormat.AlphaRange, AlphaRange);
+ end;
+ FormatDesc.Map(Pixel, aData);
+ end;
+ end;
- // Set new Image
- SetDataPointer(NewImage, Format, Info.biWidth, Info.biHeight);
+begin
+ result := false;
+ BmpFormat := tfEmpty;
+ BitfieldFormat := nil;
+ LineBuf := nil;
- Result := True;
- except
- FreeMem(NewImage);
- raise;
- end;
+ // Header
+ StartPos := aStream.Position;
+ aStream.Read(Header, SizeOf(Header));
+
+ if Header.bfType = BMP_MAGIC then begin
+ BmpFormat := ReadInfo(Info, Mask);
+ BitfieldFormat := CheckBitfields(BmpFormat, Mask);
+ try
+ if (Info.biBitCount < 16) then
+ aStream.Position := aStream.Position + Info.biClrUsed * 4;
+ aStream.Position := StartPos + Header.bfOffBits;
+
+ if (BmpFormat <> tfEmpty) then begin
+ FormatDesc := FORMAT_DESCRIPTORS[BmpFormat];
+ rbLineSize := Info.biWidth * (Info.biBitCount shr 3); //ReadBuffer LineSize
+ wbLineSize := Trunc(Info.biWidth * FormatDesc.GetSize);
+ Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
+
+ //get Memory
+ ImageSize := FormatDesc.GetSize(glBitmapPosition(Info.biWidth, Info.biHeight));
+ GetMem(ImageData, ImageSize);
+ if Assigned(BitfieldFormat) then
+ GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
+
+ //read Data
+ try try
+ FillChar(ImageData^, ImageSize, $FF);
+ TmpData := ImageData;
+ Inc(TmpData, wbLineSize * (Info.biHeight -1));
+ for i := 0 to Info.biHeight-1 do begin
+ if Assigned(BitfieldFormat) then
+ ReadBitfieldLine(TmpData, LineBuf) //if is bitfield format read and convert data
+ else
+ aStream.Read(TmpData^, wbLineSize); //else only read data
+ Dec(TmpData, wbLineSize);
+ aStream.Read(PaddingBuff, Padding);
+ end;
+ SetDataPointer(ImageData, BmpFormat, Info.biWidth, Info.biHeight);
+ result := true;
+ finally
+ if Assigned(LineBuf) then
+ FreeMem(LineBuf);
+ end;
+ except
+ FreeMem(ImageData);
+ raise;
+ end;
+ end else
+ raise EglBitmapException.Create('LoadBMP - No suitable format found');
+ finally
+ FreeAndNil(BitfieldFormat);
end;
end
- else Stream.Position := StreamPos;
+ else aStream.Position := StartPos;
end;
-{$ENDREGION}
-const
- DDS_MAGIC = $20534444;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveBMP(const aStream: TStream);
+var
+ Header: TBMPHeader;
+ Info: TBMPInfo;
+ pData, pTemp: pByte;
- // DDS_header.dwFlags
- DDSD_CAPS = $00000001;
- DDSD_HEIGHT = $00000002;
- DDSD_WIDTH = $00000004;
- DDSD_PITCH = $00000008;
- DDSD_PIXELFORMAT = $00001000;
- DDSD_MIPMAPCOUNT = $00020000;
- DDSD_LINEARSIZE = $00080000;
- DDSD_DEPTH = $00800000;
+ PixelFormat: TglBitmapPixelData;
+ ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer;
+ Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
- // DDS_header.sPixelFormat.dwFlags
- DDPF_ALPHAPIXELS = $00000001;
- DDPF_FOURCC = $00000004;
- DDPF_INDEXED = $00000020;
- DDPF_RGB = $00000040;
+ PaddingBuff: Cardinal;
- // DDS_header.sCaps.dwCaps1
- DDSCAPS_COMPLEX = $00000008;
- DDSCAPS_TEXTURE = $00001000;
- DDSCAPS_MIPMAP = $00400000;
+ function GetLineWidth : Integer;
+ begin
+ result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
+ end;
- // DDS_header.sCaps.dwCaps2
- DDSCAPS2_CUBEMAP = $00000200;
- DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
- DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
- DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
- DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
- DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
- DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
- DDSCAPS2_VOLUME = $00200000;
+begin
+ if not (ftBMP in FormatGetSupportedFiles(Format)) then
+ raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
- D3DFMT_DXT1 = $31545844;
- D3DFMT_DXT3 = $33545844;
- D3DFMT_DXT5 = $35545844;
+ ImageSize := FORMAT_DESCRIPTORS[Format].GetSize(Dimension);
-type
- TDDSPixelFormat = packed record
- dwSize: Cardinal;
- dwFlags: Cardinal;
- dwFourCC: Cardinal;
- dwRGBBitCount: Cardinal;
- dwRBitMask: Cardinal;
- dwGBitMask: Cardinal;
- dwBBitMask: Cardinal;
- dwAlphaBitMask: Cardinal;
- end;
-
- TDDSCaps = packed record
- dwCaps1: Cardinal;
- dwCaps2: Cardinal;
- dwDDSX: Cardinal;
- dwReserved: Cardinal;
- end;
-
- TDDSHeader = packed record
- dwMagic: Cardinal;
- dwSize: Cardinal;
- dwFlags: Cardinal;
- dwHeight: Cardinal;
- dwWidth: Cardinal;
- dwPitchOrLinearSize: Cardinal;
- dwDepth: Cardinal;
- dwMipMapCount: Cardinal;
- dwReserved: array[0..10] of Cardinal;
- PixelFormat: TDDSPixelFormat;
- Caps: TDDSCaps;
- dwReserved2: Cardinal;
- end;
-
-
-
-function TglBitmap.LoadDDS(Stream: TStream): Boolean;
-var
- Header: TDDSHeader;
- StreamPos: Int64;
- Y, LineSize: Cardinal;
+ Header.bfType := BMP_MAGIC;
+ Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
+ Header.bfReserved1 := 0;
+ Header.bfReserved2 := 0;
+ Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
-// MipMapCount, X, Y, XSize, YSize: Cardinal;
- RowSize: Cardinal;
- NewImage, pData: pByte;
- Format: TglBitmapFormat;
+ FillChar(Info, SizeOf(Info), 0);
+ Info.biSize := SizeOf(Info);
+ Info.biWidth := Width;
+ Info.biHeight := Height;
+ Info.biPlanes := 1;
+ Info.biCompression := BMP_COMP_RGB;
+ Info.biSizeImage := ImageSize;
+ case Format of
+ //TODO tfAlpha8, ifLuminance8, ifDepth8:
+ tfLuminance8:
+ begin
+ Info.biBitCount := 8;
+ Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
+ Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal);
- function RaiseEx : Exception;
- begin
- Result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
+ Info.biClrUsed := 256;
+ Info.biClrImportant := 256;
+ end;
+ //TODO ifLuminance8Alpha8, tfRGBA4, ifR5G6B5, tfRGB5A1:
+ tfLuminance8Alpha8, tfRGB5A1:
+ begin
+ Info.biBitCount := 16;
+ Info.biCompression := BMP_COMP_BITFIELDS;
+ end;
+ tfBGR8, tfRGB8:
+ Info.biBitCount := 24;
+ //TODO tfBGRA8, tfRGBA8, tfRGB10A2:
+ tfBGRA8, tfRGBA8:
+ begin
+ Info.biBitCount := 32;
+ Info.biCompression := BMP_COMP_BITFIELDS;
+ end;
+ else
+ raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
end;
+ Info.biXPelsPerMeter := 2835;
+ Info.biYPelsPerMeter := 2835;
-
- function GetInternalFormat: TglBitmapFormat;
- begin
- with Header.PixelFormat do begin
- // Compresses
- if (dwFlags and DDPF_FOURCC) > 0 then begin
- case Header.PixelFormat.dwFourCC of
- D3DFMT_DXT1: Result := ifDXT1;
- D3DFMT_DXT3: Result := ifDXT3;
- D3DFMT_DXT5: Result := ifDXT5;
- else
- raise RaiseEx;
- end;
- end else
-
- // RGB
- if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
- case dwRGBBitCount of
- 8:
- begin
- if dwFlags and DDPF_ALPHAPIXELS > 0 then
- Result := ifAlpha
- else
- Result := ifLuminance;
- end;
- 16:
- begin
- if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
- // Alpha
- case GetBitSize(dwRBitMask) of
- 5: Result := tfRGB5A1;
- 4: Result := tfRGBA4;
- else
- Result := ifLuminanceAlpha;
- end;
- end else begin
- // no Alpha
- Result := ifR5G6B5;
- end;
- end;
- 24:
- begin
- if dwRBitMask > dwBBitMask then
- Result := ifBGR8
- else
- Result := tfRGB8;
- end;
- 32:
- begin
- if GetBitSize(dwRBitMask) = 10 then
- Result := tfRGB10A2
- else
+ // prepare bitmasks
+ if Info.biCompression = BMP_COMP_BITFIELDS then begin
+ Info.biSize := Info.biSize + 4 * SizeOf(Cardinal);
+ Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
+ Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
- if dwRBitMask > dwBBitMask then
- Result := ifBGRA8
- else
- Result := tfRGBA8;
- end;
- else
- raise RaiseEx;
- end;
- end else
- raise RaiseEx;
+ FORMAT_DESCRIPTORS[Format].PreparePixel(PixelFormat);
+ with PixelFormat.PixelDesc do begin
+ RedMask := RedRange shl RedShift;
+ GreenMask := GreenRange shl GreenShift;
+ BlueMask := BlueRange shl BlueShift;
+ AlphaMask := AlphaRange shl AlphaShift;
end;
end;
-begin
- Result := False;
-
- // Header
- StreamPos := Stream.Position;
- Stream.Read(Header, sizeof(Header));
+ // headers
+ aStream.Write(Header, SizeOf(Header));
+ aStream.Write(Info, SizeOf(Info));
- if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
- ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
- Stream.Position := StreamPos;
- Exit;
+ // colortable
+ if Info.biBitCount = 8 then begin
+ Temp := 0;
+ for ColorIdx := Low(Byte) to High(Byte) do begin
+ aStream.Write(Temp, 4);
+ Temp := Temp + $00010101;
+ end;
end;
- // Pixelformat
-// if Header.dwFlags and DDSD_MIPMAPCOUNT <> 0
-// then MipMapCount := Header.dwMipMapCount
-// else MipMapCount := 1;
-
- Format := GetInternalFormat;
- LineSize := Trunc(Header.dwWidth * FormatGetSize(Format));
-
- GetMem(NewImage, Header.dwHeight * LineSize);
- try
- pData := NewImage;
-
- // Compressed
- if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
- RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
-
- for Y := 0 to Header.dwHeight -1 do begin
- Stream.Read(pData^, RowSize);
- Inc(pData, LineSize);
- end;
- end else
+ // bitmasks
+ if Info.biCompression = BMP_COMP_BITFIELDS then begin
+ aStream.Write(RedMask, SizeOf(Cardinal));
+ aStream.Write(GreenMask, SizeOf(Cardinal));
+ aStream.Write(BlueMask, SizeOf(Cardinal));
+ aStream.Write(AlphaMask, SizeOf(Cardinal));
+ end;
- // RGB(A)
- if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
- RowSize := Header.dwPitchOrLinearSize;
+ // image data
+ LineSize := Trunc(Width * FORMAT_DESCRIPTORS[Format].GetSize);
+ Padding := GetLineWidth - LineSize;
+ PaddingBuff := 0;
- for Y := 0 to Header.dwHeight -1 do begin
- Stream.Read(pData^, RowSize);
- Inc(pData, LineSize);
- end;
- end
- else raise RaiseEx;
+ pData := Data;
+ Inc(pData, (Height -1) * LineSize);
- SetDataPointer(NewImage, Format, Header.dwWidth, Header.dwHeight);
+ // prepare row buffer. But only for RGB because RGBA supports color masks
+ // so it's possible to change color within the image.
+ if (Format = tfRGB8) then
+ GetMem(pTemp, fRowSize)
+ else
+ pTemp := nil;
- Result := True;
- except
- FreeMem(NewImage);
- raise;
+ try
+ // write image data
+ for LineIdx := 0 to Height - 1 do begin
+ // preparing row
+ if Format = tfRGB8 then begin
+ Move(pData^, pTemp^, fRowSize);
+ SwapRGB(pTemp, Width, false);
+ end else
+ pTemp := pData;
+ aStream.Write(pTemp^, LineSize);
+ Dec(pData, LineSize);
+ if Padding > 0 then
+ aStream.Write(PaddingBuff, Padding);
+ end;
+ finally
+ // destroy row buffer
+ if Format = tfRGB8 then
+ FreeMem(pTemp);
end;
end;
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type
TTGAHeader = packed record
ImageID: Byte;
TGA_COMPRESSED_RGB = 10;
TGA_COMPRESSED_GRAY = 11;
-
-
-function TglBitmap.LoadTGA(Stream: TStream): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
var
Header: TTGAHeader;
NewImage, pData: PByte;
const
CACHE_SIZE = $4000;
+ ////////////////////////////////////////////////////////////////////////////////////////
procedure ReadUncompressed;
var
RowSize: Integer;
begin
RowSize := Header.Width * PixelSize;
-
// copy line by line
while YStart <> YEnd + YInc do begin
pData := NewImage;
Inc(pData, YStart * LineSize);
-
- Stream.Read(pData^, RowSize);
+ aStream.Read(pData^, RowSize);
Inc(YStart, YInc);
end;
end;
-
+ ////////////////////////////////////////////////////////////////////////////////////////
procedure ReadCompressed;
var
HeaderWidth, HeaderHeight: Integer;
PixelRepeat: Boolean;
PixelToRead, TempPixels: Integer;
-
+ /////////////////////////////////////////////////////////////////
procedure CheckLine;
begin
if LinePixelsRead >= HeaderWidth then begin
end;
end;
-
- procedure CachedRead(var Buffer; Count: Integer);
+ /////////////////////////////////////////////////////////////////
+ procedure CachedRead(out Buffer; Count: Integer);
var
BytesRead: Integer;
begin
// Read Data
if CacheSize - CachePos > 0 then begin
BytesRead := CacheSize - CachePos;
-
Move(pByteArray(Cache)^[CachePos], Buffer, BytesRead);
Inc(CachePos, BytesRead);
end;
// Reload Data
- CacheSize := Min(CACHE_SIZE, Stream.Size - Stream.Position);
- Stream.Read(Cache^, CacheSize);
+ CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
+ aStream.Read(Cache^, CacheSize);
CachePos := 0;
// Read else
end;
end;
-
begin
CacheSize := 0;
CachePos := 0;
CachedRead(Temp, 1);
PixelRepeat := Temp and $80 > 0;
- PixelToRead := (Temp and $7F) + 1;
+ PixelToRead := (Temp and $7F) + 1;
Inc(ImgPixelsRead, PixelToRead);
TempPixels := HeaderWidth - LinePixelsRead;
if PixelToRead < TempPixels then
TempPixels := PixelToRead;
-
+
Inc(LinePixelsRead, TempPixels);
Dec(PixelToRead, TempPixels);
while TempPixels > 0 do begin
case PixelSize of
- 1:
- begin
- pData^ := TempBuf[0];
- Inc(pData);
- end;
- 2:
- begin
- pWord(pData)^ := pWord(@TempBuf[0])^;
- Inc(pData, 2);
- end;
- 3:
- begin
- pWord(pData)^ := pWord(@TempBuf[0])^;
- Inc(pData, 2);
- pData^ := TempBuf[2];
- Inc(pData);
- end;
- 4:
- begin
- pDWord(pData)^ := pDWord(@TempBuf[0])^;
- Inc(pData, 4);
- end;
+ 1: begin
+ pData^ := TempBuf[0];
+ Inc(pData);
+ end;
+ 2: begin
+ pWord(pData)^ := pWord(@TempBuf[0])^;
+ Inc(pData, 2);
+ end;
+ 3: begin
+ pWord(pData)^ := pWord(@TempBuf[0])^;
+ Inc(pData, 2);
+ pData^ := TempBuf[2];
+ Inc(pData);
+ end;
+ 4: begin
+ pDWord(pData)^ := pDWord(@TempBuf[0])^;
+ Inc(pData, 4);
+ end;
end;
-
Dec(TempPixels);
end;
end;
// copy x pixels
while PixelToRead > 0 do begin
CheckLine;
-
TempPixels := HeaderWidth - LinePixelsRead;
if PixelToRead < TempPixels then
TempPixels := PixelToRead;
-
CachedRead(pData^, PixelSize * TempPixels);
Inc(pData, PixelSize * TempPixels);
-
Inc(LinePixelsRead, TempPixels);
-
Dec(PixelToRead, TempPixels);
end;
end;
end;
begin
- Result := False;
+ result := false;
// reading header to test file and set cursor back to begin
- StreamPos := Stream.Position;
- Stream.Read(Header, SizeOf(Header));
+ StreamPos := aStream.Position;
+ aStream.Read(Header, SizeOf(Header));
// no colormapped files
if (Header.ColorMapType = 0) then begin
if Header.ImageType in [TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY] then begin
case Header.Bpp of
- 8: Format := ifAlpha;
- 16: Format := ifLuminanceAlpha;
- 24: Format := ifBGR8;
- 32: Format := ifBGRA8;
- else
- raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
+ //TODO 8: Format := tfAlpha8;
+ 16: Format := tfLuminance8Alpha8;
+ 24: Format := tfBGR8;
+ 32: Format := tfBGRA8;
+ else
+ raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
end;
// skip image ID
if Header.ImageID <> 0 then
- Stream.Position := Stream.Position + Header.ImageID;
+ aStream.Position := aStream.Position + Header.ImageID;
- PixelSize := Trunc(FormatGetSize(Format));
- LineSize := Trunc(Header.Width * PixelSize);
+ PixelSize := Trunc(FORMAT_DESCRIPTORS[Format].GetSize);
+ LineSize := Trunc(Header.Width * PixelSize);
GetMem(NewImage, LineSize * Header.Height);
try
end;
SetDataPointer(NewImage, Format, Header.Width, Header.Height);
-
- Result := True;
+ result := true;
except
FreeMem(NewImage);
raise;
end;
end
- else Stream.Position := StreamPos;
+ else aStream.Position := StreamPos;
end
- else Stream.Position := StreamPos;
+ else aStream.Position := StreamPos;
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveTGA(const aStream: TStream);
+var
+ Header: TTGAHeader;
+ Size: Integer;
+ pTemp: pByte;
+ FormatDesc: TglBitmapFormatDescClass;
-{$IFDEF GLB_SUPPORT_PNG_WRITE}
-{$IFDEF GLB_LIB_PNG}
-procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
-begin
- TStream(png_get_io_ptr(png)).Write(buffer^, size);
-end;
-{$ENDIF}
+ procedure ConvertData(pTemp: pByte);
+ var
+ Idx, PixelSize: Integer;
+ Temp: byte;
+ begin
+ PixelSize := fPixelSize;
+ for Idx := 1 to Height * Width do begin
+ Temp := pByteArray(pTemp)^[2];
+ pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
+ pByteArray(pTemp)^[0] := Temp;
+ Inc(pTemp, PixelSize);
+ end;
+ end;
-procedure TglBitmap.SavePNG(Stream: TStream);
-{$IFDEF GLB_LIB_PNG}
-var
- png: png_structp;
- png_info: png_infop;
- png_rows: array of pByte;
- LineSize: Integer;
- ColorType: Integer;
- Row: Integer;
begin
- if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
- raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- if not init_libPNG then
- raise Exception.Create('SavePNG - unable to initialize libPNG.');
+ if not (ftTGA in FormatGetSupportedFiles(Format)) then
+ raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
- try
- case FInternalFormat of
- ifAlpha, ifLuminance, ifDepth8:
- ColorType := PNG_COLOR_TYPE_GRAY;
- ifLuminanceAlpha:
- ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
- ifBGR8, ifRGB8:
- ColorType := PNG_COLOR_TYPE_RGB;
- ifBGRA8, ifRGBA8:
- ColorType := PNG_COLOR_TYPE_RGBA;
- else
- raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ FillChar(Header, SizeOf(Header), 0);
+ case Format of
+ //TODO ifAlpha8, ifLuminance8, ifDepth8: begin
+ tfLuminance8: begin
+ Header.ImageType := TGA_UNCOMPRESSED_GRAY;
+ Header.Bpp := 8;
+ end;
+ tfLuminance8Alpha8: begin
+ Header.ImageType := TGA_UNCOMPRESSED_GRAY;
+ Header.Bpp := 16;
end;
+ tfRGB8, tfBGR8: begin
+ Header.ImageType := TGA_UNCOMPRESSED_RGB;
+ Header.Bpp := 24;
+ end;
+ tfRGBA8, tfBGRA8: begin
+ Header.ImageType := TGA_UNCOMPRESSED_RGB;
+ Header.Bpp := 32;
+ end;
+ else
+ raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
+ end;
- LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
+ Header.Width := Width;
+ Header.Height := Height;
+ Header.ImageDes := $20;
+ FormatDesc := FORMAT_DESCRIPTORS[Format];
- // creating array for scanline
- SetLength(png_rows, Height);
- try
- for Row := 0 to Height - 1 do begin
- png_rows[Row] := Data;
- Inc(png_rows[Row], Row * LineSize)
- end;
+ if FormatDesc.HasAlpha then
+ Header.ImageDes := Header.ImageDes or $08;
+ aStream.Write(Header, SizeOf(Header));
- // write struct
- png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
- if png = nil then
- raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
+ // convert RGB(A) to BGR(A)
+ Size := FormatDesc.GetSize(Dimension);
+ if Format in [tfRGB8, tfRGBA8] then begin
+ GetMem(pTemp, Size);
+ end else
+ pTemp := Data;
- // create png info
- png_info := png_create_info_struct(png);
- if png_info = nil then begin
- png_destroy_write_struct(@png, nil);
- raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
- end;
+ try
+ // convert data
+ if Format in [tfRGB8, tfRGBA8] then begin
+ Move(Data^, pTemp^, Size);
+ ConvertData(pTemp);
+ end;
- // set read callback
- png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
+ // write data
+ aStream.Write(pTemp^, Size);
+ finally
+ // free tempdata
+ if Format in [tfRGB8, tfRGBA8] then
+ FreeMem(pTemp);
+ end;
+end;
- // set compression
- png_set_compression_level(png, 6);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+const
+ DDS_MAGIC = $20534444;
- if InternalFormat in [ifBGR8, ifBGRA8] then
- png_set_bgr(png);
+ // DDS_header.dwFlags
+ DDSD_CAPS = $00000001;
+ DDSD_HEIGHT = $00000002;
+ DDSD_WIDTH = $00000004;
+ DDSD_PITCH = $00000008;
+ DDSD_PIXELFORMAT = $00001000;
+ DDSD_MIPMAPCOUNT = $00020000;
+ DDSD_LINEARSIZE = $00080000;
+ DDSD_DEPTH = $00800000;
- // setup header
- png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ // DDS_header.sPixelFormat.dwFlags
+ DDPF_ALPHAPIXELS = $00000001;
+ DDPF_FOURCC = $00000004;
+ DDPF_INDEXED = $00000020;
+ DDPF_RGB = $00000040;
- // write info
- png_write_info(png, png_info);
+ // DDS_header.sCaps.dwCaps1
+ DDSCAPS_COMPLEX = $00000008;
+ DDSCAPS_TEXTURE = $00001000;
+ DDSCAPS_MIPMAP = $00400000;
- // write image data
- png_write_image(png, @png_rows[0]);
+ // DDS_header.sCaps.dwCaps2
+ DDSCAPS2_CUBEMAP = $00000200;
+ DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
+ DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
+ DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
+ DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
+ DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
+ DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
+ DDSCAPS2_VOLUME = $00200000;
- // write end
- png_write_end(png, png_info);
+ D3DFMT_DXT1 = $31545844;
+ D3DFMT_DXT3 = $33545844;
+ D3DFMT_DXT5 = $35545844;
- // destroy write struct
- png_destroy_write_struct(@png, @png_info);
- finally
- SetLength(png_rows, 0);
- end;
- finally
- quit_libPNG;
+type
+ TDDSPixelFormat = packed record
+ dwSize: Cardinal;
+ dwFlags: Cardinal;
+ dwFourCC: Cardinal;
+ dwRGBBitCount: Cardinal;
+ dwRBitMask: Cardinal;
+ dwGBitMask: Cardinal;
+ dwBBitMask: Cardinal;
+ dwAlphaBitMask: Cardinal;
end;
-end;
-{$ENDIF}
-{$IFDEF GLB_PNGIMAGE}
+
+ TDDSCaps = packed record
+ dwCaps1: Cardinal;
+ dwCaps2: Cardinal;
+ dwDDSX: Cardinal;
+ dwReserved: Cardinal;
+ end;
+
+ TDDSHeader = packed record
+ dwMagic: Cardinal;
+ dwSize: Cardinal;
+ dwFlags: Cardinal;
+ dwHeight: Cardinal;
+ dwWidth: Cardinal;
+ dwPitchOrLinearSize: Cardinal;
+ dwDepth: Cardinal;
+ dwMipMapCount: Cardinal;
+ dwReserved: array[0..10] of Cardinal;
+ PixelFormat: TDDSPixelFormat;
+ Caps: TDDSCaps;
+ dwReserved2: Cardinal;
+ end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
var
- Png: TPNGObject;
+ Header: TDDSHeader;
+ StreamPos: Int64;
+ Y, LineSize: Cardinal;
+ RowSize: Cardinal;
+ NewImage, pData: pByte;
+ ddsFormat: TglBitmapFormat;
- pSource, pDest: pByte;
- X, Y, PixSize: Integer;
- ColorType: Cardinal;
- Alpha: Boolean;
+ function RaiseEx : Exception;
+ begin
+ result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
+ end;
- pTemp: pByte;
- Temp: Byte;
-begin
- if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
- raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ function GetDDSFormat: TglBitmapFormat;
+ begin
+ with Header.PixelFormat do begin
+ // Compresses
+ if (dwFlags and DDPF_FOURCC) > 0 then begin
+ (* TODO
+ case Header.PixelFormat.dwFourCC of
+ D3DFMT_DXT1: result := ifDXT1;
+ D3DFMT_DXT3: result := ifDXT3;
+ D3DFMT_DXT5: result := ifDXT5;
+ else
+ raise RaiseEx;
+ end;
+ *)
+ raise RaiseEx;
+ end else
- case FInternalFormat of
- ifAlpha, ifLuminance, ifDepth8:
- begin
- ColorType := COLOR_GRAYSCALE;
- PixSize := 1;
- Alpha := False;
- end;
- ifLuminanceAlpha:
- begin
- ColorType := COLOR_GRAYSCALEALPHA;
- PixSize := 1;
- Alpha := True;
- end;
- ifBGR8, ifRGB8:
- begin
- ColorType := COLOR_RGB;
- PixSize := 3;
- Alpha := False;
- end;
- ifBGRA8, ifRGBA8:
- begin
- ColorType := COLOR_RGBALPHA;
- PixSize := 3;
- Alpha := True
- end;
- else
- raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ // RGB
+ if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
+ case dwRGBBitCount of
+ 8: begin
+ (* TODO if dwFlags and DDPF_ALPHAPIXELS > 0 then
+ result := tfAlpha
+ else
+ *)
+ result := tfLuminance8;
+ end;
+ 16: begin
+ if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
+ // Alpha
+ case CountSetBits(dwRBitMask) of
+ 5: result := tfRGB5A1;
+ //TODO 4: result := tfRGBA4;
+ else
+ result := tfLuminance8Alpha8;
+ end;
+ end else begin
+ // no Alpha
+ //TODO result := ifR5G6B5;
+ raise RaiseEx;
+ end;
+ end;
+ 24: begin
+ if dwRBitMask > dwBBitMask then
+ result := tfBGR8
+ else
+ result := tfRGB8;
+ end;
+ 32: begin
+ if CountSetBits(dwRBitMask) = 10 then
+ //TODO result := tfRGB10A2
+ raise RaiseEx
+ else
+
+ if dwRBitMask > dwBBitMask then
+ result := tfBGRA8
+ else
+ result := tfRGBA8;
+ end;
+ else
+ raise RaiseEx;
+ end;
+ end else
+ raise RaiseEx;
+ end;
end;
- Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
- try
- // Copy ImageData
- pSource := Data;
- for Y := 0 to Height -1 do begin
- pDest := png.ScanLine[Y];
+begin
+ result := false;
- for X := 0 to Width -1 do begin
- Move(pSource^, pDest^, PixSize);
+ // Header
+ StreamPos := aStream.Position;
+ aStream.Read(Header, sizeof(Header));
- Inc(pDest, PixSize);
- Inc(pSource, PixSize);
+ if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
+ ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
+ aStream.Position := StreamPos;
+ exit;
+ end;
- if Alpha then begin
- png.AlphaScanline[Y]^[X] := pSource^;
- Inc(pSource);
- end;
- end;
+ ddsFormat := GetDDSFormat;
+ LineSize := Trunc(Header.dwWidth * FORMAT_DESCRIPTORS[ddsFormat].GetSize);
+ GetMem(NewImage, Header.dwHeight * LineSize);
+ try
+ pData := NewImage;
- // convert RGB line to BGR
- if InternalFormat in [ifRGB8, ifRGBA8] then begin
- pTemp := png.ScanLine[Y];
+ // Compressed
+ if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
+ RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
+ for Y := 0 to Header.dwHeight -1 do begin
+ aStream.Read(pData^, RowSize);
+ Inc(pData, LineSize);
+ end;
+ end else
- for X := 0 to Width -1 do begin
- Temp := pByteArray(pTemp)^[0];
- pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
- pByteArray(pTemp)^[2] := Temp;
+ // RGB(A)
+ if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
+ RowSize := Header.dwPitchOrLinearSize;
- Inc(pTemp, 3);
- end;
+ for Y := 0 to Header.dwHeight -1 do begin
+ aStream.Read(pData^, RowSize);
+ Inc(pData, LineSize);
end;
- end;
+ end else
+ raise RaiseEx;
- // Save to Stream
- Png.CompressionLevel := 6;
- Png.SaveToStream(Stream);
- finally
- FreeAndNil(Png);
+ SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
+ result := true;
+ except
+ FreeMem(NewImage);
+ raise;
end;
end;
-{$ENDIF}
-{$ENDIF}
-
-procedure TglBitmap.SaveDDS(Stream: TStream);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveDDS(const aStream: TStream);
var
Header: TDDSHeader;
Pix: TglBitmapPixelData;
begin
- if not FormatIsUncompressed(InternalFormat) then
- raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ //if not FormatIsUncompressed(InternalFormat) then
+ // raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT);
- if InternalFormat = ifAlpha then
- FormatPreparePixel(Pix, ifLuminance)
- else
- FormatPreparePixel(Pix, InternalFormat);
+ (* TODO if Format = tfAlpha8 then
+ FORMAT_DESCRIPTORS[tfLuminance8].PreparePixel(Pix);
+ else *)
+ FORMAT_DESCRIPTORS[Format].PreparePixel(Pix);
// Generell
FillChar(Header, SizeOf(Header), 0);
-
Header.dwMagic := DDS_MAGIC;
- Header.dwSize := 124;
+ Header.dwSize := 124;
Header.dwFlags := DDSD_PITCH or DDSD_CAPS or DDSD_PIXELFORMAT;
if Width > 0 then begin
Header.dwFlags := Header.dwFlags or DDSD_HEIGHT;
end;
- Header.dwPitchOrLinearSize := fRowSize;
- Header.dwMipMapCount := 1;
-
- // Caps
- Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
-
- // Pixelformat
- Header.PixelFormat.dwSize := Sizeof(Header.PixelFormat);
- Header.PixelFormat.dwFlags := DDPF_RGB;
-
- if FormatHasAlpha(InternalFormat) and (InternalFormat <> ifAlpha)
- then Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
-
- Header.PixelFormat.dwRGBBitCount := Trunc(FormatGetSize(InternalFormat) * 8);
- Header.PixelFormat.dwRBitMask := Pix.PixelDesc.RedRange shl Pix.PixelDesc.RedShift;
- Header.PixelFormat.dwGBitMask := Pix.PixelDesc.GreenRange shl Pix.PixelDesc.GreenShift;
- Header.PixelFormat.dwBBitMask := Pix.PixelDesc.BlueRange shl Pix.PixelDesc.BlueShift;
- Header.PixelFormat.dwAlphaBitMask := Pix.PixelDesc.AlphaRange shl Pix.PixelDesc.AlphaShift;
-
- // Write
- Stream.Write(Header, SizeOf(Header));
-
- Stream.Write(Data^, FormatGetImageSize(glBitmapPosition(Width, Height), InternalFormat));
-end;
-
-
-procedure TglBitmap.SaveTGA(Stream: TStream);
-var
- Header: TTGAHeader;
- Size: Integer;
- pTemp: pByte;
-
-
- procedure ConvertData(pTemp: pByte);
- var
- Idx, PixelSize: Integer;
- Temp: byte;
- begin
- PixelSize := fPixelSize;
-
- for Idx := 1 to Height * Width do begin
- Temp := pByteArray(pTemp)^[2];
- pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
- pByteArray(pTemp)^[0] := Temp;
-
- Inc(pTemp, PixelSize);
- end;
- end;
-
-
-begin
- if not (ftTGA in FormatGetSupportedFiles (InternalFormat)) then
- raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- FillChar(Header, SizeOf(Header), 0);
-
- case InternalFormat of
- ifAlpha, ifLuminance, ifDepth8:
- begin
- Header.ImageType := TGA_UNCOMPRESSED_GRAY;
- Header.Bpp := 8;
- end;
- ifLuminanceAlpha:
- begin
- Header.ImageType := TGA_UNCOMPRESSED_GRAY;
- Header.Bpp := 16;
- end;
- tfRGB8, ifBGR8:
- begin
- Header.ImageType := TGA_UNCOMPRESSED_RGB;
- Header.Bpp := 24;
- end;
- tfRGBA8, ifBGRA8:
- begin
- Header.ImageType := TGA_UNCOMPRESSED_RGB;
- Header.Bpp := 32;
- end;
- else
- raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_INTERNAL_FORMAT);
- end;
-
- Header.Width := Width;
- Header.Height := Height;
- Header.ImageDes := $20;
-
- if FormatHasAlpha(InternalFormat) then
- Header.ImageDes := Header.ImageDes or $08;
-
- Stream.Write(Header, SizeOf(Header));
-
- // convert RGB(A) to BGR(A)
- Size := FormatGetImageSize(glBitmapPosition(Width, Height), InternalFormat);
- if InternalFormat in [tfRGB8, tfRGBA8] then begin
- GetMem(pTemp, Size);
- end else
- pTemp := Data;
-
- try
- // convert data
- if InternalFormat in [tfRGB8, tfRGBA8] then begin
- Move(Data^, pTemp^, Size);
- ConvertData(pTemp);
- end;
-
- // write data
- Stream.Write(pTemp^, Size);
- finally
- // free tempdata
- if InternalFormat in [tfRGB8, tfRGBA8] then
- FreeMem(pTemp);
- end;
-end;
-
-
-{$IFDEF GLB_SUPPORT_JPEG_WRITE}
-procedure TglBitmap.SaveJPEG(Stream: TStream);
-{$IFDEF GLB_LIB_JPEG}
-var
- jpeg: jpeg_compress_struct;
- jpeg_err: jpeg_error_mgr;
- Row: Integer;
- pTemp, pTemp2: pByte;
-
-
- procedure CopyRow(pDest, pSource: pByte);
- var
- X: Integer;
- begin
- for X := 0 to Width - 1 do begin
- pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
- pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
- pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
-
- Inc(pDest, 3);
- Inc(pSource, 3);
- end;
- end;
-
-begin
- if not (ftJPEG in FormatGetSupportedFiles(InternalFormat)) then
- raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- if not init_libJPEG then
- raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
-
- try
- FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
- FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
-
- // error managment
- jpeg.err := jpeg_std_error(@jpeg_err);
- jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
- jpeg_err.output_message := glBitmap_libJPEG_output_message;
-
- // compression struct
- jpeg_create_compress(@jpeg);
-
- // allocation space for streaming methods
- jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
-
- // seeting up custom functions
- with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
- pub.init_destination := glBitmap_libJPEG_init_destination;
- pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
- pub.term_destination := glBitmap_libJPEG_term_destination;
-
- pub.next_output_byte := @DestBuffer[1];
- pub.free_in_buffer := Length(DestBuffer);
-
- DestStream := Stream;
- end;
-
- // very important state
- jpeg.global_state := CSTATE_START;
-
- jpeg.image_width := Width;
- jpeg.image_height := Height;
- case InternalFormat of
- ifAlpha, ifLuminance, ifDepth8:
- begin
- jpeg.input_components := 1;
- jpeg.in_color_space := JCS_GRAYSCALE;
- end;
- ifRGB8, ifBGR8:
- begin
- jpeg.input_components := 3;
- jpeg.in_color_space := JCS_RGB;
- end;
- end;
-
- // setting defaults
- jpeg_set_defaults(@jpeg);
-
- // compression quality
- jpeg_set_quality(@jpeg, 95, True);
-
- // start compression
- jpeg_start_compress(@jpeg, true);
-
- // write rows
- pTemp := Data;
-
- // initialing row
- if InternalFormat = ifBGR8 then
- GetMem(pTemp2, fRowSize)
- else
- pTemp2 := pTemp;
-
- try
- for Row := 0 to jpeg.image_height -1 do begin
- // prepare row
- if InternalFormat = ifBGR8 then
- CopyRow(pTemp2, pTemp)
- else
- pTemp2 := pTemp;
-
- // write row
- jpeg_write_scanlines(@jpeg, @pTemp2, 1);
- inc(pTemp, fRowSize);
- end;
- finally
- // free memory
- if InternalFormat = ifBGR8 then
- FreeMem(pTemp2);
- end;
-
- // finish compression
- jpeg_finish_compress(@jpeg);
-
- // destroy compression
- jpeg_destroy_compress(@jpeg);
- finally
- quit_libJPEG;
- end;
-end;
-{$ENDIF}
-{$IFDEF GLB_DELPHI_JPEG}
-var
- Bmp: TBitmap;
- Jpg: TJPEGImage;
-begin
- if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
- raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- Bmp := TBitmap.Create;
- try
- Jpg := TJPEGImage.Create;
- try
- AssignToBitmap(Bmp);
-
- if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
- Jpg.Grayscale := True;
- Jpg.PixelFormat := jf8Bit;
- end;
-
- Jpg.Assign(Bmp);
-
- Jpg.SaveToStream(Stream);
- finally
- FreeAndNil(Jpg);
- end;
- finally
- FreeAndNil(Bmp);
- end;
-end;
-{$ENDIF}
-{$ENDIF}
-
-
-procedure TglBitmap.SaveBMP(Stream: TStream);
-var
- Header: TBMPHeader;
- Info: TBMPInfo;
- pData, pTemp: pByte;
-
- PixelFormat: TglBitmapPixelData;
- ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer;
- Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
-
- PaddingBuff: Cardinal;
-
-
- function GetLineWidth : Integer;
- begin
- Result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
- end;
-
-
-begin
- if not (ftBMP in FormatGetSupportedFiles(InternalFormat)) then
- raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- ImageSize := Trunc(Width * Height * FormatGetSize(InternalFormat));
-
- Header.bfType := BMP_MAGIC;
- Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
- Header.bfReserved1 := 0;
- Header.bfReserved2 := 0;
- Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
-
- FillChar(Info, SizeOf(Info), 0);
- Info.biSize := SizeOf(Info);
- Info.biWidth := Width;
- Info.biHeight := Height;
- Info.biPlanes := 1;
- Info.biCompression := BMP_COMP_RGB;
- Info.biSizeImage := ImageSize;
- case InternalFormat of
- ifAlpha, ifLuminance, ifDepth8:
- begin
- Info.biBitCount := 8;
-
- Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
- Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal);
-
- Info.biClrUsed := 256;
- Info.biClrImportant := 256;
- end;
- ifLuminanceAlpha, tfRGBA4, ifR5G6B5, tfRGB5A1:
- begin
- Info.biBitCount := 16;
- Info.biCompression := BMP_COMP_BITFIELDS;
- end;
- ifBGR8, tfRGB8:
- Info.biBitCount := 24;
- ifBGRA8, tfRGBA8, tfRGB10A2:
- begin
- Info.biBitCount := 32;
- Info.biCompression := BMP_COMP_BITFIELDS;
- end;
- else
- raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_INTERNAL_FORMAT);
- end;
- Info.biXPelsPerMeter := 2835;
- Info.biYPelsPerMeter := 2835;
-
- // prepare bitmasks
- if Info.biCompression = BMP_COMP_BITFIELDS then begin
- Info.biSize := Info.biSize + 4 * SizeOf(Cardinal);
- Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
- Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
-
- FormatPreparePixel(PixelFormat, InternalFormat);
-
- with PixelFormat.PixelDesc do begin
- RedMask := RedRange shl RedShift;
- GreenMask := GreenRange shl GreenShift;
- BlueMask := BlueRange shl BlueShift;
- AlphaMask := AlphaRange shl AlphaShift;
- end;
- end;
-
- // headers
- Stream.Write(Header, SizeOf(Header));
- Stream.Write(Info, SizeOf(Info));
-
- // colortable
- if Info.biBitCount = 8 then begin
- Temp := 0;
- for ColorIdx := Low(Byte) to High(Byte) do begin
- Stream.Write(Temp, 4);
- Temp := Temp + $00010101;
- end;
- end;
-
- // bitmasks
- if Info.biCompression = BMP_COMP_BITFIELDS then begin
- Stream.Write(RedMask, SizeOf(Cardinal));
- Stream.Write(GreenMask, SizeOf(Cardinal));
- Stream.Write(BlueMask, SizeOf(Cardinal));
- Stream.Write(AlphaMask, SizeOf(Cardinal));
- end;
-
- // image data
- LineSize := Trunc(Width * FormatGetSize(InternalFormat));
- Padding := GetLineWidth - LineSize;
- PaddingBuff := 0;
-
- pData := Data;
- Inc(pData, (Height -1) * LineSize);
-
- // prepare row buffer. But only for RGB because RGBA supports color masks
- // so it's possible to change color within the image.
- if InternalFormat = tfRGB8 then
- GetMem(pTemp, fRowSize)
- else
- pTemp := nil;
-
- try
- // write image data
- for LineIdx := 0 to Height - 1 do begin
- // preparing row
- if InternalFormat = tfRGB8 then begin
- Move(pData^, pTemp^, fRowSize);
- SwapRGB(pTemp, Width, False);
- end else
- pTemp := pData;
-
- Stream.Write(pTemp^, LineSize);
-
- Dec(pData, LineSize);
-
- if Padding > 0 then
- Stream.Write(PaddingBuff, Padding);
- end;
- finally
- // destroy row buffer
- if InternalFormat = tfRGB8 then
- FreeMem(pTemp);
- end;
-end;
-
-
-procedure TglBitmap.Bind(EnableTextureUnit: Boolean);
-begin
- if EnableTextureUnit then
- glEnable(Target);
-
- if ID > 0 then
- glBindTexture(Target, ID);
-end;
-
-
-procedure TglBitmap.Unbind(DisableTextureUnit: Boolean);
-begin
- if DisableTextureUnit then
- glDisable(Target);
-
- glBindTexture(Target, 0);
-end;
-
-
-procedure TglBitmap.GetPixel(const Pos: TglBitmapPixelPosition;
- var Pixel: TglBitmapPixelData);
-begin
- if Assigned (fGetPixelFunc) then
- fGetPixelFunc(Pos, Pixel);
-end;
-
-
-procedure TglBitmap.SetPixel (const Pos: TglBitmapPixelPosition;
- const Pixel: TglBitmapPixelData);
-begin
- if Assigned (fSetPixelFunc) then
- fSetPixelFunc(Pos, Pixel);
-end;
-
-
-
-
-
-
-function TglBitmap.FlipHorz: Boolean;
-begin
- Result := False;
-end;
-
-
-function TglBitmap.FlipVert: Boolean;
-begin
- Result := False;
-end;
-
-
-procedure TglBitmap.FreeData;
-begin
- SetDataPointer(nil, ifEmpty);
-end;
-
-
-procedure glBitmapFillWithColorFunc(var FuncRec: TglBitmapFunctionRec);
-type
- PglBitmapPixelData = ^TglBitmapPixelData;
-begin
- with FuncRec do begin
- Dest.Red := PglBitmapPixelData(CustomData)^.Red;
- Dest.Green := PglBitmapPixelData(CustomData)^.Green;
- Dest.Blue := PglBitmapPixelData(CustomData)^.Blue;
- Dest.Alpha := PglBitmapPixelData(CustomData)^.Alpha;
- end;
-end;
-
-
-procedure TglBitmap.FillWithColor(Red, Green, Blue: Byte; Alpha: Byte);
-begin
- FillWithColorFloat(Red / $FF, Green / $FF, Blue / $FF, Alpha / $FF);
-end;
-
-
-procedure TglBitmap.FillWithColorFloat(Red, Green, Blue: Single; Alpha: Single);
-var
- PixelData: TglBitmapPixelData;
-begin
- FormatPreparePixel(PixelData, InternalFormat);
-
- PixelData.Red := Max(0, Min(PixelData.PixelDesc.RedRange, Trunc(PixelData.PixelDesc.RedRange * Red)));
- PixelData.Green := Max(0, Min(PixelData.PixelDesc.GreenRange, Trunc(PixelData.PixelDesc.GreenRange * Green)));
- PixelData.Blue := Max(0, Min(PixelData.PixelDesc.BlueRange, Trunc(PixelData.PixelDesc.BlueRange * Blue)));
- PixelData.Alpha := Max(0, Min(PixelData.PixelDesc.AlphaRange, Trunc(PixelData.PixelDesc.AlphaRange * Alpha)));
-
- AddFunc(glBitmapFillWithColorFunc, False, @PixelData);
-end;
-
-
-procedure TglBitmap.FillWithColorRange(Red, Green, Blue: Cardinal;
- Alpha: Cardinal);
-var
- PixelData: TglBitmapPixelData;
-begin
- FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
-
- FillWithColorFloat(
- Red / PixelData.PixelDesc.RedRange,
- Green / PixelData.PixelDesc.GreenRange,
- Blue / PixelData.PixelDesc.BlueRange,
- Alpha / PixelData.PixelDesc.AlphaRange);
-end;
-
-
-
-procedure TglBitmap.SetInternalFormat(const aValue: TglBitmapFormat);
-begin
- if InternalFormat <> Value then begin
- if FormatGetSize(Value) <> FormatGetSize(InternalFormat) then
- raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- // Update whatever
- SetDataPointer(Data, Value);
- end;
-end;
-
-
-function TglBitmap.AddFunc(Func: TglBitmapFunction; CreateTemp: Boolean;
- CustomData: Pointer): boolean;
-begin
- Result := AddFunc(Self, Func, CreateTemp, InternalFormat, CustomData);
-end;
-
-
-function TglBitmap.AddFunc(Source: TglBitmap; Func: TglBitmapFunction;
- CreateTemp: Boolean; Format: TglBitmapFormat; CustomData: Pointer): boolean;
-var
- pDest, NewImage, pSource: pByte;
- TempHeight, TempWidth: Integer;
- MapFunc: TglBitmapMapFunc;
- UnMapFunc: TglBitmapUnMapFunc;
-
- FuncRec: TglBitmapFunctionRec;
-begin
- Assert(Assigned(Data));
- Assert(Assigned(Source));
- Assert(Assigned(Source.Data));
-
- Result := False;
-
- if Assigned (Source.Data) and FormatIsUncompressed(Format) and
- ((Source.Height > 0) or (Source.Width > 0)) then begin
-
- // inkompatible Formats so CreateTemp
- if FormatGetSize(Format) <> FormatGetSize(InternalFormat) then
- CreateTemp := True;
-
- // Values
- TempHeight := Max(1, Source.Height);
- TempWidth := Max(1, Source.Width);
-
- FuncRec.Sender := Self;
- FuncRec.CustomData := CustomData;
-
- NewImage := nil;
-
- if CreateTemp then begin
- GetMem(NewImage, Trunc(FormatGetSize(Format) * TempHeight * TempWidth));
- pDest := NewImage;
- end
- else pDest := Data;
-
- try
- // Mapping
- MapFunc := FormatGetMapFunc(Format);
- FormatPreparePixel(FuncRec.Dest, Format);
- FormatPreparePixel(FuncRec.Source, Source.InternalFormat);
-
- FuncRec.Size := Source.Dimension;
- FuncRec.Position.Fields := FuncRec.Size.Fields;
-
- if FormatIsUncompressed(Source.InternalFormat) then begin
- // Uncompressed Images
- pSource := Source.Data;
- UnMapFunc := FormatGetUnMapFunc(Source.InternalFormat);
-
- FuncRec.Position.Y := 0;
- while FuncRec.Position.Y < TempHeight do begin
- FuncRec.Position.X := 0;
- while FuncRec.Position.X < TempWidth do begin
- // Get Data
- UnMapFunc(pSource, FuncRec.Source);
- // Func
- Func(FuncRec);
- // Set Data
- MapFunc(FuncRec.Dest, pDest);
- Inc(FuncRec.Position.X);
- end;
- Inc(FuncRec.Position.Y);
- end;
- end else begin
- // Compressed Images
- FuncRec.Position.Y := 0;
- while FuncRec.Position.Y < TempHeight do begin
- FuncRec.Position.X := 0;
- while FuncRec.Position.X < TempWidth do begin
- // Get Data
- fGetPixelFunc(FuncRec.Position, FuncRec.Source);
- // Func
- Func(FuncRec);
- // Set Data
- MapFunc(FuncRec.Dest, pDest);
- Inc(FuncRec.Position.X);
- end;
- Inc(FuncRec.Position.Y);
- end;
- end;
-
- // Updating Image or InternalFormat
- if CreateTemp then
- SetDataPointer(NewImage, Format)
- else
-
- if Format <> InternalFormat then
- SetInternalFormat(Format);
-
- Result := True;
- except
- if CreateTemp
- then FreeMem(NewImage);
- raise;
- end;
- end;
-end;
-
-
-procedure glBitmapConvertCopyFunc(var FuncRec: TglBitmapFunctionRec);
-begin
- with FuncRec do begin
- if Source.PixelDesc.RedRange > 0 then
- Dest.Red := Source.Red;
-
- if Source.PixelDesc.GreenRange > 0 then
- Dest.Green := Source.Green;
-
- if Source.PixelDesc.BlueRange > 0 then
- Dest.Blue := Source.Blue;
-
- if Source.PixelDesc.AlphaRange > 0 then
- Dest.Alpha := Source.Alpha;
- end;
-end;
-
-
-procedure glBitmapConvertCalculateRGBAFunc(var FuncRec: TglBitmapFunctionRec);
-begin
- with FuncRec do begin
- if Source.PixelDesc.RedRange > 0 then
- Dest.Red := Round(Dest.PixelDesc.RedRange * Source.Red / Source.PixelDesc.RedRange);
-
- if Source.PixelDesc.GreenRange > 0 then
- Dest.Green := Round(Dest.PixelDesc.GreenRange * Source.Green / Source.PixelDesc.GreenRange);
-
- if Source.PixelDesc.BlueRange > 0 then
- Dest.Blue := Round(Dest.PixelDesc.BlueRange * Source.Blue / Source.PixelDesc.BlueRange);
-
- if Source.PixelDesc.AlphaRange > 0 then
- Dest.Alpha := Round(Dest.PixelDesc.AlphaRange * Source.Alpha / Source.PixelDesc.AlphaRange);
- end;
-end;
-
-
-procedure glBitmapConvertShiftRGBAFunc(var FuncRec: TglBitmapFunctionRec);
-begin
- with FuncRec do
- with TglBitmapPixelDesc(CustomData^) do begin
- if Source.PixelDesc.RedRange > 0 then
- Dest.Red := Source.Red shr RedShift;
-
- if Source.PixelDesc.GreenRange > 0 then
- Dest.Green := Source.Green shr GreenShift;
-
- if Source.PixelDesc.BlueRange > 0 then
- Dest.Blue := Source.Blue shr BlueShift;
-
- if Source.PixelDesc.AlphaRange > 0 then
- Dest.Alpha := Source.Alpha shr AlphaShift;
- end;
-end;
-
-
-function TglBitmap.ConvertTo(NewFormat: TglBitmapFormat): boolean;
-var
- Source, Dest: TglBitmapPixelData;
- PixelDesc: TglBitmapPixelDesc;
-
- function CopyDirect: Boolean;
- begin
- Result :=
- ((Source.PixelDesc.RedRange = Dest.PixelDesc.RedRange) or (Source.PixelDesc.RedRange = 0) or (Dest.PixelDesc.RedRange = 0)) and
- ((Source.PixelDesc.GreenRange = Dest.PixelDesc.GreenRange) or (Source.PixelDesc.GreenRange = 0) or (Dest.PixelDesc.GreenRange = 0)) and
- ((Source.PixelDesc.BlueRange = Dest.PixelDesc.BlueRange) or (Source.PixelDesc.BlueRange = 0) or (Dest.PixelDesc.BlueRange = 0)) and
- ((Source.PixelDesc.AlphaRange = Dest.PixelDesc.AlphaRange) or (Source.PixelDesc.AlphaRange = 0) or (Dest.PixelDesc.AlphaRange = 0));
- end;
-
- function CanShift: Boolean;
- begin
- Result :=
- ((Source.PixelDesc.RedRange >= Dest.PixelDesc.RedRange ) or (Source.PixelDesc.RedRange = 0) or (Dest.PixelDesc.RedRange = 0)) and
- ((Source.PixelDesc.GreenRange >= Dest.PixelDesc.GreenRange) or (Source.PixelDesc.GreenRange = 0) or (Dest.PixelDesc.GreenRange = 0)) and
- ((Source.PixelDesc.BlueRange >= Dest.PixelDesc.BlueRange ) or (Source.PixelDesc.BlueRange = 0) or (Dest.PixelDesc.BlueRange = 0)) and
- ((Source.PixelDesc.AlphaRange >= Dest.PixelDesc.AlphaRange) or (Source.PixelDesc.AlphaRange = 0) or (Dest.PixelDesc.AlphaRange = 0));
- end;
-
- function GetShift(Source, Dest: Cardinal) : ShortInt;
- begin
- Result := 0;
-
- while (Source > Dest) and (Source > 0) do begin
- Inc(Result);
- Source := Source shr 1;
- end;
- end;
-
-begin
- if NewFormat <> InternalFormat then begin
- FormatPreparePixel(Source, InternalFormat);
- FormatPreparePixel(Dest, NewFormat);
-
- if CopyDirect then
- Result := AddFunc(Self, glBitmapConvertCopyFunc, False, NewFormat)
- else
- if CanShift then begin
- PixelDesc.RedShift := GetShift(Source.PixelDesc.RedRange, Dest.PixelDesc.RedRange);
- PixelDesc.GreenShift := GetShift(Source.PixelDesc.GreenRange, Dest.PixelDesc.GreenRange);
- PixelDesc.BlueShift := GetShift(Source.PixelDesc.BlueRange, Dest.PixelDesc.BlueRange);
- PixelDesc.AlphaShift := GetShift(Source.PixelDesc.AlphaRange, Dest.PixelDesc.AlphaRange);
-
- Result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, False, NewFormat, @PixelDesc);
- end
- else Result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, False, NewFormat);
- end
- else Result := True;
-end;
-
-
-function TglBitmap.RemoveAlpha: Boolean;
-begin
- Result := False;
-
- if (Assigned(Data)) then begin
- if not (FormatIsUncompressed(InternalFormat) or FormatHasAlpha(InternalFormat)) then
- raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- Result := ConvertTo(FormatGetWithoutAlpha(InternalFormat));
- end;
-end;
-
-
-function TglBitmap.AddAlphaFromFunc(Func: TglBitmapFunction; CustomData: Pointer): boolean;
-begin
- if not FormatIsUncompressed(InternalFormat) then
- raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- Result := AddFunc(Self, Func, False, FormatGetWithAlpha(InternalFormat), CustomData);
-end;
-
-
-function TglBitmap.GetFileHeight: Integer;
-begin
- Result := Max(1, Height);
-end;
-
-
-function TglBitmap.GetFileWidth: Integer;
-begin
- Result := Max(1, Width);
-end;
-
-
-procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
-var
- Temp: Single;
-begin
- with FuncRec do begin
- Temp :=
- Source.Red / Source.PixelDesc.RedRange * 0.3 +
- Source.Green / Source.PixelDesc.GreenRange * 0.59 +
- Source.Blue / Source.PixelDesc.BlueRange * 0.11;
-
- Dest.Alpha := Round (Dest.PixelDesc.AlphaRange * Temp);
- end;
-end;
-
-
-function TglBitmap.AddAlphaFromglBitmap(glBitmap: TglBitmap; Func: TglBitmapFunction; CustomData: Pointer): boolean;
-var
- pDest, pDest2, pSource: pByte;
- TempHeight, TempWidth: Integer;
- MapFunc: TglBitmapMapFunc;
- DestUnMapFunc, UnMapFunc: TglBitmapUnMapFunc;
-
- FuncRec: TglBitmapFunctionRec;
-begin
- Result := False;
-
- assert(Assigned(Data));
- assert(Assigned(glBitmap));
- assert(Assigned(glBitmap.Data));
-
- if ((glBitmap.Width = Width) and (glBitmap.Height = Height)) then begin
- // Convert to Data with Alpha
- Result := ConvertTo(FormatGetWithAlpha(FormatGetUncompressed(InternalFormat)));
-
- if not Assigned(Func) then
- Func := glBitmapAlphaFunc;
-
- // Values
- TempHeight := glBitmap.FileHeight;
- TempWidth := glBitmap.FileWidth;
-
- FuncRec.Sender := Self;
- FuncRec.CustomData := CustomData;
-
- pDest := Data;
- pDest2 := Data;
- pSource := glBitmap.Data;
-
- // Mapping
- FormatPreparePixel(FuncRec.Dest, InternalFormat);
- FormatPreparePixel(FuncRec.Source, glBitmap.InternalFormat);
- MapFunc := FormatGetMapFunc(InternalFormat);
- DestUnMapFunc := FormatGetUnMapFunc(InternalFormat);
- UnMapFunc := FormatGetUnMapFunc(glBitmap.InternalFormat);
-
- FuncRec.Size := Dimension;
- FuncRec.Position.Fields := FuncRec.Size.Fields;
-
- FuncRec.Position.Y := 0;
- while FuncRec.Position.Y < TempHeight do begin
- FuncRec.Position.X := 0;
- while FuncRec.Position.X < TempWidth do begin
- // Get Data
- UnMapFunc(pSource, FuncRec.Source);
- DestUnMapFunc(pDest2, FuncRec.Dest);
- // Func
- Func(FuncRec);
- // Set Data
- MapFunc(FuncRec.Dest, pDest);
- Inc(FuncRec.Position.X);
- end;
- Inc(FuncRec.Position.Y);
- end;
- end;
-end;
-
-
-procedure TglBitmap.SetBorderColor(Red, Green, Blue, Alpha: Single);
-begin
- fBorderColor[0] := Red;
- fBorderColor[1] := Green;
- fBorderColor[2] := Blue;
- fBorderColor[3] := Alpha;
-
- if ID > 0 then begin
- Bind (False);
-
- glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
- end;
-end;
-
-
-{ TglBitmap2D }
-
-procedure TglBitmap2D.SetDataPointer(Data: pByte; Format: TglBitmapFormat; Width, Height: Integer);
-var
- Idx, LineWidth: Integer;
-begin
- inherited;
-
- // Format
- if FormatIsUncompressed(Format) then begin
- fUnmapFunc := FormatGetUnMapFunc(Format);
- fGetPixelFunc := GetPixel2DUnmap;
-
- fMapFunc := FormatGetMapFunc(Format);
- fSetPixelFunc := SetPixel2DUnmap;
-
- // Assigning Data
- if Assigned(Data) then begin
- SetLength(fLines, GetHeight);
-
- LineWidth := Trunc(GetWidth * FormatGetSize(InternalFormat));
-
- for Idx := 0 to GetHeight -1 do begin
- fLines[Idx] := Data;
- Inc(fLines[Idx], Idx * LineWidth);
- end;
- end
- else SetLength(fLines, 0);
- end else begin
- SetLength(fLines, 0);
-
- fSetPixelFunc := nil;
-
- case Format of
- ifDXT1:
- fGetPixelFunc := GetPixel2DDXT1;
- ifDXT3:
- fGetPixelFunc := GetPixel2DDXT3;
- ifDXT5:
- fGetPixelFunc := GetPixel2DDXT5;
- else
- fGetPixelFunc := nil;
- end;
- end;
-end;
-
-
-procedure TglBitmap2D.GetDXTColorBlock(pData: pByte; relX, relY: Integer; var Pixel: TglBitmapPixelData);
-type
- PDXT1Chunk = ^TDXT1Chunk;
- TDXT1Chunk = packed record
- Color1: WORD;
- Color2: WORD;
- Pixels: array [0..3] of byte;
- end;
-
-var
- BasePtr: pDXT1Chunk;
- PixPos: Integer;
- Colors: array [0..3] of TRGBQuad;
-begin
- BasePtr := pDXT1Chunk(pData);
-
- PixPos := BasePtr^.Pixels[relY] shr (relX * 2) and $3;
-
- if PixPos in [0, 2, 3] then begin
- Colors[0].rgbRed := BasePtr^.Color1 and $F800 shr 8;
- Colors[0].rgbGreen := BasePtr^.Color1 and $07E0 shr 3;
- Colors[0].rgbBlue := BasePtr^.Color1 and $001F shl 3;
- Colors[0].rgbReserved := 255;
- end;
-
- if PixPos in [1, 2, 3] then begin
- Colors[1].rgbRed := BasePtr^.Color2 and $F800 shr 8;
- Colors[1].rgbGreen := BasePtr^.Color2 and $07E0 shr 3;
- Colors[1].rgbBlue := BasePtr^.Color2 and $001F shl 3;
- Colors[1].rgbReserved := 255;
- end;
-
- if PixPos = 2 then begin
- Colors[2].rgbRed := (Colors[0].rgbRed * 67 + Colors[1].rgbRed * 33) div 100;
- Colors[2].rgbGreen := (Colors[0].rgbGreen * 67 + Colors[1].rgbGreen * 33) div 100;
- Colors[2].rgbBlue := (Colors[0].rgbBlue * 67 + Colors[1].rgbBlue * 33) div 100;
- Colors[2].rgbReserved := 255;
- end;
-
- if PixPos = 3 then begin
- Colors[3].rgbRed := (Colors[0].rgbRed * 33 + Colors[1].rgbRed * 67) div 100;
- Colors[3].rgbGreen := (Colors[0].rgbGreen * 33 + Colors[1].rgbGreen * 67) div 100;
- Colors[3].rgbBlue := (Colors[0].rgbBlue * 33 + Colors[1].rgbBlue * 67) div 100;
- if BasePtr^.Color1 > BasePtr^.Color2 then
- Colors[3].rgbReserved := 255
- else
- Colors[3].rgbReserved := 0;
- end;
-
- Pixel.Red := Colors[PixPos].rgbRed;
- Pixel.Green := Colors[PixPos].rgbGreen;
- Pixel.Blue := Colors[PixPos].rgbBlue;
- Pixel.Alpha := Colors[PixPos].rgbReserved;
-end;
-
-
-procedure TglBitmap2D.GetPixel2DDXT1(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-var
- BasePtr: pByte;
- PosX, PosY: Integer;
-begin
- inherited;
-
- if (Pos.Y <= Height) and (Pos.X <= Width) then begin
- PosX := Pos.X div 4;
- PosY := Pos.Y div 4;
-
- BasePtr := Data;
- Inc(BasePtr, (PosY * Width div 4 + PosX) * 8);
-
- GetDXTColorBlock(BasePtr, Pos.X - PosX * 4, Pos.Y - PosY * 4, Pixel);
- end;
-end;
-
-
-procedure TglBitmap2D.GetPixel2DDXT3(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-type
- PDXT3AlphaChunk = ^TDXT3AlphaChunk;
- TDXT3AlphaChunk = array [0..3] of WORD;
-
-var
- ColorPtr: pByte;
- AlphaPtr: PDXT3AlphaChunk;
- PosX, PosY, relX, relY: Integer;
-begin
- inherited;
-
- if (Pos.Y <= Height) and (Pos.X <= Width) then begin
- PosX := Pos.X div 4;
- PosY := Pos.Y div 4;
- relX := Pos.X - PosX * 4;
- relY := Pos.Y - PosY * 4;
-
- // get color value
- AlphaPtr := PDXT3AlphaChunk(Data);
- Inc(AlphaPtr, (PosY * Width div 4 + PosX) * 2);
-
- ColorPtr := pByte(AlphaPtr);
- Inc(ColorPtr, 8);
-
- GetDXTColorBlock(ColorPtr, relX, relY, Pixel);
-
- // extracting alpha
- Pixel.Alpha := AlphaPtr^[relY] shr (4 * relX) and $0F shl 4;
- end;
-end;
-
-
-procedure TglBitmap2D.GetPixel2DDXT5(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-var
- ColorPtr: pByte;
- AlphaPtr: PInt64;
- PixPos, PosX, PosY, relX, relY: Integer;
- Alpha0, Alpha1: Byte;
-begin
- inherited;
-
- if (Pos.Y <= Height) and (Pos.X <= Width) then begin
- PosX := Pos.X div 4;
- PosY := Pos.Y div 4;
- relX := Pos.X - PosX * 4;
- relY := Pos.Y - PosY * 4;
-
- // get color value
- AlphaPtr := PInt64(Data);
- Inc(AlphaPtr, (PosY * Width div 4 + PosX) * 2);
-
- ColorPtr := pByte(AlphaPtr);
- Inc(ColorPtr, 8);
-
- GetDXTColorBlock(ColorPtr, relX, relY, Pixel);
-
- // extracting alpha
- Alpha0 := AlphaPtr^ and $FF;
- Alpha1 := AlphaPtr^ shr 8 and $FF;
-
- PixPos := AlphaPtr^ shr (16 + (relY * 4 + relX) * 3) and $07;
-
- // use alpha 0
- if PixPos = 0 then begin
- Pixel.Alpha := Alpha0;
- end else
-
- // use alpha 1
- if PixPos = 1 then begin
- Pixel.Alpha := Alpha1;
- end else
-
- // alpha interpolate 7 Steps
- if Alpha0 > Alpha1 then begin
- Pixel.Alpha := ((8 - PixPos) * Alpha0 + (PixPos - 1) * Alpha1) div 7;
- end else
-
- // alpha is 100% transparent or not transparent
- if PixPos >= 6 then begin
- if PixPos = 6 then
- Pixel.Alpha := 0
- else
- Pixel.Alpha := 255;
- end else
-
- // alpha interpolate 5 Steps
- begin
- Pixel.Alpha := ((6 - PixPos) * Alpha0 + (PixPos - 1) * Alpha1) div 5;
- end;
- end;
-end;
-
-
-procedure TglBitmap2D.GetPixel2DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-var
- pTemp: pByte;
-begin
- pTemp := fLines[Pos.Y];
- Inc(pTemp, Pos.X * fPixelSize);
-
- fUnmapFunc(pTemp, Pixel);
-end;
-
-
-procedure TglBitmap2D.SetPixel2DUnmap(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData);
-var
- pTemp: pByte;
-begin
- pTemp := fLines[Pos.Y];
- Inc(pTemp, Pos.X * fPixelSize);
-
- fMapFunc(Pixel, pTemp);
-end;
-
-
-function TglBitmap2D.FlipHorz: Boolean;
-var
- Col, Row: Integer;
- pTempDest, pDest, pSource: pByte;
- ImgSize: Integer;
-begin
- Result := Inherited FlipHorz;
-
- if Assigned(Data) then begin
- pSource := Data;
- ImgSize := Height * fRowSize;
+ Header.dwPitchOrLinearSize := fRowSize;
+ Header.dwMipMapCount := 1;
- GetMem(pDest, ImgSize);
- try
- pTempDest := pDest;
+ // Caps
+ Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
- Dec(pTempDest, fRowSize + fPixelSize);
- for Row := 0 to Height -1 do begin
- Inc(pTempDest, fRowSize * 2);
- for Col := 0 to Width -1 do begin
- Move(pSource^, pTempDest^, fPixelSize);
+ // Pixelformat
+ Header.PixelFormat.dwSize := Sizeof(Header.PixelFormat);
+ Header.PixelFormat.dwFlags := DDPF_RGB;
- Inc(pSource, fPixelSize);
- Dec(pTempDest, fPixelSize);
- end;
- end;
+ (* TODO tfAlpha8
+ if FORMAT_DESCRIPTORS[Format].HasAlpha and (Format <> tfAlpha8) then
+ Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
+ *)
- SetDataPointer(pDest, InternalFormat);
+ Header.PixelFormat.dwRGBBitCount := Trunc(FORMAT_DESCRIPTORS[Format].GetSize * 8);
+ Header.PixelFormat.dwRBitMask := Pix.PixelDesc.RedRange shl Pix.PixelDesc.RedShift;
+ Header.PixelFormat.dwGBitMask := Pix.PixelDesc.GreenRange shl Pix.PixelDesc.GreenShift;
+ Header.PixelFormat.dwBBitMask := Pix.PixelDesc.BlueRange shl Pix.PixelDesc.BlueShift;
+ Header.PixelFormat.dwAlphaBitMask := Pix.PixelDesc.AlphaRange shl Pix.PixelDesc.AlphaShift;
- Result := True;
- except
- FreeMem(pDest);
- raise;
- end;
- end;
+ aStream.Write(Header, SizeOf(Header));
+ aStream.Write(Data^, FORMAT_DESCRIPTORS[Format].GetSize(Dimension));
end;
+{$ENDREGION}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
+begin
+ if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
+ result := fLines[aIndex]
+ else
+ result := nil;
+end;
-function TglBitmap2D.FlipVert: Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
+ const aWidth: Integer; const aHeight: Integer);
var
- Row: Integer;
- pTempDest, pDest, pSource: pByte;
+ Idx, LineWidth: Integer;
begin
- Result := Inherited FlipVert;
-
- if Assigned(Data) then begin
- pSource := Data;
- GetMem(pDest, Height * fRowSize);
- try
- pTempDest := pDest;
-
- Inc(pTempDest, Width * (Height -1) * fPixelSize);
+ inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
- for Row := 0 to Height -1 do begin
- Move(pSource^, pTempDest^, fRowSize);
+ //TODO compression
+ if {FormatIsUncompressed(Format)} true then begin
+ (* TODO PixelFuncs
+ fGetPixelFunc := GetPixel2DUnmap;
+ fSetPixelFunc := SetPixel2DUnmap;
+ *)
+ // Assigning Data
+ if Assigned(Data) then begin
+ SetLength(fLines, GetHeight);
+ LineWidth := Trunc(GetWidth * FORMAT_DESCRIPTORS[Format].GetSize);
- Dec(pTempDest, fRowSize);
- Inc(pSource, fRowSize);
+ for Idx := 0 to GetHeight -1 do begin
+ fLines[Idx] := Data;
+ Inc(fLines[Idx], Idx * LineWidth);
end;
+ end
+ else SetLength(fLines, 0);
+ end else begin
+ (*
+ SetLength(fLines, 0);
- SetDataPointer(pDest, InternalFormat);
+ fSetPixelFunc := nil;
- Result := True;
- except
- FreeMem(pDest);
- raise;
+ case Format of
+ ifDXT1:
+ fGetPixelFunc := GetPixel2DDXT1;
+ ifDXT3:
+ fGetPixelFunc := GetPixel2DDXT3;
+ ifDXT5:
+ fGetPixelFunc := GetPixel2DDXT5;
+ else
+ fGetPixelFunc := nil;
end;
+ *)
end;
end;
-
-procedure TglBitmap2D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
+var
+ FormatDescriptor: TglBitmapFormatDescClass;
+ FormatDesc: TglBitmapFormatDesc;
begin
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- // Upload data
+ (* TODO compression
if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
glCompressedTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Trunc(Width * Height * FormatGetSize(Self.InternalFormat)), Data)
else
+ *)
- if BuildWithGlu then
- gluBuild2DMipmaps(Target, InternalFormat, Width, Height, Format, Typ, Data)
+ FormatDescriptor := FORMAT_DESCRIPTORS[Format];
+ FormatDesc := FormatDescriptor.GetFormatDesc;
+ if aBuildWithGlu then
+ gluBuild2DMipmaps(aTarget, FormatDescriptor.GetColorCompCount, Width, Height,
+ FormatDesc.Format, FormatDesc.DataType, Data)
else
- glTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Format, Typ, Data);
+ glTexImage2D(aTarget, 0, FormatDesc.InternalFormat, Width, Height, 0,
+ FormatDesc.Format, FormatDesc.DataType, Data);
// Freigeben
if (FreeDataAfterGenTexture) then
FreeData;
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.AfterConstruction;
+begin
+ inherited;
+ Target := GL_TEXTURE_2D;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
+var
+ Temp: pByte;
+ Size, w, h: Integer;
+ FormatDesc: TglBitmapFormatDescClass;
+ glFormatDesc: TglBitmapFormatDesc;
+begin
+ (* TODO compression
+ if not FormatIsUncompressed(Format) then
+ raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
+ *)
+
+ w := aRight - aLeft;
+ h := aBottom - aTop;
+ FormatDesc := FORMAT_DESCRIPTORS[Format];
+ glFormatDesc := FormatDesc.GetFormatDesc;
+ Size := FormatDesc.GetSize(glBitmapPosition(w, h));
+ GetMem(Temp, Size);
+ try
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ glReadPixels(aLeft, aTop, w, h, glFormatDesc.Format, glFormatDesc.DataType, Temp);
+ SetDataPointer(Temp, Format, w, h);
+ FlipVert;
+ except
+ FreeMem(Temp);
+ raise;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.GetDataFromTexture;
+var
+ Temp: PByte;
+ TempWidth, TempHeight, RedSize, GreenSize, BlueSize, AlphaSize, LumSize: Integer;
+ TempType, TempIntFormat: Cardinal;
+ IntFormat: TglBitmapFormat;
+ FormatDesc: TglBitmapFormatDescClass;
+begin
+ Bind;
+
+ // Request Data
+ glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
+ glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
+ glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
+
+ glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_RED_SIZE, @RedSize);
+ glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_GREEN_SIZE, @GreenSize);
+ glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_BLUE_SIZE, @BlueSize);
+ glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_ALPHA_SIZE, @AlphaSize);
+ glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_LUMINANCE_SIZE, @LumSize);
+
+ IntFormat := tfEmpty;
+ for FormatDesc in FORMAT_DESCRIPTORS do
+ if (FormatDesc.GetFormatDesc.InternalFormat = TempIntFormat) then begin
+ IntFormat := FormatDesc.GetFormat;
+ break;
+ end;
+
+ // Getting data from OpenGL
+ GetMem(Temp, FormatDesc.GetSize(glBitmapPosition(TempWidth, TempHeight)));
+ try
+ (* TODO Compression
+ if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
+ glGetCompressedTexImage(Target, 0, Temp)
+ else
+ *)
+ with FormatDesc.GetFormatDesc do
+ glGetTexImage(Target, 0, InternalFormat, DataType, Temp);
+ SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
+ except
+ FreeMem(Temp);
+ raise;
+ end;
+end;
-procedure TglBitmap2D.GenTexture(TestTextureSize: Boolean);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
var
BuildWithGlu, PotTex, TexRec: Boolean;
- glFormat, glInternalFormat, glType: Cardinal;
TexSize: Integer;
begin
if Assigned(Data) then begin
// Check Texture Size
- if (TestTextureSize) then begin
+ if (aTestTextureSize) then begin
glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
if ((Height > TexSize) or (Width > TexSize)) then
raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
- PotTex := IsPowerOfTwo (Height) and IsPowerOfTwo (Width);
- TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
- (Target = GL_TEXTURE_RECTANGLE_ARB);
+ PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
+ TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE_ARB);
if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
end;
CreateId;
-
SetupParameters(BuildWithGlu);
- SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
-
- UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
-
- // Infos sammeln
- glAreTexturesResident(1, @ID, @fIsResident);
+ UploadData(Target, BuildWithGlu);
+ glAreTexturesResident(1, @fID, @fIsResident);
end;
end;
-
-procedure TglBitmap2D.AfterConstruction;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap2D.FlipHorz: Boolean;
+var
+ Col, Row: Integer;
+ TempDestData, DestData, SourceData: PByte;
+ ImgSize: Integer;
begin
- inherited;
-
- Target := GL_TEXTURE_2D;
+ result := inherited FlipHorz;
+ if Assigned(Data) then begin
+ SourceData := Data;
+ ImgSize := Height * fRowSize;
+ GetMem(DestData, ImgSize);
+ try
+ TempDestData := DestData;
+ Dec(TempDestData, fRowSize + fPixelSize);
+ for Row := 0 to Height -1 do begin
+ Inc(TempDestData, fRowSize * 2);
+ for Col := 0 to Width -1 do begin
+ Move(SourceData^, TempDestData^, fPixelSize);
+ Inc(SourceData, fPixelSize);
+ Dec(TempDestData, fPixelSize);
+ end;
+ end;
+ SetDataPointer(DestData, Format);
+ result := true;
+ except
+ FreeMem(DestData);
+ raise;
+ end;
+ end;
end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap2D.FlipVert: Boolean;
+var
+ Row: Integer;
+ TempDestData, DestData, SourceData: PByte;
+begin
+ result := inherited FlipVert;
+ if Assigned(Data) then begin
+ SourceData := Data;
+ GetMem(DestData, Height * fRowSize);
+ try
+ TempDestData := DestData;
+ Inc(TempDestData, Width * (Height -1) * fPixelSize);
+ for Row := 0 to Height -1 do begin
+ Move(SourceData^, TempDestData^, fRowSize);
+ Dec(TempDestData, fRowSize);
+ Inc(SourceData, fRowSize);
+ end;
+ SetDataPointer(DestData, Format);
+ result := true;
+ except
+ FreeMem(DestData);
+ raise;
+ end;
+ end;
+end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type
TMatrixItem = record
X, Y: Integer;
const
oneover255 = 1 / 255;
-procedure glBitmapToNormalMapPrepareFunc (var FuncRec: TglBitmapFunctionRec);
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
var
Val: Single;
begin
with FuncRec do begin
Val := Source.Red * 0.3 + Source.Green * 0.59 + Source.Blue * 0.11;
- PglBitmapToNormalMapRec (CustomData)^.Heights[Position.Y * Size.X + Position.X] := Val * oneover255;
+ PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * oneover255;
end;
end;
-
-procedure glBitmapToNormalMapPrepareAlphaFunc (var FuncRec: TglBitmapFunctionRec);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
begin
with FuncRec do
- PglBitmapToNormalMapRec (CustomData)^.Heights[Position.Y * Size.X + Position.X] := Source.Alpha * oneover255;
+ PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Alpha * oneover255;
end;
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
type
TVec = Array[0..2] of Single;
with FuncRec do begin
X := Max(0, Min(Size.X -1, X));
Y := Max(0, Min(Size.Y -1, Y));
-
- Result := PglBitmapToNormalMapRec (CustomData)^.Heights[Y * Size.X + X];
+ result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
end;
end;
begin
with FuncRec do begin
- with PglBitmapToNormalMapRec (CustomData)^ 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;
end;
end;
-
-procedure TglBitmap2D.ToNormalMap(Func: TglBitmapNormalMapFunc; Scale: Single; UseAlpha: Boolean);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
var
Rec: TglBitmapToNormalMapRec;
end;
begin
+ (* TODO Compression
if not FormatIsUncompressed(InternalFormat) then
- raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_INTERNAL_FORMAT);
+ raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_FORMAT);
+ *)
- if Scale > 100 then
+ if aScale > 100 then
Rec.Scale := 100
- else
- if Scale < -100 then
+ else if aScale < -100 then
Rec.Scale := -100
else
- Rec.Scale := Scale;
+ Rec.Scale := aScale;
SetLength(Rec.Heights, Width * Height);
try
- case Func 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;
+ 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 UseAlpha and FormatHasAlpha(InternalFormat) then
- AddFunc(glBitmapToNormalMapPrepareAlphaFunc, False, @Rec)
+ if aUseAlpha and FORMAT_DESCRIPTORS[Format].HasAlpha then
+ AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec))
else
- AddFunc(glBitmapToNormalMapPrepareFunc, False, @Rec);
-
- // Neues Bild berechnen
- AddFunc(glBitmapToNormalMapFunc, False, @Rec);
+ AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec));
+ AddFunc(glBitmapToNormalMapFunc, false, PtrInt(@Rec));
finally
SetLength(Rec.Heights, 0);
end;
end;
-procedure TglBitmap2D.GrabScreen(Top, Left, Right, Bottom: Integer; Format: TglBitmapFormat);
-var
- Temp: pByte;
- Size: Integer;
- glFormat, glInternalFormat, glType: Cardinal;
-begin
- if not FormatIsUncompressed(Format) then
- raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
- // Only to select Formats
- SelectFormat(Format, glFormat, glInternalFormat, glType, False);
-
- Size := FormatGetImageSize(glBitmapPosition(Right - Left, Bottom - Top), Format);
- GetMem(Temp, Size);
- try
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadPixels(Left, Top, Right - Left, Bottom - Top, glFormat, glType, Temp);
-
- // Set Data
- SetDataPointer(Temp, Format, Right - Left, Bottom - Top);
-
- // Flip
- FlipVert;
- except
- FreeMem(Temp);
- raise;
- end;
-end;
-
-
-procedure TglBitmap2D.GetDataFromTexture;
-var
- Temp: pByte;
- TempWidth, TempHeight, RedSize, GreenSize, BlueSize, AlphaSize, LumSize: Integer;
- TempType, TempIntFormat: Cardinal;
- IntFormat: TglBitmapFormat;
-begin
- Bind;
-
- // Request Data
- glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
- glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
- glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
-
- glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_RED_SIZE, @RedSize);
- glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_GREEN_SIZE, @GreenSize);
- glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_BLUE_SIZE, @BlueSize);
- glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_ALPHA_SIZE, @AlphaSize);
- glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_LUMINANCE_SIZE, @LumSize);
-
- // Get glBitmapInternalFormat from TempIntFormat
- TempType := GL_UNSIGNED_BYTE;
- case TempIntFormat of
- GL_ALPHA:
- IntFormat := ifAlpha;
- GL_LUMINANCE:
- IntFormat := ifLuminance;
- GL_LUMINANCE_ALPHA:
- IntFormat := ifLuminanceAlpha;
- GL_RGB4:
- begin
- IntFormat := ifR5G6B5;
- TempIntFormat := GL_RGB;
- TempType := GL_UNSIGNED_SHORT_5_6_5;
- end;
- GL_RGB, GL_RGB8:
- IntFormat := tfRGB8;
- GL_RGBA, GL_RGBA4, GL_RGBA8:
- begin
- if (RedSize = 4) and (BlueSize = 4) and (GreenSize = 4) and (AlphaSize = 4) then begin
- IntFormat := tfRGBA4;
- TempIntFormat := GL_BGRA;
- TempType := GL_UNSIGNED_SHORT_4_4_4_4_REV;
- end else
- if (RedSize = 5) and (BlueSize = 5) and (GreenSize = 5) and (AlphaSize = 1) then begin
- IntFormat := tfRGB5A1;
- TempIntFormat := GL_BGRA;
- TempType := GL_UNSIGNED_SHORT_1_5_5_5_REV;
- end else begin
- IntFormat := tfRGBA8;
- end;
- end;
- GL_BGR:
- IntFormat := ifBGR8;
- GL_BGRA:
- IntFormat := ifBGRA8;
- GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- IntFormat := ifDXT1;
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- IntFormat := ifDXT1;
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- IntFormat := ifDXT3;
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- IntFormat := ifDXT5;
- else
- IntFormat := ifEmpty;
- end;
- // Getting data from OpenGL
- GetMem(Temp, FormatGetImageSize(glBitmapPosition(TempWidth, TempHeight), IntFormat));
- try
- if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
- glGetCompressedTexImage(Target, 0, Temp)
- else
- glGetTexImage(Target, 0, TempIntFormat, TempType, Temp);
- SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
- except
- FreeMem(Temp);
- raise;
- end;
-end;
-function TglBitmap2D.GetScanline(Index: Integer): Pointer;
-begin
- if (Index >= Low(fLines)) and (Index <= High(fLines)) then
- Result := fLines[Index]
- else
- Result := nil;
-end;
-{ TglBitmap1D }
+(*
procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
var
pTemp: pByte;
Col: Integer;
pTempDest, pDest, pSource: pByte;
begin
- Result := Inherited FlipHorz;
+ result := inherited FlipHorz;
if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
pSource := Data;
SetDataPointer(pDest, InternalFormat);
- Result := True;
+ result := true;
finally
FreeMem(pDest);
end;
UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
// Infos sammeln
- glAreTexturesResident(1, @ID, @fIsResident);
+ glAreTexturesResident(1, @fID, @fIsResident);
end;
end;
procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
begin
- Assert(False, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
+ Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
end;
begin
Rec.HalfSize := Size div 2;
- FreeDataAfterGenTexture := False;
+ FreeDataAfterGenTexture := false;
SizeRec.Fields := [ffX, ffY];
SizeRec.X := Size;
LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
end;
+*)
initialization
glBitmapSetDefaultFormat(tfEmpty);