X-Git-Url: https://git.delphigl.com/?a=blobdiff_plain;f=glBitmap.pas;h=b1817054a283a804b46a85663356ae56b876a2df;hb=39d0b4a3cc4b5d49c02b79eac4f7fa7d40691c9e;hp=7c6e8403e7aca2593d1ff3d8ac3de81c1dabdabc;hpb=d5c49ccbaf8da189f750c0577eee4ac2ac5a3abc;p=glBitmap.git diff --git a/glBitmap.pas b/glBitmap.pas index 7c6e840..b181705 100644 --- a/glBitmap.pas +++ b/glBitmap.pas @@ -24,7 +24,7 @@ History - 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 @@ -53,7 +53,7 @@ History - 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 @@ -221,7 +221,7 @@ unit glBitmap; // 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 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -242,7 +242,7 @@ unit glBitmap; {.$DEFINE GLB_DELPHI} // activate to enable the support for TLazIntfImage from Lazarus -{$DEFINE GLB_LAZARUS} +{.$DEFINE GLB_LAZARUS} @@ -254,7 +254,7 @@ unit glBitmap; // 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 @@ -268,7 +268,7 @@ unit glBitmap; // 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} @@ -443,11 +443,12 @@ interface 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} @@ -859,6 +860,7 @@ type 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; @@ -887,6 +889,9 @@ type 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; @@ -894,6 +899,9 @@ type 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; @@ -922,9 +930,10 @@ type fTarget: GLuint; fAnisotropic: Integer; fDeleteTextureOnFree: Boolean; + fFreeDataOnDestroy: Boolean; fFreeDataAfterGenTexture: Boolean; fData: PByte; - fIsResident: Boolean; + fIsResident: GLboolean; fBorderColor: array[0..3] of Single; fDimension: TglBitmapPixelPosition; @@ -964,6 +973,7 @@ type 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); @@ -1002,11 +1012,12 @@ type 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; @@ -1102,7 +1113,7 @@ type 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; @@ -1224,7 +1235,9 @@ function CreateGrayPalette: HPALETTE; 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} @@ -1265,6 +1278,9 @@ type 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; @@ -2301,7 +2317,7 @@ begin end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TglBitmapFormatDescriptor/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TFormatDescriptor/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TFormatDescriptor.GetRedMask: QWord; begin @@ -2333,6 +2349,24 @@ 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); @@ -4173,6 +4207,14 @@ begin 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 @@ -4332,7 +4374,6 @@ begin fTarget := 0; fIsResident := false; - fFormat := glBitmapGetDefaultFormat; fMipMap := glBitmapDefaultMipmap; fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture; fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree; @@ -4347,8 +4388,10 @@ procedure TglBitmap.BeforeDestruction; 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; @@ -4415,7 +4458,7 @@ begin FreeMem(tmpData); raise; end; - AddFunc(Self, aFunc, false, Format, aArgs); + AddFunc(Self, aFunc, false, aFormat, aArgs); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -4953,6 +4996,42 @@ var 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 @@ -4971,10 +5050,17 @@ begin 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 @@ -5591,7 +5677,7 @@ begin 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; @@ -5621,6 +5707,8 @@ begin glbReadOpenGLExtensions; {$ENDIF} inherited Create; + fFormat := glBitmapGetDefaultFormat; + fFreeDataOnDestroy := true; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -5638,27 +5726,30 @@ begin 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); @@ -5688,7 +5779,7 @@ const 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]; @@ -5704,27 +5795,20 @@ begin 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; @@ -6290,8 +6374,8 @@ const MAGIC_LEN = 2; JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8; var - jpeg: TJPEGImage; intf: TLazIntfImage; + reader: TFPReaderJPEG; StreamPos: Int64; magic: String[MAGIC_LEN]; begin @@ -6306,28 +6390,20 @@ 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; @@ -7978,7 +8054,7 @@ procedure TglBitmap2D.GetDataFromTexture; var Temp: PByte; TempWidth, TempHeight: Integer; - TempIntFormat: Cardinal; + TempIntFormat: GLint; IntFormat, f: TglBitmapFormat; FormatDesc: TFormatDescriptor; begin @@ -8559,8 +8635,15 @@ initialization 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. \ No newline at end of file +end.