Large tilesets - grabbing an alphablended sprite

Share your advanced PureBasic knowledge/code with the community.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Large tilesets - grabbing an alphablended sprite

Post by netmaestro »

Someone correct me if I'm wrong, but I know of no native way to grab individual sprites off a large tileset if you need #PB_Sprite_Alphablending under the DX9 subsystem. Unless you catch or load a sprite directly, your alphablending is going to wind up on a black background, as in GrabImage-StartDrawing(SpriteOutput())-DrawAlphaImage() etc. or DisplaySprite-GrabSprite. This is not true of DX7, but under DX9 it's a problem. What if you have a large tileset with 50 images on it and they need alphablending because of antialiased edges or dropshadowing? Are you stuck with cutting them out in Photoshop or similar and IncludeBinary-ing each and every individual one so you can catch it directly? This is the dilemma facing me currently, and here's how I solved it:

Code: Select all

Procedure GrabSprite_I32(image, sprite, x, y, w, h)

  ; netmaestro December 2008
  ; Grabs an alphablended sprite located at x,y 
  ; and with specified width=w And height=h
  ; from a 32bit image in memory

  Protected tmp,Bmp.BITMAP,BmiInfo.BITMAPV5HEADER,sz_colorbits
  Protected sz_image,*rawimage,*fileheader.BITMAPFILEHEADER
  Protected *header.BITMAPV5HEADER,result

  tmp = GrabImage(image, #PB_Any, x,y,w,h)
  If tmp And GetObject_(ImageID(tmp), SizeOf(BITMAP), Bmp)
    With BmiInfo
      \bV5Size         = SizeOf(BITMAPV5HEADER) 
      \bV5Width        = Bmp\bmWidth 
      \bV5Height       = Bmp\bmHeight
      \bV5Planes       = 1 
      \bV5BitCount     = 32 
      \bV5Compression  = #BI_RGB  
    EndWith 
  Else
    ProcedureReturn 0
  EndIf
  sz_colorbits = w*h*4
  sz_image = SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPV5HEADER) + sz_colorbits
  *rawimage = AllocateMemory(sz_image) 
  *fileheader = *rawimage 
  *header = *rawimage + SizeOf(BITMAPFILEHEADER) 
  With *fileheader 
    \bfType = PeekW(@"BM")
    \bfSize = sz_image 
    \bfOffBits = SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPV5HEADER) 
  EndWith 
  CopyMemory(BmiInfo, *header, SizeOf(BITMAPV5HEADER)) 
  CopyMemory(Bmp\bmBits, *rawimage + SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPV5HEADER), sz_colorbits) 
  result = CatchSprite(sprite,*rawimage,#PB_Sprite_Texture|#PB_Sprite_AlphaBlending)
  FreeMemory(*rawimage) : FreeImage(tmp)
  
  ProcedureReturn result
  
EndProcedure
Pretty much solved, it works fine for me. Maybe it's of some use to you?
BERESHEIT
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I think the Screen itself has no Alphachannel since it has no "backdrop"...?
(it has 32bit but the alpha is not used...?)
the Alpha is only an Information how much of the existing backdrop is to be mixed into the currently displayed texture.
the completed screenpicture does not need any Alpha, so there is none, or is there?
oh... and have a nice day.
Post Reply