- GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
10-08-2008
- AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
-- Additional Datapointer for functioninterface now has the name CustomData
+- Additional Datapointer for functioninterface now has the name CustomData
24-07-2008
- AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
- If you load an texture from an file the property Filename will be set to the name of the file
- Property DataPtr now has the name Data
- Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
- Unused Depth removed
-- Function FreeData to freeing image data added
+- Function FreeData to freeing image data added
24-10-2007
- ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
15-11-2006
// Please uncomment the defines below to configure the glBitmap to your preferences.
// If you have configured the unit you can uncomment the warning above.
-{$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
+{.$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{.$DEFINE GLB_DELPHI}
// activate to enable the support for TLazIntfImage from Lazarus
-{$DEFINE GLB_LAZARUS}
+{.$DEFINE GLB_LAZARUS}
// activate to enable Lazarus TPortableNetworkGraphic support
// if you enable this pngImage and libPNG will be ignored
-{$DEFINE GLB_LAZ_PNG}
+{.$DEFINE GLB_LAZ_PNG}
// activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
// if you enable pngimage the libPNG will be ignored
// activate to enable Lazarus TJPEGImage support
// if you enable this delphi jpegs and libJPEG will be ignored
-{$DEFINE GLB_LAZ_JPEG}
+{.$DEFINE GLB_LAZ_JPEG}
// if you enable delphi jpegs the libJPEG will be ignored
{.$DEFINE GLB_DELPHI_JPEG}
uses
{$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
{$IF DEFINED(GLB_WIN) AND
- DEFINED(GLB_NATIVE_OGL)} windows, {$IFEND}
+ (DEFINED(GLB_NATIVE_OGL) OR
+ DEFINED(GLB_DELPHI))} windows, {$IFEND}
{$IFDEF GLB_SDL} SDL, {$ENDIF}
{$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
- {$IFDEF GLB_DELPHI} Dialogs, Graphics, {$ENDIF}
+ {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
{$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
{$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
EglBitmapSizeToLarge = class(EglBitmap);
EglBitmapNonPowerOfTwo = class(EglBitmap);
EglBitmapUnsupportedFormat = class(EglBitmap)
+ public
constructor Create(const aFormat: TglBitmapFormat); overload;
constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
end;
TglBitmapFormatDescriptor = class(TObject)
protected
function GetIsCompressed: Boolean; virtual; abstract;
+ function GetHasRed: Boolean; virtual; abstract;
+ function GetHasGreen: Boolean; virtual; abstract;
+ function GetHasBlue: Boolean; virtual; abstract;
function GetHasAlpha: Boolean; virtual; abstract;
function GetglDataFormat: GLenum; virtual; abstract;
function GetglInternalFormat: GLenum; virtual; abstract;
public
property IsCompressed: Boolean read GetIsCompressed;
+ property HasRed: Boolean read GetHasRed;
+ property HasGreen: Boolean read GetHasGreen;
+ property HasBlue: Boolean read GetHasBlue;
property HasAlpha: Boolean read GetHasAlpha;
property glFormat: GLenum read GetglFormat;
fTarget: GLuint;
fAnisotropic: Integer;
fDeleteTextureOnFree: Boolean;
+ fFreeDataOnDestroy: Boolean;
fFreeDataAfterGenTexture: Boolean;
fData: PByte;
- fIsResident: Boolean;
+ fIsResident: GLboolean;
fBorderColor: array[0..3] of Single;
fDimension: TglBitmapPixelPosition;
procedure SetCustomData(const aValue: Pointer);
procedure SetCustomName(const aValue: String);
procedure SetCustomNameW(const aValue: WideString);
+ procedure SetFreeDataOnDestroy(const aValue: Boolean);
procedure SetDeleteTextureOnFree(const aValue: Boolean);
procedure SetFormat(const aValue: TglBitmapFormat);
procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
property CustomData: Pointer read fCustomData write SetCustomData;
property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
+ property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy;
property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
property Dimension: TglBitmapPixelPosition read fDimension;
property Data: PByte read fData;
- property IsResident: Boolean read fIsResident;
+ property IsResident: GLboolean read fIsResident;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
constructor Create; 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; aData: PByte = nil); overload;
constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); 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;
implementation
uses
- Math, syncobjs, typinfo;
+ Math, syncobjs, typinfo
+ {$IFDEF GLB_DELPHI}, Types{$ENDIF}
+ {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
type
{$IFNDEF fpc}
fglDataFormat: GLenum;
function GetIsCompressed: Boolean; override;
+ function GetHasRed: Boolean; override;
+ function GetHasGreen: Boolean; override;
+ function GetHasBlue: Boolean; override;
function GetHasAlpha: Boolean; override;
function GetglFormat: GLenum; override;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TFormatDescriptor.GetRedMask: QWord;
begin
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TFormatDescriptor.GetHasRed: Boolean;
+begin
+ result := (fRange.r > 0);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TFormatDescriptor.GetHasGreen: Boolean;
+begin
+ result := (fRange.g > 0);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TFormatDescriptor.GetHasBlue: Boolean;
+begin
+ result := (fRange.b > 0);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TFormatDescriptor.GetHasAlpha: Boolean;
begin
result := (fRange.a > 0);
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
+begin
+ if fFreeDataOnDestroy = aValue then
+ exit;
+ fFreeDataOnDestroy := aValue;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
begin
if fDeleteTextureOnFree = aValue then
fTarget := 0;
fIsResident := false;
- fFormat := glBitmapGetDefaultFormat;
fMipMap := glBitmapDefaultMipmap;
fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
var
NewData: PByte;
begin
- NewData := nil;
- SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
+ if fFreeDataOnDestroy then begin
+ NewData := nil;
+ SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
+ end;
if (fID > 0) and fDeleteTextureOnFree then
glDeleteTextures(1, @fID);
inherited BeforeDestruction;
FreeMem(tmpData);
raise;
end;
- AddFunc(Self, aFunc, false, Format, aArgs);
+ AddFunc(Self, aFunc, false, aFormat, aArgs);
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
rid.Width := Width;
rid.Height := Height;
- rid.Depth := CountSetBits(FormatDesc.Range.r or FormatDesc.Range.g or FormatDesc.Range.b or FormatDesc.Range.a);
+ rid.Depth := CountSetBits(FormatDesc.RedMask or FormatDesc.GreenMask or FormatDesc.BlueMask or FormatDesc.AlphaMask);
rid.BitOrder := riboBitsInOrder;
rid.ByteOrder := riboLSBFirst;
rid.LineOrder := riloTopToBottom;
FormatDesc: TFormatDescriptor;
ImageData: PByte;
ImageSize: Integer;
+ CanCopy: Boolean;
+
+ procedure CopyConvert;
+ var
+ bfFormat: TbmpBitfieldFormat;
+ pSourceLine, pDestLine: PByte;
+ pSourceMD, pDestMD: Pointer;
+ x, y: Integer;
+ pixel: TglBitmapPixelData;
+ begin
+ bfFormat := TbmpBitfieldFormat.Create;
+ with aImage.DataDescription do begin
+ bfFormat.RedMask := ((1 shl RedPrec) - 1) shl RedShift;
+ bfFormat.GreenMask := ((1 shl GreenPrec) - 1) shl GreenShift;
+ bfFormat.BlueMask := ((1 shl BluePrec) - 1) shl BlueShift;
+ bfFormat.AlphaMask := ((1 shl AlphaPrec) - 1) shl AlphaShift;
+ bfFormat.PixelSize := BitsPerPixel / 8;
+ end;
+ pSourceMD := bfFormat.CreateMappingData;
+ pDestMD := FormatDesc.CreateMappingData;
+ try
+ for y := 0 to aImage.Height-1 do begin
+ pSourceLine := aImage.PixelData + y * aImage.DataDescription.BytesPerLine;
+ pDestLine := ImageData + y * Round(FormatDesc.PixelSize * aImage.Width);
+ for x := 0 to aImage.Width-1 do begin
+ bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
+ FormatDesc.Map(pixel, pDestLine, pDestMD);
+ end;
+ end;
+ finally
+ FormatDesc.FreeMappingData(pDestMD);
+ bfFormat.FreeMappingData(pSourceMD);
+ bfFormat.Free;
+ end;
+ end;
+
begin
result := false;
if not Assigned(aImage) then
if (f = tfEmpty) then
exit;
+ CanCopy :=
+ (Round(FormatDesc.PixelSize * 8) = aImage.DataDescription.Depth) and
+ (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
+
ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
ImageData := GetMem(ImageSize);
try
- Move(aImage.PixelData^, ImageData^, (aImage.Width * aImage.Height * aImage.DataDescription.BitsPerPixel) shr 3);
+ if CanCopy then
+ Move(aImage.PixelData^, ImageData^, ImageSize)
+ else
+ CopyConvert;
SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
except
if Assigned(ImageData) then
if (ID > 0) then begin
Bind(false);
- glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, @fSwizzle[0]);
+ glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
end;
end;
glbReadOpenGLExtensions;
{$ENDIF}
inherited Create;
+ fFormat := glBitmapGetDefaultFormat;
+ fFreeDataOnDestroy := true;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
+constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
var
- Image: PByte;
ImageSize: Integer;
begin
Create;
- ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
- GetMem(Image, ImageSize);
- try
- FillChar(Image^, ImageSize, #$FF);
- SetDataPointer(Image, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
- except
- if Assigned(Image) then
- FreeMem(Image);
- raise;
+ if not Assigned(aData) then begin
+ ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
+ GetMem(aData, ImageSize);
+ try
+ FillChar(aData^, ImageSize, #$FF);
+ SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
+ except
+ if Assigned(aData) then
+ FreeMem(aData);
+ raise;
+ end;
+ end else begin
+ SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
+ fFreeDataOnDestroy := false;
end;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
- const aFunc: TglBitmapFunction; const aArgs: Pointer);
+constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
begin
Create;
LoadFromFunc(aSize, aFunc, aFormat, aArgs);
MAGIC_LEN = 8;
PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
var
- png: TPortableNetworkGraphic;
+ reader: TLazReaderPNG;
intf: TLazIntfImage;
StreamPos: Int64;
magic: String[MAGIC_LEN];
exit;
end;
- png := TPortableNetworkGraphic.Create;
+ intf := TLazIntfImage.Create(0, 0);
+ reader := TLazReaderPNG.Create;
try try
- png.LoadFromStream(aStream);
- intf := png.CreateIntfImage;
- try try
- AssignFromLazIntfImage(intf);
- except
- result := false;
- aStream.Position := StreamPos;
- exit;
- end;
- finally
- intf.Free;
- end;
+ reader.UpdateDescription := true;
+ reader.ImageRead(aStream, intf);
+ AssignFromLazIntfImage(intf);
except
result := false;
aStream.Position := StreamPos;
exit;
end;
finally
- png.Free;
+ reader.Free;
+ intf.Free;
end;
end;
var
png: TPortableNetworkGraphic;
intf: TLazIntfImage;
+ raw: TRawImage;
begin
png := TPortableNetworkGraphic.Create;
intf := TLazIntfImage.Create(0, 0);
try
if not AssignToLazIntfImage(intf) then
raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
- png.LoadFromIntfImage(intf);
+ intf.GetRawImage(raw);
+ png.LoadFromRawImage(raw, false);
png.SaveToStream(aStream);
finally
png.Free;
MAGIC_LEN = 2;
JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
var
- jpeg: TJPEGImage;
intf: TLazIntfImage;
+ reader: TFPReaderJPEG;
StreamPos: Int64;
magic: String[MAGIC_LEN];
begin
exit;
end;
- jpeg := TJPEGImage.Create;
+ reader := TFPReaderJPEG.Create;
+ intf := TLazIntfImage.Create(0, 0);
try try
- jpeg.LoadFromStream(aStream);
- intf := TLazIntfImage.Create(0, 0);
- try try
- intf.LoadFromBitmap(jpeg.BitmapHandle, jpeg.MaskHandle);
- AssignFromLazIntfImage(intf);
- except
- result := false;
- aStream.Position := StreamPos;
- exit;
- end;
- finally
- intf.Free;
- end;
+ intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
+ reader.ImageRead(aStream, intf);
+ AssignFromLazIntfImage(intf);
except
result := false;
aStream.Position := StreamPos;
exit;
end;
finally
- jpeg.Free;
+ reader.Free;
+ intf.Free;
end;
end;
var
jpeg: TJPEGImage;
intf: TLazIntfImage;
+ raw: TRawImage;
begin
jpeg := TJPEGImage.Create;
intf := TLazIntfImage.Create(0, 0);
try
if not AssignToLazIntfImage(intf) then
raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
- jpeg.LoadFromIntfImage(intf);
+ intf.GetRawImage(raw);
+ jpeg.LoadFromRawImage(raw, false);
jpeg.SaveToStream(aStream);
finally
intf.Free;
var
Temp: PByte;
TempWidth, TempHeight: Integer;
- TempIntFormat: Cardinal;
+ TempIntFormat: GLint;
IntFormat, f: TglBitmapFormat;
FormatDesc: TFormatDescriptor;
begin
finalization
TFormatDescriptor.Finalize;
+{$IFDEF GLB_NATIVE_OGL}
+ if Assigned(GL_LibHandle) then
+ glbFreeLibrary(GL_LibHandle);
+
{$IFDEF GLB_NATIVE_OGL_DYNAMIC}
+ if Assigned(GLU_LibHandle) then
+ glbFreeLibrary(GLU_LibHandle);
FreeAndNil(InitOpenGLCS);
{$ENDIF}
+{$ENDIF}
end.