C'est bien que tu soit passé sous Linux , tu vas pouvoir bricolé des truc sympas
ce code manipule les pixels avec la portabilité Linux / Windows en tenant en compte du subsystem
( le codage des couleurs n'est pas le même RGBA ARGB RGB BGR Y inversé... )
On peut aussi mélangé les couleurs comme le fait OpenGL ou DirectX avec les facteurs destination & source !
C'est pas pour du temps réel , mais pour appliqué des Filtres , faire des mélanges de manière ponctuelle.
Code : Tout sélectionner
; -----------------------------------------------------
; PBDDS API FOR PUREBASIC 4.40 , 4.41
;
; -----------------------------------------------------
; DIRECT DRAWING SCREEN API FOR PUREBASIC
; -----------------------------------------------------
; By Cpl.Bator
;
; Work on PureBasic 4.41 x86
; - Linux ( SDL & OPENGL Subsytem )
; - Windows XP ( DIRECTX 9 , DIRECTX 7 , OPENGL Subsytem )
;
; Not tested on MacOS.
; Note for MacOS , you must add code to the procedures :
;
; - PBDDS_FlipToScreen()
; - PBDDS_FlipToSprite()
; -----------------------------------------------------
Procedure PBDDS_ErrorHandler()
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
OpenConsole()
PrintN("PUREBASIC DIRECT DRAWING SCREEN EXCEPTION AT LINE ("+Str(ErrorLine())+") :"+ErrorMessage()+Chr(10))
CompilerElse
MessageRequester("Error","PUREBASIC DIRECT DRAWING SCREEN EXCEPTION AT LINE ("+Str(ErrorLine())+") :"+ErrorMessage())
CompilerEndIf
EndProcedure
; --------------------------------------------------------------------------------------------------------------
Procedure.f min(a.f, d.f)
If a < d
ProcedureReturn a
Else
ProcedureReturn d
EndIf
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Constante de blending , similaire à OpenGL
; --------------------------------------------------------------------------------------------------------------
Enumeration
#PBDDS_ZERO
#PBDDS_ONE
#PBDDS_DST_COLOR
#PBDDS_SRC_COLOR
#PBDDS_ONE_MINUS_DST_COLOR
#PBDDS_ONE_MINUS_SRC_COLOR
#PBDDS_SRC_ALPHA
#PBDDS_ONE_MINUS_SRC_ALPHA
#PBDDS_DST_ALPHA
#PBDDS_ONE_MINUS_DST_ALPHA
#PBDDS_SRC_ALPHA_SATURATE
EndEnumeration
; --------------------------------------------------------------------------------------------------------------
; Structure d'un buffer vidéo
; il contient :
; - les pixels ( suivant le format )
; - la taille en hauteur et largeur du buffer
; - le format du pixel
; - si le buffer est inversé ( OpenGL & linux par exemple )
; - information si la couleur est en RGB ou BGR
; - si le blending est activé ou non
; - le mode de blending destination / source ( identique à OpenGL )
; --------------------------------------------------------------------------------------------------------------
Structure PBDDS_Buffer_Video
*mDatas.l ; Pixel storage.
mBufferWidth.l
mBufferHeight.l
mBufferPixelFormat.l ; Pixel format
mBufferReversedY.a ;OpenGL Write upper line at the bottom of memory
mBufferMemoryOrder.a ;RGB Or BGR
mBlending.a
mBufferBlendSCR.l
mBufferBlendDST.l
EndStructure
; --------------------------------------------------------------------------------------------------------------
Global *__PBDDS_CURRENT_BUFFER__.PBDDS_Buffer_Video = #Null
; --------------------------------------------------------------------------------------------------------------
; --------------------------------------------------------------------------------------------------------------
; Creation d'un buffer video de la taille voulue
; Par défaut , le buffer n'utilise pas le blending pour les couleurs
; Le dernier Buffer créer deviens le buffer courant
; --------------------------------------------------------------------------------------------------------------
Procedure.l PBDDS_CreateBuffer(Width.l,Height.l)
CompilerIf #PB_Compiler_Debugger = #False
OnErrorCall(@PBDDS_ErrorHandler())
CompilerEndIf
*Buffer.PBDDS_Buffer_Video = AllocateMemory(SizeOf(PBDDS_Buffer_Video))
With *Buffer
\mBufferWidth = Width
\mBufferHeight = Height
\mBufferReversedY = #False
\mBufferBlendSCR = #PBDDS_ZERO ;#PBDDS_SRC_ALPHA
\mBufferBlendDST = #PBDDS_ONE ;#PBDDS_ONE_MINUS_SRC_ALPHA
\mBlending = #False
StartDrawing(ScreenOutput())
BufferPixelFormat = DrawingBufferPixelFormat()
StopDrawing()
If BufferPixelFormat & #PB_PixelFormat_8Bits : \mBufferPixelFormat = 1 : \mBufferMemoryOrder=0 : EndIf
If BufferPixelFormat & #PB_PixelFormat_15Bits : \mBufferPixelFormat = 2 : \mBufferMemoryOrder=0 : EndIf
If BufferPixelFormat & #PB_PixelFormat_16Bits : \mBufferPixelFormat = 2 : \mBufferMemoryOrder=0 : EndIf
If BufferPixelFormat & #PB_PixelFormat_24Bits_RGB : \mBufferPixelFormat = 3 : \mBufferMemoryOrder=1 : EndIf
If BufferPixelFormat & #PB_PixelFormat_24Bits_BGR : \mBufferPixelFormat = 3 : \mBufferMemoryOrder=2 : EndIf
If BufferPixelFormat & #PB_PixelFormat_32Bits_RGB : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=1 : EndIf
If BufferPixelFormat & #PB_PixelFormat_32Bits_BGR : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=2 : EndIf
If BufferPixelFormat & #PB_PixelFormat_ReversedY : \mBufferReversedY = #True : EndIf ; FOR OPENGL SUBSYSTEM
\mDatas = AllocateMemory( \mBufferWidth * \mBufferHeight *\mBufferPixelFormat )
EndWith
*__PBDDS_CURRENT_BUFFER__ = *Buffer
ProcedureReturn *Buffer
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Active ou Desactive (True ou False) le blending sur le buffer courrant
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_Blending(state.a)
*__PBDDS_CURRENT_BUFFER__\mBlending = state
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Selectionne le mode de blending source et destination ( Paramètres identique à OpenGL )
; Le Blending doit être activé avec la fonction PBDDS_Blending()
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_BlendingMode(FACTOR_SRC.l , FACTOR_DST.l)
With *__PBDDS_CURRENT_BUFFER__
\mBufferBlendDST = FACTOR_DST
\mBufferBlendSCR = FACTOR_SRC
EndWith
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Cette fonction renvois la bonne couleur suivant le format ( RGB ou BGR )
; #Null pour les couleurs en 8/15/16 bits.
; --------------------------------------------------------------------------------------------------------------
Procedure.l PBDDS_Color(Red.a,Green.a,Blue.a,Alpha.a)
With *__PBDDS_CURRENT_BUFFER__
If \mBufferMemoryOrder=2
ProcedureReturn RGBA(Blue,Green,Red,Alpha)
EndIf
If \mBufferMemoryOrder=1
ProcedureReturn RGBA(Red,Green,Blue,Alpha)
EndIf
ProcedureReturn #Null
EndWith
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Change le buffer courant par le buffer passé en paramètre.
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_UseBuffer(*Buffer.PBDDS_Buffer_Video)
*__PBDDS_CURRENT_BUFFER__ = *Buffer
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Ajoute un pixel sur le buffer courrant
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_SetPixel( x.l , y.l , color.l )
With *__PBDDS_CURRENT_BUFFER__
CompilerIf #PB_Compiler_Debugger = #False
OnErrorCall(@PBDDS_ErrorHandler())
CompilerEndIf
BufferColor = PeekI(\mDatas + ( x * \mBufferPixelFormat) + \mBufferWidth * ( y * \mBufferPixelFormat))
; No blending operation
If \mBlending = #False
Select \mBufferPixelFormat
Case 4:
PokeL(\mDatas + ( x * \mBufferPixelFormat) + \mBufferWidth * ( y * \mBufferPixelFormat), color)
Case 3:
*Ptr = \mDatas + ( x * \mBufferPixelFormat) + \mBufferWidth * ( y * \mBufferPixelFormat)
PokeA(*Ptr , color & $FF)
PokeA(*Ptr+1 , color >>8 & $FF)
PokeA(*Ptr+2 , color >>16 & $FF)
EndSelect
; With blending Operation
ElseIf \mBlending = #True
int_a.l = (BufferColor & $FF):int_b.l = (BufferColor >> 8 & $FF):int_c.l = (BufferColor >> 16 & $FF):int_d.l = (BufferColor >> 24 & $FF)
Rd_.f = int_a / 255
Gd_.f = int_b / 255
Bd_.f = int_c / 255
Ad_.f = int_d / 255
int_a.l = (color & $FF):int_b.l = (color >> 8 & $FF):int_c.l = (color >> 16 & $FF):int_d.l = (color >> 24 & $FF)
Rs_.f = int_a / 255
Gs_.f = int_b / 255
Bs_.f = int_c / 255
As_.f = int_d / 255
f.f = min(As_,1-Ad_)
Select \mBufferBlendSCR
Case #PBDDS_ZERO : Sr.f = 0 : Sg.f = 0 : Sb.f = 0 : Sa.f = 0
Case #PBDDS_ONE : Sr.f = 1 : Sg.f = 1 : Sb.f = 1 : Sa.f = 1
Case #PBDDS_DST_COLOR : Sr.f = Rd_ : Sg.f = Gd_ : Sb.f = Bd_ : Sa.f = Ad_
Case #PBDDS_ONE_MINUS_DST_COLOR : Sr.f = 1-Rd_ : Sg.f = 1-Gd_ : Sb.f = 1-Bd_ : Sa.f = 1-Ad_
Case #PBDDS_SRC_ALPHA : Sr.f = As_ : Sg.f = As_ : Sb.f = As_ : Sa.f = As_
Case #PBDDS_ONE_MINUS_SRC_ALPHA : Sr.f = 1-As_ : Sg.f = 1-As_ : Sb.f = 1-As_ : Sa.f = 1-As_
Case #PBDDS_DST_ALPHA : Sr.f = Ad_ : Sg.f = Ad_ : Sb.f = Ad_ : Sa.f = Ad_
Case #PBDDS_ONE_MINUS_DST_ALPHA : Sr.f = 1-Ad_ : Sg.f = 1-Ad_ : Sb.f = 1-Ad_ : Sa.f = 1-Ad_
Case #PBDDS_SRC_ALPHA_SATURATE : Sr.f = f : Sg.f = f : Sb.f = f : Sa.f = 1
EndSelect
Select \mBufferBlendDST
Case #PBDDS_ZERO : Dr.f = 0 : Dg.f = 0 : Db.f = 0 : Da.f = 0
Case #PBDDS_ONE : Dr.f = 1 : Dg.f = 1 : Db.f = 1 : Da.f = 1
Case #PBDDS_SRC_COLOR : Dr.f = Rs_ : Dg.f = Gs_ : Db.f = Bs_ : Da.f = As_
Case #PBDDS_ONE_MINUS_SRC_COLOR : Dr.f = 1-Rs_ : Dg.f = 1-Gs_ : Db.f = 1-Bs_ : Da.f = 1-As_
Case #PBDDS_SRC_ALPHA : Dr.f = As_ : Dg.f = As_ : Db.f = As_ : Da.f = As_
Case #PBDDS_ONE_MINUS_SRC_ALPHA : Dr.f = 1-As_ : Dg.f = 1-As_ : Db.f = 1-As_ : Da.f = 1-As_
Case #PBDDS_DST_ALPHA : Dr.f = Ad_ : Dg.f = Ad_ : Db.f = Ad_ : Da.f = Ad_
Case #PBDDS_ONE_MINUS_DST_ALPHA : Dr.f = 1-Ad_ : Dg.f = 1-Ad_ : Db.f = 1-Ad_ : Da.f = 1-Ad_
EndSelect
; Paste pixel with the correct pixel format
Select \mBufferPixelFormat
Case 3:
R.f = (Rs_ * Sr + Rd_ * Dr)
G.f = (Gs_ * Sg + Gd_ * Dg)
B.f = (Bs_ * Sb + Bd_ * Db)
*Ptr = \mDatas + ( x * \mBufferPixelFormat) + \mBufferWidth * ( y * \mBufferPixelFormat)
PokeA(*Ptr ,R*255)
PokeA(*Ptr+1 ,G*255)
PokeA(*Ptr+2 ,B*255)
Case 4:
R.f = Rs_ * Sr + Rd_ * Dr
G.f = Gs_ * Sg + Gd_ * Dg
B.f = Bs_ * Sb + Bd_ * Db
A.f = As_ * Sa + Ad_ * Da
PokeI(\mDatas + ( x * \mBufferPixelFormat) + \mBufferWidth * ( y * \mBufferPixelFormat), RGBA(R*255,G*255,B*255,A*255))
EndSelect
EndIf
EndWith
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Lit un pixel sur le buffer courant , retourne la couleur
; --------------------------------------------------------------------------------------------------------------
Procedure.l PBDDS_GetPixel(x.l,y.l)
With *__PBDDS_CURRENT_BUFFER__
CompilerIf #PB_Compiler_Debugger = #False
OnErrorCall(@PBDDS_ErrorHandler())
CompilerEndIf
ProcedureReturn PeekI(\mDatas + ( x * \mBufferPixelFormat) + \mBufferWidth * ( y * \mBufferPixelFormat))
EndWith
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Envois un buffer sur l'écran PureBasic , le buffer doit avoir la même taille que l'écran
; La hauteur de l'écran doit être passé en paramètres pour la rastérization.
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_FlipToScreen(H.l)
With *__PBDDS_CURRENT_BUFFER__
StartDrawing(ScreenOutput())
*ScreenBuffer = DrawingBuffer()
LineBufferSize = DrawingBufferPitch()
For Y = 0 To H-1
; ------------------------------------------------------------------------------------------------------------
; Linux
; ------------------------------------------------------------------------------------------------------------
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
MemorySrc.l = \mDatas + \mBufferWidth * (Y * \mBufferPixelFormat)
If \mBufferReversedY = #True
MemoryDst = *ScreenBuffer + LineBufferSize * (((\mBufferHeight-1)-Y))
Else
MemoryDst = *ScreenBuffer + \mBufferWidth * (Y * \mBufferPixelFormat)
EndIf
MemorySizeOf = \mBufferWidth * \mBufferPixelFormat
CopyMemory(MemorySrc,MemoryDst,MemorySizeOf)
CompilerEndIf
; ------------------------------------------------------------------------------------------------------------
; Windows
; ------------------------------------------------------------------------------------------------------------
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
MemorySrc.l = \mDatas + \mBufferWidth * (Y * \mBufferPixelFormat)
; DIRECTX COMPATIBILITY
;Directx9 (Default)
MemoryDst = *ScreenBuffer + (LineBufferSize/\mBufferPixelFormat) * (Y * \mBufferPixelFormat)
;Directx7
CompilerIf Subsystem("directx7")
MemoryDst = *ScreenBuffer + LineBufferSize * Y
CompilerEndIf
; OPENGL COMPATIBILITY
CompilerIf Subsystem("opengl")
If \mBufferReversedY = #True
MemoryDst = *ScreenBuffer + LineBufferSize * (((\mBufferHeight-1)-Y))
Else
MemoryDst = *ScreenBuffer + \mBufferWidth * (Y * \mBufferPixelFormat) ; NOT TESTED !
EndIf
CompilerEndIf
MemorySizeOf = \mBufferWidth * \mBufferPixelFormat
CopyMemory(MemorySrc,MemoryDst,MemorySizeOf)
CompilerEndIf
; ------------------------------------------------------------------------------------------------------------
; MacOS
; ------------------------------------------------------------------------------------------------------------
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
CompilerEndIf
Next
StopDrawing()
EndWith
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Envois un buffer sur un sprite purebasic , le buffer doit avoir la même taille que le sprite
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_FlipToSprite(SpriteID.l)
With *__PBDDS_CURRENT_BUFFER__
StartDrawing(SpriteOutput(SpriteID))
*ScreenBuffer = DrawingBuffer()
LineBufferSize = DrawingBufferPitch()
For Y = 0 To SpriteHeight(SpriteID)-1
; ------------------------------------------------------------------------------------------------------------
; Linux
; ------------------------------------------------------------------------------------------------------------
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
MemorySrc.l = \mDatas + \mBufferWidth * (Y * \mBufferPixelFormat)
If \mBufferReversedY = #True
MemoryDst = *ScreenBuffer + LineBufferSize * (((\mBufferHeight-1)-Y))
Else
MemoryDst = *ScreenBuffer + \mBufferWidth * (Y * \mBufferPixelFormat)
EndIf
MemorySizeOf = \mBufferWidth * \mBufferPixelFormat
CopyMemory(MemorySrc,MemoryDst,MemorySizeOf)
CompilerEndIf
; ------------------------------------------------------------------------------------------------------------
; Windows
; ------------------------------------------------------------------------------------------------------------
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
MemorySrc.l = \mDatas + \mBufferWidth * (Y * \mBufferPixelFormat)
; DIRECTX COMPATIBILITY
;Directx9 (Default)
MemoryDst = *ScreenBuffer + (LineBufferSize/\mBufferPixelFormat) * (Y * \mBufferPixelFormat)
;Directx7
CompilerIf Subsystem("directx7")
MemoryDst = *ScreenBuffer + LineBufferSize * Y
CompilerEndIf
; OPENGL COMPATIBILITY
CompilerIf Subsystem("opengl")
If \mBufferReversedY = #True
MemoryDst = *ScreenBuffer + LineBufferSize * (((\mBufferHeight-1)-Y))
Else
MemoryDst = *ScreenBuffer + \mBufferWidth * (Y * \mBufferPixelFormat) ; NOT TESTED !
EndIf
CompilerEndIf
MemorySizeOf = \mBufferWidth * \mBufferPixelFormat
CopyMemory(MemorySrc,MemoryDst,MemorySizeOf)
CompilerEndIf
; ------------------------------------------------------------------------------------------------------------
; MacOS
; ------------------------------------------------------------------------------------------------------------
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
CompilerEndIf
Next
StopDrawing()
EndWith
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Rempli le buffer très rapidement avec la couleur choisie
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_FillBuffer( color.l )
With *__PBDDS_CURRENT_BUFFER__
FillMemory(\mDatas,MemorySize(\mDatas),color,#PB_Long)
EndWith
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Dessine un rectance dans le buffer , ne pas utilisé en temps réel.
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_DrawRect( x.l , y.l , w.l , h.l , color.l )
With *__PBDDS_CURRENT_BUFFER__
For _y = y To y+h
For _x = x To x+w
;If _x => 0 And x <= \mBufferWidth-1 And _y=>0 And y <= \mBufferHeight-1
CompilerIf #PB_Compiler_Debugger = #False
OnErrorCall(@PBDDS_ErrorHandler())
CompilerEndIf
BufferColor = PeekI(\mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat))
; No blending operation
If \mBlending = #False
Select \mBufferPixelFormat
Case 3:
PokeL(\mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat), color)
Case 4:
*Ptr = \mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat)
PokeA(*Ptr , color & $FF)
PokeA(*Ptr+1 , color >>8 & $FF)
PokeA(*Ptr+2 , color >>16 & $FF)
EndSelect
; With blending Operation
ElseIf \mBlending = #True
int_a.l = (BufferColor & $FF):int_b.l = (BufferColor >> 8 & $FF):int_c.l = (BufferColor >> 16 & $FF):int_d.l = (BufferColor >> 24 & $FF)
Rd_.f = int_a / 255
Gd_.f = int_b / 255
Bd_.f = int_c / 255
Ad_.f = int_d / 255
int_a.l = (color & $FF):int_b.l = (color >> 8 & $FF):int_c.l = (color >> 16 & $FF):int_d.l = (color >> 24 & $FF)
Rs_.f = int_a / 255
Gs_.f = int_b / 255
Bs_.f = int_c / 255
As_.f = int_d / 255
f.f = min(As_,1-Ad_)
Select \mBufferBlendSCR
Case #PBDDS_ZERO : Sr.f = 0 : Sg.f = 0 : Sb.f = 0 : Sa.f = 0
Case #PBDDS_ONE : Sr.f = 1 : Sg.f = 1 : Sb.f = 1 : Sa.f = 1
Case #PBDDS_DST_COLOR : Sr.f = Rd_ : Sg.f = Gd_ : Sb.f = Bd_ : Sa.f = Ad_
Case #PBDDS_ONE_MINUS_DST_COLOR : Sr.f = 1-Rd_ : Sg.f = 1-Gd_ : Sb.f = 1-Bd_ : Sa.f = 1-Ad_
Case #PBDDS_SRC_ALPHA : Sr.f = As_ : Sg.f = As_ : Sb.f = As_ : Sa.f = As_
Case #PBDDS_ONE_MINUS_SRC_ALPHA : Sr.f = 1-As_ : Sg.f = 1-As_ : Sb.f = 1-As_ : Sa.f = 1-As_
Case #PBDDS_DST_ALPHA : Sr.f = Ad_ : Sg.f = Ad_ : Sb.f = Ad_ : Sa.f = Ad_
Case #PBDDS_ONE_MINUS_DST_ALPHA : Sr.f = 1-Ad_ : Sg.f = 1-Ad_ : Sb.f = 1-Ad_ : Sa.f = 1-Ad_
Case #PBDDS_SRC_ALPHA_SATURATE : Sr.f = f : Sg.f = f : Sb.f = f : Sa.f = 1
EndSelect
Select \mBufferBlendDST
Case #PBDDS_ZERO : Dr.f = 0 : Dg.f = 0 : Db.f = 0 : Da.f = 0
Case #PBDDS_ONE : Dr.f = 1 : Dg.f = 1 : Db.f = 1 : Da.f = 1
Case #PBDDS_SRC_COLOR : Dr.f = Rs_ : Dg.f = Gs_ : Db.f = Bs_ : Da.f = As_
Case #PBDDS_ONE_MINUS_SRC_COLOR : Dr.f = 1-Rs_ : Dg.f = 1-Gs_ : Db.f = 1-Bs_ : Da.f = 1-As_
Case #PBDDS_SRC_ALPHA : Dr.f = As_ : Dg.f = As_ : Db.f = As_ : Da.f = As_
Case #PBDDS_ONE_MINUS_SRC_ALPHA : Dr.f = 1-As_ : Dg.f = 1-As_ : Db.f = 1-As_ : Da.f = 1-As_
Case #PBDDS_DST_ALPHA : Dr.f = Ad_ : Dg.f = Ad_ : Db.f = Ad_ : Da.f = Ad_
Case #PBDDS_ONE_MINUS_DST_ALPHA : Dr.f = 1-Ad_ : Dg.f = 1-Ad_ : Db.f = 1-Ad_ : Da.f = 1-Ad_
EndSelect
; Paste pixel with the correct pixel format
Select \mBufferPixelFormat
Case 3:
R.f = (Rs_ * Sr + Rd_ * Dr)
G.f = (Gs_ * Sg + Gd_ * Dg)
B.f = (Bs_ * Sb + Bd_ * Db)
*Ptr = \mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat)
PokeA(*Ptr ,R*255)
PokeA(*Ptr+1 ,G*255)
PokeA(*Ptr+2 ,B*255)
Case 4:
R.f = Rs_ * Sr + Rd_ * Dr
G.f = Gs_ * Sg + Gd_ * Dg
B.f = Bs_ * Sb + Bd_ * Db
A.f = As_ * Sa + Ad_ * Da
PokeI(\mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat), RGBA(R*255,G*255,B*255,A*255))
EndSelect
EndIf
;EndIf
Next
Next
EndWith
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Charge une image et la convertie en Buffer
; ( le fait de ne pas utilisé d'api est volontaire , c'est pour assurer la portabilité )
; Renvois -1 si l'image n'a pas été chargé , pensé à utilisé les décodeurs purebasic pour les format "exotique"
; --------------------------------------------------------------------------------------------------------------
Procedure.l PBDDS_LoadBuffer(file.s)
Image = LoadImage(#PB_Any,file)
If Image
*Buffer.PBDDS_Buffer_Video = AllocateMemory(SizeOf(PBDDS_Buffer_Video))
With *Buffer
\mBufferWidth = ImageHeight(Image)
\mBufferHeight = ImageWidth(Image)
\mBufferReversedY = #False
\mBufferBlendSCR = #PBDDS_ZERO ;#PBDDS_SRC_ALPHA
\mBufferBlendDST = #PBDDS_ONE ;#PBDDS_ONE_MINUS_SRC_ALPHA
\mBlending = #False
StartDrawing(ScreenOutput())
BufferPixelFormat = DrawingBufferPixelFormat()
StopDrawing()
;OpenGL HACK , set PixFormat for All to 4 !
If BufferPixelFormat & #PB_PixelFormat_8Bits : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=0 : EndIf
If BufferPixelFormat & #PB_PixelFormat_15Bits : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=0 : EndIf
If BufferPixelFormat & #PB_PixelFormat_16Bits : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=0 : EndIf
If BufferPixelFormat & #PB_PixelFormat_24Bits_RGB : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=1 : EndIf
If BufferPixelFormat & #PB_PixelFormat_24Bits_BGR : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=2 : EndIf
If BufferPixelFormat & #PB_PixelFormat_32Bits_RGB : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=1 : EndIf
If BufferPixelFormat & #PB_PixelFormat_32Bits_BGR : \mBufferPixelFormat = 4 : \mBufferMemoryOrder=2 : EndIf
If BufferPixelFormat & #PB_PixelFormat_ReversedY : \mBufferReversedY = #True : EndIf ; FOR OPENGL SUBSYSTEM
\mDatas = AllocateMemory( \mBufferWidth * \mBufferHeight *\mBufferPixelFormat )
EndWith
PBDDS_UseBuffer(*Buffer)
StartDrawing(ImageOutput(Image)) : DrawingMode(#PB_2DDrawing_AlphaBlend )
For y = 0 To ImageHeight(Image)-1
For x = 0 To ImageWidth(Image)-1
Color = Point(x,y)
R=Red(Color)
G=Green(Color)
B=Blue(Color)
A=Alpha(Color)
PBDDS_SetPixel( x , y , PBDDS_Color(R,G,B,A) )
Next
Next
StopDrawing()
FreeImage(Image)
ProcedureReturn *Buffer
EndIf
ProcedureReturn -1
EndProcedure
; --------------------------------------------------------------------------------------------------------------
; Ajoute un buffer passé en paramètres dans le buffer courant
; Le blending se fera suivant le Buffer qui est passé en paramètre.
; --------------------------------------------------------------------------------------------------------------
Procedure PBDDS_PasteBuffer(*Buffer.PBDDS_Buffer_Video, x.l , y.l)
With *__PBDDS_CURRENT_BUFFER__
realx.l=0
realy.l=0
For _y = y To y+*Buffer\mBufferHeight-1
For _x = x To x+*Buffer\mBufferWidth-1
;If _x => 0 And x <= \mBufferWidth-1 And _y=>0 And y <= \mBufferHeight-1
CompilerIf #PB_Compiler_Debugger = #False
OnErrorCall(@PBDDS_ErrorHandler())
CompilerEndIf
SourceColor = PeekL(\mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat))
BufferColor = PeekL(*Buffer\mDatas + ( realx * *Buffer\mBufferPixelFormat) + *Buffer\mBufferWidth * ( realy * *Buffer\mBufferPixelFormat))
; No blending operation
If *Buffer\mBlending = #False
Select \mBufferPixelFormat
Case 4:
If \mBufferMemoryOrder = 1
PokeL(\mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat), BufferColor)
ElseIf \mBufferMemoryOrder = 2
RC.a=Red(BufferColor)
GC.a=Green(BufferColor)
BC.A=Blue(BufferColor)
AC.a=Alpha(BufferColor)
PokeL(\mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat), RGBA(RC,GC,BC,AC))
EndIf
Case 3:
*Ptr = \mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat)
PokeA(*Ptr , BufferColor & $FF)
PokeA(*Ptr+1 , BufferColor >>8 & $FF)
PokeA(*Ptr+2 , BufferColor >>16 & $FF)
EndSelect
; With blending Operation
ElseIf *Buffer\mBlending = #True
int_a.l = (SourceColor & $FF):int_b.l = (SourceColor >> 8 & $FF):int_c.l = (SourceColor >> 16 & $FF):int_d.l = (SourceColor >> 24 & $FF)
Rd_.f = int_a / 255
Gd_.f = int_b / 255
Bd_.f = int_c / 255
Ad_.f = int_d / 255
int_a.l = (BufferColor & $FF):int_b.l = (BufferColor >> 8 & $FF):int_c.l = (BufferColor >> 16 & $FF):int_d.l = (BufferColor >> 24 & $FF)
Rs_.f = int_a / 255
Gs_.f = int_b / 255
Bs_.f = int_c / 255
As_.f = int_d / 255
f.f = min(As_,1-Ad_)
Select *Buffer\mBufferBlendSCR
Case #PBDDS_ZERO : Sr.f = 0 : Sg.f = 0 : Sb.f = 0 : Sa.f = 0
Case #PBDDS_ONE : Sr.f = 1 : Sg.f = 1 : Sb.f = 1 : Sa.f = 1
Case #PBDDS_DST_COLOR : Sr.f = Rd_ : Sg.f = Gd_ : Sb.f = Bd_ : Sa.f = Ad_
Case #PBDDS_ONE_MINUS_DST_COLOR : Sr.f = 1-Rd_ : Sg.f = 1-Gd_ : Sb.f = 1-Bd_ : Sa.f = 1-Ad_
Case #PBDDS_SRC_ALPHA : Sr.f = As_ : Sg.f = As_ : Sb.f = As_ : Sa.f = As_
Case #PBDDS_ONE_MINUS_SRC_ALPHA : Sr.f = 1-As_ : Sg.f = 1-As_ : Sb.f = 1-As_ : Sa.f = 1-As_
Case #PBDDS_DST_ALPHA : Sr.f = Ad_ : Sg.f = Ad_ : Sb.f = Ad_ : Sa.f = Ad_
Case #PBDDS_ONE_MINUS_DST_ALPHA : Sr.f = 1-Ad_ : Sg.f = 1-Ad_ : Sb.f = 1-Ad_ : Sa.f = 1-Ad_
Case #PBDDS_SRC_ALPHA_SATURATE : Sr.f = f : Sg.f = f : Sb.f = f : Sa.f = 1
EndSelect
Select *Buffer\mBufferBlendDST
Case #PBDDS_ZERO : Dr.f = 0 : Dg.f = 0 : Db.f = 0 : Da.f = 0
Case #PBDDS_ONE : Dr.f = 1 : Dg.f = 1 : Db.f = 1 : Da.f = 1
Case #PBDDS_SRC_COLOR : Dr.f = Rs_ : Dg.f = Gs_ : Db.f = Bs_ : Da.f = As_
Case #PBDDS_ONE_MINUS_SRC_COLOR : Dr.f = 1-Rs_ : Dg.f = 1-Gs_ : Db.f = 1-Bs_ : Da.f = 1-As_
Case #PBDDS_SRC_ALPHA : Dr.f = As_ : Dg.f = As_ : Db.f = As_ : Da.f = As_
Case #PBDDS_ONE_MINUS_SRC_ALPHA : Dr.f = 1-As_ : Dg.f = 1-As_ : Db.f = 1-As_ : Da.f = 1-As_
Case #PBDDS_DST_ALPHA : Dr.f = Ad_ : Dg.f = Ad_ : Db.f = Ad_ : Da.f = Ad_
Case #PBDDS_ONE_MINUS_DST_ALPHA : Dr.f = 1-Ad_ : Dg.f = 1-Ad_ : Db.f = 1-Ad_ : Da.f = 1-Ad_
EndSelect
; Paste pixel with the correct pixel format
Select \mBufferPixelFormat
Case 3:
R.f = (Rs_ * Sr + Rd_ * Dr)
G.f = (Gs_ * Sg + Gd_ * Dg)
B.f = (Bs_ * Sb + Bd_ * Db)
A.f = As_ * Sa + Ad_ * Da
*Ptr = \mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat)
PokeA(*Ptr ,R*255)
PokeA(*Ptr+1 ,G*255)
PokeA(*Ptr+2 ,B*255)
Case 4:
R.f = Rs_ * Sr + Rd_ * Dr
G.f = Gs_ * Sg + Gd_ * Dg
B.f = Bs_ * Sb + Bd_ * Db
A.f = As_ * Sa + Ad_ * Da
PokeL(\mDatas + ( _x * \mBufferPixelFormat) + \mBufferWidth * ( _y * \mBufferPixelFormat), RGBA(R*255,G*255,B*255,A*255))
EndSelect
EndIf
;EndIf
realx + 1
Next
realx = 0
realy + 1
Next
EndWith
EndProcedure
;
; ;-TEST
;
;
; ExamineDesktops()
;
; DW = DesktopWidth(0)
; DH = DesktopHeight(0)
; DD = DesktopDepth(0)
;
;
; InitSprite()
; InitKeyboard()
; InitMouse()
;
; OpenScreen(DW,DH,32,"")
;
; BufferDeBase = PBDDS_CreateBuffer(DW,DH)
; PBDDS_FillBuffer(PBDDS_Color(255,255,255,255))
;
;
; UsePNGImageDecoder()
; Brush = PBDDS_LoadBuffer("./brush4.png")
; PBDDS_Blending(#True)
; PBDDS_BlendingMode(#PBDDS_SRC_ALPHA,#PBDDS_ONE_MINUS_SRC_ALPHA)
;
; PBDDS_UseBuffer(BufferDeBase)
;
; ; For i = 0 To 200
; PBDDS_PasteBuffer(Brush,10,10)
; ; Next
;
;
; PBDDS_Blending(#True)
; PBDDS_BlendingMode(#PBDDS_SRC_ALPHA,#PBDDS_ONE_MINUS_SRC_ALPHA)
; PBDDS_DrawRect(10 , 10 ,DW-20,200 , PBDDS_Color(255,0,0,64) )
;
; KeyboardMode(#PB_Keyboard_International)
; ReleaseMouse(0)
; Repeat
;
;
;
; ExamineMouse() : ExamineKeyboard()
;
; mx + MouseDeltaX()/10
; my + MouseDeltaY()/10
;
; If MouseButton(1)
; PBDDS_UseBuffer(BufferDeBase)
; PBDDS_PasteBuffer(Brush,mx,my)
; EndIf
;
; If T<ElapsedMilliseconds()
; T = ElapsedMilliseconds()+30
;
; ClearScreen($FFFFFF)
; PBDDS_FlipToScreen(DH)
;
; StartDrawing(ScreenOutput())
; DrawingMode(#PB_2DDrawing_Outlined)
; Circle(Mx+8,My+8,8,$0)
; StopDrawing()
; FlipBuffers()
; EndIf
;
;
;
;
;
;
;
;
; Until KeyboardPushed(#PB_Key_Escape)
; End