Ok, here is an idiot proof function demonstrating what I mean

. Making it taught me something about backbuffer access too...
`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
Isn't it? Wasn't it? Marvellous!
