TGC Codebase Backup



Backbuffer Transparent Box Function by Hamish McHaggis

5th Apr 2005 8:41
Summary

Function that draws a semi-transparent box to the screen. Also a good example of backbuffer access.



Description

This function reads data from the backbuffer and merges it with the new box data, based on an alpha value. It is fairly slow comparatively, but should be adaquite if you use small boxes.



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    `Backbuffer Transparent Box Demo and Function
`Joseph Thomson
`5/4/05

`This demo shows how to read and write to the backbuffer in order to create a
`transparent box without using images.  It is relatively slow, but will be ok
`if the box is kept small.

sync on
sync rate 60
autocam off
backdrop on
color backdrop rgb(255,255,255)

make object cube 1,10
position camera 0,0,-15
point camera 0,0,0

local fade as float = 1.0
local col as integer

randomize timer()

col = rgb(rnd(255),rnd(255),rnd(255))

ink 0,0

do
   `Control box changing colour
   if mouseclick() = 1
      if mouseHold = 0
         col = rgb(rnd(255),rnd(255),rnd(255))
      endif
      mouseHold = 1
   else
      mouseHold = 0
   endif

   `Control changing fading
   fade = fade + (rightkey()-leftkey())*0.01
   if fade < 0.0 then fade = 0.0
   if fade > 1.0 then fade = 1.0

   `Rotate object
   turn object right 1,1.2
   pitch object up 1,0.4

   `Print info
   text 10,10,"Backbuffer Transparent Box Demo by Joseph Thomson"
   text 10,25,"Press left and right to change transparency"
   text 10,40,"Click the left mouse button to change box colour"
   text 10,55,"Click the right mouse button to not draw box"
   text 10,70,"FPS - "+str$(screen fps())

   `Print box
   if mouseclick() <> 2 then TransparentBox(mousex()-120,mousey()-20,mousex()+120,mousey()+20,col,fade)
   sync
loop

function TransparentBox(left as integer, top as integer, right as integer, bottom as integer, colour as integer, alpha as float)
   local x as integer
   local ptr as integer
   local width as integer
   local height as integer
   local depth as integer
   local pitch as integer
   local bytesperpixel as integer
   local red as integer
   local grn as integer
   local blu as integer
   local newRed as integer
   local newGrn as integer
   local newBlu as integer
   local invAlpha as float

   `Split colour into separate components, for blending
   red = rgbr(colour)
   grn = rgbg(colour)
   blu = rgbb(colour)

   `Lock the backbuffer so we can change it
   lock backbuffer

   `Get backbuffer info
   ptr = get backbuffer ptr()          `Gets the address in memory of pixel (0,0) on the backbuffer
   width = get backbuffer width()      `Gets the screen width of the backbuffer
   height = get backbuffer height()    `Gets the screen height of the backbuffer
   depth = get backbuffer depth()      `Gets the screen depth of the backbuffer
   pitch = get backbuffer pitch()      `The pitch is the number of bytes in a single scanline across the screen
   bytesperpixel = depth/8             `Work out the bytes per pixel

   `Crop the box if it goes off the screen, otherwise it will wrap around
   if left < 0 then left = 0
   if right > width then right = width
   if top < 0 then top = 0
   if bottom > height then bottom = height

   `Work out 1-alpha value
   invAlpha = 1.0-alpha

   `Find top,left hand corner of the box
   ptr = ptr + top*pitch + left*bytesperpixel
   `Loop through all rows
   for y = top to (bottom-1)
      `Loop through all pixels on that row
      for x = left to (right-1)
         `Find a new colour by blending then existing value with the new value
         newRed = rgbr(*ptr)*invAlpha+red*alpha
         newGrn = rgbg(*ptr)*invAlpha+grn*alpha
         newBlu = rgbb(*ptr)*invAlpha+blu*alpha
         (*ptr) = rgb(newRed,newGrn,newBlu)
         `Go to the next pixel
         ptr = ptr + bytesperpixel
      next x
      `Return to the start of the row, and incriment by one scanline (ie. go to the next row)
      ptr = ptr - (bytesperpixel*(right-left)) + pitch
   next y

   `Unlock the backbuffer
   unlock backbuffer
endfunction