CustomFilterCallback: lParam

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

CustomFilterCallback: lParam

Post by netmaestro »

For the project I'm currently working on I would like to produce crossplatform code. I know several ways to draw 24bit images transparently, they're all fast and they all work well - and they're all windows-specific. So I tested the native 2DDrawing library (which is awesome btw) and found that a custom filter callback is:

a) suited to the purpose
b) fast enough for seamless animation

So, great! a native crossplatform solution. However, we cannot pass anything in the way of further information to the callback. All it gets and all it wants are x, y, SourceColor, TargetColor and those are passed by the 2DDrawing library. I can add nothing to it. So I have to make my transparent color global or something. Not optimal.

If the prototype of the FilterCallback were CustomFilterProc(x, y, SourceColor, TargetColor, [, lParam]) then current code wouldn't break and I could pass the transparent color (or a pointer to a structure with lots of info in it), generally enhancing the usability of the callback.

btw, I'm saying lParam because I code for windows and that's the term I'm used to. But userdata, customdata, etc. might be more suitable choices for a crossplatform library.

Code: Select all

Procedure FilterCallback(x, y, SourceColor, TargetColor)
  If SourceColor&$FFFFFF = RGB(255,0,255) ; I'm hardcoding this here because I can't pass it as parameter :-(
    ProcedureReturn TargetColor
  Else
    ProcedureReturn SourceColor
  EndIf
EndProcedure

CreateImage(1, 128,128,24,RGB(255,0,255)) ; pink for a transparent color
StartDrawing(ImageOutput(1))
  Circle(64,64,60,#Blue)
StopDrawing()

If OpenWindow(0, 0, 0, 256,256, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowColor(0, RGB(255,255,223))
  
  If CreateImage(0, 128, 128, 24, GetWindowColor(0)) And StartDrawing(ImageOutput(0))
      DrawingMode(#PB_2DDrawing_CustomFilter)      
      CustomFilterCallback(@FilterCallback())
      DrawImage(ImageID(1), 0, 0)
    StopDrawing() 
    ImageGadget(0, 64, 64, 0, 00, ImageID(0))
  EndIf
  
  Repeat
    Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
EndIf
BERESHEIT
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: CustomFilterCallback: lParam

Post by freak »

> So I have to make my transparent color global or something. Not optimal.

I thought about it, but the 2ddrawing lib would just store the value in a global variable too and then pass it back to the function. It would be no different, just not visible.

> CustomFilterProc(x, y, SourceColor, TargetColor, lParam=0)

Unfortunately this is not possible. Callbacks must have a fixed number of parameters. So its either always with the extra parameter or never.
quidquid Latine dictum sit altum videtur
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: CustomFilterCallback: lParam

Post by netmaestro »

Fair enough, I can live with that.
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: CustomFilterCallback: lParam

Post by netmaestro »

I made a codeblock I can just stick at the top of my program and forget about. It allows me to use the feature just as if it were actually there:

Code: Select all

;////////////////////////////////////////////////////////////////////

; Boilerplate code - do not edit                                  

Global gFilterUserData                                            

Macro UseFilterProc(callback, lParam=0)                           
  gFilterUserData.i = lParam                                      
  CustomFilterCallback(callback)                                  
EndMacro                                                          

Procedure TransparentDrawing24(x, y, SourceColor, TargetColor)    
  If SourceColor&$FFFFFF = gFilterUserData                        
    ProcedureReturn TargetColor                                   
  Else                                                            
    ProcedureReturn SourceColor                                   
  EndIf                                                           
EndProcedure                                                      
;////////////////////////////////////////////////////////////////////

CreateImage(1, 128,128,24,RGB(255,0,255)) ; pink for a transparent color
StartDrawing(ImageOutput(1))
  Circle(64,64,60,#Blue)
StopDrawing()

If OpenWindow(0, 0, 0, 256,256, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowColor(0, RGB(255,255,223))
  
  If CreateImage(0, 128, 128, 24, GetWindowColor(0)) And StartDrawing(ImageOutput(0))
      DrawingMode(#PB_2DDrawing_CustomFilter)      
      UseFilterProc(@TransparentDrawing24(), RGB(255,0,255))
      x=ElapsedMilliseconds()
      DrawImage(ImageID(1), 0, 0)
      y=ElapsedMilliseconds()
    StopDrawing() 
    ImageGadget(0, 64, 64, 0, 00, ImageID(0))
  EndIf
  SetWindowTitle(0, "Drawing time: "+Str(y-x)+" ms")
  Repeat
    Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
EndIf
BERESHEIT
Post Reply