Page 3 of 3

Posted: Fri Jun 29, 2007 4:37 pm
by netmaestro
That's not surprising as no window events are being processed in between SetGadgetState commands.

Posted: Fri Jun 29, 2007 5:24 pm
by Dare
I suppose it takes a heap of API stuff to make the text background in the image and text box transparent. :?

Code: Select all

ProcedureDLL.l TicksHQ()
  Static maxfreq.q
  Protected t.q
  If maxfreq=0
    QueryPerformanceFrequency_(@maxfreq)
    maxfreq=maxfreq/1000
  EndIf
  QueryPerformanceCounter_(@t)
  ProcedureReturn t/maxfreq
EndProcedure


Structure REGIONDATA
  rdh.RGNDATAHEADER
  buffer.l[100000]
EndStructure

; ===========================================================================================

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor

  ;=======================================================
  ;                                                      =
  ;      Very fast bitmap -> region creator              =
  ;                                                      =
  ;      By netmaestro                                   =
  ;                                                      =
  ;      Contributors: eesau, nico, flype                =
  ;                                                      =
  ;      June 26, 2007                                   =
  ;                                                      =
  ;=======================================================

  Structure RGBTRIPLEC
    rgbtBlue.b
    rgbtGreen.b
    rgbtRed.b
  EndStructure

  GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP)
 
  Protected width       = bmp\bmWidth
  Protected height      = bmp\bmHeight
  Protected hVisibleRgn = CreateRectRgn_(0, 0, width, height)
  Protected tred        = Red(transcolor)
  Protected tgreen      = Green(transcolor)
  Protected tblue       = Blue(transcolor)
 
  BmiInfo.BITMAPINFOHEADER
  With BmiInfo
    \biSize         = SizeOf(BITMAPINFOHEADER)
    \biWidth        = width
    \biHeight       = -height
    \biPlanes       = 1
    \biBitCount     = 24
    \biCompression  = #BI_RGB
  EndWith   
 
  bytesperrow = 4*((3*width+3)/4)

  *ColorBits = AllocateMemory(bytesperrow*height)
  hDC   = GetWindowDC_(#Null)
  iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS)
  ReleaseDC_(#Null, hDC)
 
  Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER)
  *Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max)
  *rd.LONG=*Buffer+SizeOf(RGNDATAHEADER)

  bufferloc = 0 : rectcount = 0
  For y=0 To height-1
    pxcount=0
    For x=0 To bytesperrow-1 Step 3
      *px.RGBTRIPLEC = *ColorBits + bytesperrow * y + x
      If *px\rgbtRed&$FF=tred And *px\rgbtGreen&$FF=tgreen And *px\rgbtBlue&$FF=tblue
        transcount = 1 : firsttrans = pxcount
        While *px\rgbtRed&$FF=tred And *px\rgbtGreen&$FF=tgreen And *px\rgbtBlue&$FF=tblue  And x<=bytesperrow-4
          transcount+1 : pxcount+1 : x+3 : *px = *ColorBits + bytesperrow * y + x
        Wend
        rectcount+1
        *rd\l = firsttrans            : *rd+4
        *rd\l = y                     : *rd+4
        *rd\l = firsttrans+transcount : *rd+4
        *rd\l = y+1                   : *rd+4
      EndIf
      pxcount+1
    Next
  Next
 
  With *Buffer
    \dwSize         = SizeOf(RGNDATAHEADER)
    \iType          = #RDH_RECTANGLES
    \nCount         = rectcount
    \nRgnSize       = rectcount * SizeOf(RECT)
    \rcBound\left   = 0
    \rcBound\top    = 0
    \rcBound\right  = width
    \rcBound\bottom = height
  EndWith
 
  RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT))
  hTransparentRgn = ExtCreateRegion_(#Null, RegionSize, *Buffer)
  CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR)
   
  FreeMemory(*Buffer)
  FreeMemory(*ColorBits)
  DeleteObject_(hTransparentRgn)
 
  ProcedureReturn hVisibleRgn
 
EndProcedure 

Procedure.l counter(ctr)
  StartDrawing(WindowOutput(0))
    DrawText(130,190,"Girl "+Str(ctr),$00FF00)
  StopDrawing()
  SetGadgetText(1,Str(ctr))
  ProcedureReturn ctr+1
EndProcedure

; ===========================================================================================

LoadImage(0, "girl.bmp")

