[futurebasic] Re: [FB] Pixel Graphics

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : January 2008 : Group Archive : Group : All Groups

From: Robert Covington <artlythere@...>
Date: Wed, 23 Jan 2008 05:41:44 -0500
On Jan 23, 2008, at 3:57 AM, Bernie wrote:

> RC wrote:
>> I replied to him offlist, for fear of posting a demo with a global  
>> in it. ;)
> I'll have your globals. I love them. I'm having globals globals  
> globals globals globals...

Now there's a fine coder. A lovely coder. A world class global villager.

> Please post the demo. If anyone complains, we'll send in the vikings.
> Bernie

Please send in the Vikings. Just not those from the Capital One  

Beware the email line wrap! Any weird errors, check for invisible bad  
characters Mail added. (Delete spaces, add back , usually infests dim  
areas, or = )

Composed using Carbon App, Appearance Runtime

'-------------------------------- Cut From Below , Ever Onward

// Begin listing/lecture. ;) One Way To Do Things. Not Set Out As The  
// Note: If the listing becomes too pronounced, please move to the  
other side of the ship.
// Any buyer's agents on board, please advise the listing agents to  
get with the program.

// Cheesey Demo of Gworlds, pixel getting and setting
// Robert Covington Jan 22, 2008 , artlythere@...

Dim gRect     as Rect// Because I'm not a rectless driver.
Dim gWorld    as long// Because I never forget a phase.
dim gRowBytes as long// Guard dog bytes.
dim gBaseAddr as long// More Base, less treble. Er, trouble.
dim gCycle    as int // Incrementer for Mass Effector
dim gDestGW   as long// Yer Winder Port thingie
dim gTestPixel
end globals // It's a Global Village. Be a World Class Coder, not a  
'local' hick. :)

  // Lovely thingie gets around carnage from GWorlds larger than 4096  
pixels on a side
toolbox fn GetPixRowBytes(PixMapHandle pm) = long

local fn CopyGW2GW( srcGW as Long, destGW as Long, srcR as Ptr, destR  
as Ptr, cMode )

//lock. Not usually a problem, but when it is, -there's- a bug! :)
long if ( fn LockPixels( fn GetGWorldPixMap( srcGW ) ) )
// Prevent all manner of colorized heck
ForeColor( _blackColor )
BackColor( _whiteColor )
CopyBits( #srcGW+2, #destGW+2, #srcR, #destR, cMode, 0)
UnlockPixels( fn GetGWorldPixMap( srcGW ) )
end if

end fn

  // Can move this to any local function. But why remove the need for  
a global! :)
LOCAL FN GetBaseBytes(theGWorld as long)
' get information needed to manipulate a GWorld's pixels directly
DIM pmHandle as handle to pixMap
pmHandle = FN GETGWORLDPIXMAP(theGWorld)
//gRowBytes = pmHandle..RowBytes AND 0x3FFF
gRowBytes = fn GetPixRowBytes(pmHandle)
gBaseAddr = FN GETPIXBASEADDR(pmHandle)

// Make an invisble offscreen window for your graphics edification.  
// Illumination. Colorization. Pixelation.
// I digress.
local fn CreateGWorld(theRect as pointer to rect, depth)
dim qdErr
DIM @ myGWorld as long
qdErr = FN NEWGWORLD(myGWorld, depth, #theRect, 0,0,0)
LONG IF (qdErr != _noErr)
if myGWorld then Call DisposeGWorld(myGWorld)
myGWorld = 0
END FN = myGWorld

clear local
// No, I'm not lazy for using Clear. :)
// Programming environments should do -more- things for the user not  
// One bonus is that Clear saves a lot of typing to manually init vars.
//  Leaving me more time to write comments like this. :)
local fn CycleColors
dim as long xx,yy
dim as long maxX,maxY,btY
dim as int r,g,b,locked
dim pixPtr as ptr

locked = fn LockPixels( fn GetGWorldPixMap( gWorld ) )

long if locked

maxX = gRect.right-1
maxY = gRect.bottom-1

long if gCycle < 3
for yy = 0 to maxY
bty = gBaseAddr + (yy*gRowbytes) // optimizer
for xx = 0 to maxX
pixPtr = bty + (xx*4) // 32 bit gworld = xx*4, 16 bit = xx*2, 8 bit =  
xx, so on

// Pixel data is 0 to 255, 256 values per channel

select gCycle
case 0
pixPtr.1`` = 255
pixPtr.2`` = 0
pixPtr.3`` = 0
case 1
pixPtr.1`` = 0
pixPtr.2`` = 255
pixPtr.3`` = 0
case 2
pixPtr.1`` = 0
pixPtr.2`` = 0
pixPtr.3`` = 255
end select

next xx
next yy
// Manually do something else
for yy = 0 to maxY
bty = gBaseAddr + (yy*gRowbytes)
for xx = 0 to maxX
pixPtr = bty + (xx*4)
r = pixPtr.1``
g = pixPtr.2``
b = pixPtr.3``

pixPtr.1`` = 127
pixPtr.2`` = 127
pixPtr.3`` = 127

next xx
next yy
end if

if gCycle = 4 then gCycle = 0

end if

end fn

local Fn BlitIt

dim as long @tmpGW,tmpDevice // @ yields register vars, sometimes  
required here

fn CopyGW2GW( gWorld,gDestGW, gRect, gRect, _srcCopy )

// if ever in your world you do not see this instantly, or soon ,  
call FlushWindowBuffer. Somewhere appropriate.
end fn

local Fn DoMouse // Very Basic Mouse thingie
dim pt as point
dim myRGB as RGBColor


// Colors here are from 0 to 65535
Stop "Red = " + STR$(myRgb.red) + " Green = " + STR$(myRgb.green) + "  
Blue = " + STR$(myRGB.blue) // Press Continue!
while Fn StillDown // One time Only, get out after
// Not Carbon Friendly at all. Don't hold down your mouse too long.
Fn CycleColors // Bitwhack here
Fn BlitIt// Copy result to window here
end fn

"MAIN" // In the

dim as long @tmpGW,tmpDevice // @ yields register vars, sometimes  
required for toolbox use

SetRect(gRect,0,0,400,400) // We are shooting for a handy 400 x 400  
pixel window

gWorld = FN CreateGWorld(gRect, 32) // make a same sized port

long if gWorld // Created?
Window 1, "Click In Window To Change Colors", @gRect,_DocNoGrow //  
GetGWorld(gDestGW,tmpDevice)// Store port for copying need
SetGWorld(gWorld,0)// Set to that port
FN GetBaseBytes(gWorld)// Go ahead and get the goodies
Color _zMagenta // Paint it magenta to start with
PaintRect(gRect) // Fill that buffer
Color _zBlack // reset color
Fn BlitIt // Premier first Copy


Text _SrcCopy
Print %(20,20) "Click in window to get a color via GetCPixel"
Print %(20,40) "Then to change colors via GWorld PixelWhacking"
Print %(20,60) "press Continue in the STOP Dialog."
Print %(20,80) "Command-Q To Quit"
FlushWindowBuffer// Slight delay otherwise waiting for event loop to  
kick in (here at least) :)
end if

on mouse fn DoMouse // Our only even vector

until gFBQuit // Command-Q to Quit

if gWorld then DisposeGWorld(gWorld) // Clean up after yourself