OpenWindow(0,0,0,ImageWidth(0),ImageHeight(0),"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)
CreateGadgetList(WindowID(0))
ImageGadget(0,0,0,0,0,ImageID(0))
TextGadget(1, 130,210,50,20,"")

region = GrabRegion(ImageID(0), #White)

SetWindowRgn_(WindowID(0), region, #True)
HideWindow(0,0)

tm=ElapsedMilliseconds()
Repeat
  WaitWindowEvent(100)
  If ElapsedMilliseconds() > tm + 999
    ctr=counter(ctr)
    tm=ElapsedMilliseconds()
  EndIf
Until GetAsyncKeyState_(#VK_SPACE) & 32768 

Posted: Fri Jun 29, 2007 5:46 pm
by netmaestro
No, sorry to disappoint, but no API required:

Code: Select all

;=========================================================================================== 

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor 

  ;======================================================= 
  ;                                                      = 
  ;      Very fast bitmap -> region creator              = 
  ;                                                      = 
  ;      By netmaestro                                   = 
  ;                                                      = 
  ;      Contributors: eesau, nico, flype                = 
  ;                                                      = 
  ;      June 26, 2007                                   = 
  ;                                                      = 
  ;======================================================= 

  GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) 
  
  Protected width       = bmp\bmWidth 
  Protected height      = bmp\bmHeight 
  Protected hVisibleRgn = CreateRectRgn_(0, 0, width, height) 
  Protected tred        = Red(transcolor) 
  Protected tgreen      = Green(transcolor) 
  Protected tblue       = Blue(transcolor) 
  
  BmiInfo.BITMAPINFOHEADER 
  With BmiInfo 
    \biSize         = SizeOf(BITMAPINFOHEADER) 
    \biWidth        = width 
    \biHeight       = -height 
    \biPlanes       = 1 
    \biBitCount     = 24 
    \biCompression  = #BI_RGB 
  EndWith    
  
  bytesperrow = 4*((3*width+3)/4) 

  *ColorBits = AllocateMemory(bytesperrow*height) 
  hDC   = GetWindowDC_(#Null) 
  iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS) 
  ReleaseDC_(#Null, hDC) 
  
  Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER) 
  *Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max) 
  *rd.LONG=*Buffer+SizeOf(RGNDATAHEADER) 

  bufferloc = 0 : rectcount = 0 
  For y=0 To height-1 
    pxcount=0 
    For x=0 To bytesperrow-1 Step 3 
      *px.RGBTRIPLE = *ColorBits + bytesperrow * y + x 
      If *px\rgbtRed&$FF=tred And *px\rgbtGreen&$FF=tgreen And *px\rgbtBlue&$FF=tblue 
        transcount = 1 : firsttrans = pxcount 
        While *px\rgbtRed&$FF=tred And *px\rgbtGreen&$FF=tgreen And *px\rgbtBlue&$FF=tblue  And x<=bytesperrow-4 
          transcount+1 : pxcount+1 : x+3 : *px = *ColorBits + bytesperrow * y + x 
        Wend 
        rectcount+1 
        *rd\l = firsttrans            : *rd+4 
        *rd\l = y                     : *rd+4 
        *rd\l = firsttrans+transcount : *rd+4 
        *rd\l = y+1                   : *rd+4 
      EndIf 
      pxcount+1 
    Next 
  Next 
  
  With *Buffer 
    \dwSize         = SizeOf(RGNDATAHEADER) 
    \iType          = #RDH_RECTANGLES 
    \nCount         = rectcount 
    \nRgnSize       = rectcount * SizeOf(RECT) 
    \rcBound\left   = 0 
    \rcBound\top    = 0 
    \rcBound\right  = width 
    \rcBound\bottom = height 
  EndWith 
  
  RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT)) 
  hTransparentRgn = ExtCreateRegion_(#Null, RegionSize, *Buffer) 
  CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR) 
    
  FreeMemory(*Buffer) 
  FreeMemory(*ColorBits) 
  DeleteObject_(hTransparentRgn) 
  
  ProcedureReturn hVisibleRgn 
  
EndProcedure 

Procedure.l counter(ctr) 
  srcdc = StartDrawing(WindowOutput(0)) 
    DrawImage(ImageID(1),130,190)
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(130,190,"Girl "+Str(ctr),$00FF00) 
  StopDrawing() 
  ProcedureReturn ctr+1 
EndProcedure 

; =========================================================================================== 

LoadImage(0, "girl.bmp") 

OpenWindow(0,0,0,ImageWidth(0),ImageHeight(0),"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible) 
CreateGadgetList(WindowID(0)) 
ImageGadget(0,0,0,0,0,ImageID(0)) 
DisableGadget(0,1)
GrabImage(0,1,130,190,40,20)
region = GrabRegion(ImageID(0), #White) 

SetWindowRgn_(WindowID(0), region, #True) 
HideWindow(0,0) 

tm=ElapsedMilliseconds() 
Repeat 
  WaitWindowEvent(100) 
  If ElapsedMilliseconds() > tm + 999 
    ctr=counter(ctr) 
    tm=ElapsedMilliseconds() 
  EndIf 
Until GetAsyncKeyState_(#VK_SPACE) & 32768 

Posted: Fri Jun 29, 2007 5:54 pm
by Dare
netmaestro wrote:No, sorry to disappoint, but no API required:
:lol:

Thanks mate.

And the textgadget ... if you can do that sans api I will eat my ... dinner.


(Was going to say hat but knowing you I thought it too risky - besides, I like my hat)

Posted: Fri Jun 29, 2007 6:04 pm
by netmaestro
No, I think your hat and dinner are safe enough, the textgadget would need a callback trapping WM_CTLCOLORSTATIC and returning a null brush, but even at that you'd have difficulties when the text changed as the null brush doesn't erase anything. It's solved in the drawing-to-windowoutput approach by grabbing the snapshot behind the text ahead of time and drawing first the snapshot and then the transparent text, but it's going to be a pain subclassing the textgadget and doing similar. You're best off contenting yourself with WindowOutput and be done with it.

Posted: Fri Jun 29, 2007 6:44 pm
by srod
Just seen ebs' contribution to this drag image thread - another cracker!

Great stuff.

Posted: Sat Jun 30, 2007 2:49 am
by Fangbeast
srod I think I've been asking too many questions of professor NetMaestro and taxing his health. Have you shared any food with him lately????

He looks as skinny as you do and I can't detect any humour in his posts so I should leave him alone.

/me falls off the chair, slimes through the corridor into the kitchen and goes to have breakfast.

Posted: Sat Jun 30, 2007 6:47 am
by Fangbeast
In this window, I open the drag and drop window and make an initial call to Counter with a value of 0.

The window works, counter doesn't. Yes, the procedures are declared:):)

Code: Select all

;============================================================================================================================
; Open the drag target window
;============================================================================================================================

Procedure OpenDragBox() 

  If Window_dragbox()
      
    ;SetWindowLong_(WindowID(#Window_dragbox), #GWL_EXSTYLE, GetWindowLong_(WindowID(#Window_dragbox), #GWL_EXSTYLE) | #WS_EX_TOOLWINDOW)
      
    program\dragdrop = 1
  
    AddKeyboardShortcut(#Window_dragbox, #PB_Shortcut_Alt | #PB_Shortcut_D, #Shortcut_dragbox_closedragbox)
  
    GrabImage(#Image_dragbox_dropzone, #Image_dragbox_counter, 0, 0, 60, 25)         ; Create counter image
  
    region = GrabRegion(ImageID(#Image_dragbox_dropzone), #Black)                    ; Create the region for the included picture

    SetWindowRgn_(WindowID(#Window_dragbox), region, #True)                          ; Clip the image to the calculated region
    
    hBrush = CreatePatternBrush_(ImageID(#Image_dragbox_dropzone))                   ; Set the window background to the image.
      
    SetClassLong_(WindowID(#Window_dragbox), #GCL_HBRBACKGROUND, hBrush)             ; Subclass the window to allow dragging around
    
    DrawCounter(50550500)                                                            ; Draw the counter with an initial value of 0
    
    HideWindow(#Window_dragbox, 0)                                                   ; Show the window now that everything is ready
    
    EnableWindowDrop(#Window_dragbox, #PB_Drop_Files, #PB_Drag_Copy)                 ; Enable dragging and dropping on this window
    
    StickyWindow(#Window_dragbox, 1)                                                 ; Make this window stay on top of all others
  
  EndIf

EndProcedure
Just borrowing on everyone's posts in this code and remembering that my drag and drop image is only 80x80, I thought this work work. I was wrong!

Code: Select all

;============================================================================================================================
; Draw the file count on the drop target
;============================================================================================================================

Procedure.l DrawCounter(Counter)

  StartDrawing(WindowOutput(#Window_dragbox))

    DrawImage(ImageID(#Image_dragbox_counter), 20, 20)

    DrawingMode(#PB_2DDrawing_Transparent)

    DrawText(20, 20, Str(Counter) + " Counter me baby")

  StopDrawing()

  ; ProcedureReturn ctr + 1

EndProcedure

I am extremely dumb about graphics and how they work. In 6 years of pb, this is the first time I am touching them. And advertising my lack of knowledge (Ouch!)

EDIT** Had to add in the missing command GrabImage and add the missing image constants (Doh!), that should tell you how little I understand graphics but still no go.

Posted: Sun Jul 01, 2007 9:16 am
by Fangbeast
Okay, I give up. Currently fighting with Vmware converter and that's giving me a headache.

Possible with OGRE? Trying for colorkeyed transparent win

Posted: Thu Jul 26, 2007 7:55 pm
by vrman3d
Hi Fangbeast, Netmaestro, Dare, Srod and everyone.

This is a great thread, cool stuff, and almost does what I need, HOWEVER:

Is there an easy way to set up things like this with an OGRE3D app? I have tried all sorts of things just to get a bitmap to display as the background of the 3D window to no avail. Perhaps I'm blind, but it seems like there's no way to set an image as a camera background (you can use a color, but not an image).

I'm sure there must be an easy way, since in other languages/sdks it's very common. Any ideas?

I've tried all sorts of things, including using 'Billboards' but that's a kludgy solution, and I need pixel perfect bitmap positioning, not 3d world units, and need the pixel perfect bitmap without texture filtering, etc. And what I'm really looking for is being able to update the 2D bg image on the fly (by drawing to it).

Any help would be greatly appreciated!

Best regards,
-=VRMan=-