[futurebasic] FB3 GWorlds Refreshing/ Demo

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

From: Robert Covington <artlythere@...>
Date: Sun, 6 Jan 2002 15:00:40 -0500
>rc:
>
>Didn't you have a small demo of how one should always draw to GWorlds
>and then have "copying from it" do all the display work?
>
>If so, I would like to see that demo as well.

>tedd

Here is a new demo that was posted in portion to x-fb list...more for
others than Tedd since he has read it. Plus List Beast over there chewed me
out for posting code on an X-FB list. What irony. :)

Anyway, this is a completely new beast from that. So even Tedd can enjoy it
now. But he gets billed the $75. :)

The GWorld refresh is the basis of
"PixelManipulation.bas" of FB Example fame and a fundamental for flicker
avoidance.

Fundamental to Avoiding Flicker using any approach: Only draw/copy to any
window when you receive notice of a refresh event. Otherwise your first
drawing will be wiped out, and then redrawn again on refresh, making for
that flick.

For programs showing multiple GWorlds and other items, including Pict
sliders, direct Pixel drawing to a GWorld, and more including ant-ialiased
lines,
visit:

http://www.mindspring.com/~artlythere/fb.html

No warranties. :) Standard Software Disclaimer applies.

RC

' BEGIN FB 3 Program===============

// 2 Windows and GWorld Refresh Demo
// Robert Covington, Artly There Software
// GWorld FN's in portion via Robert Purves

// Use less globals if you can.
// Always draw into a window only on update/refresh events
// to avoid flicker, whether using GWorlds for refreshing
// or not.

// Beware email line wrap.
// "Call" is used here. Can be left out if compiler prefs are set
// to not require it.

Begin Globals
DIM gOneWorld as Long
DIM gTwoWorld as Long
DIM gOneWndGW as long
DIM gTwoWndGW as long
DIM gScreenDevice as long
DIM g1Rect as Rect
DIM g2Rect as Rect
_safeExtraMem = 128*1024

'~'2
BEGIN RECORD OpenCPicParams
DIM srcRect as Rect
DIM hRes as Fixed
DIM vRes as Fixed
DIM version as short
DIM reserved1 as short
DIM reserved2 as long
END RECORD

DIM myPic as OpenCPicParams

End globals
'~'2

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) OR (MEM(_maxAvail) < _safeExtraMem)
if myGWorld then Call DisposeGWorld(myGWorld)
myGWorld = 0
END IF
END FN = myGWorld
'~'2
// Lock GWorlds when drawing to or copying from typically.
// Can lock at creation if not doing much memory shuffling.
// But best to leave unlocked and floating so that memory
// manager can move around as needed to avoid fragmenatation.
Local
DIM err
Local FN LockGW(srcGW as long)
err = fn LockPixels( fn GetGWorldPixMap( srcGW ))
End FN = err

Local FN UnlockGW(srcGW as long)
UnlockPixels( fn GetGWorldPixMap( srcGW ) )
End FN
'~'2

local fn CopyGW2GW( srcGW as Long, destGW as Long, srcR as Ptr,¬
 destR as Ptr, cMode )
'~'1
long if ( fn LockPixels( fn GetGWorldPixMap( srcGW ) ) )
ForeColor( _blackColor )
BackColor( _whiteColor )
CopyBits( #srcGW+2, #destGW+2, #srcR, #destR, cMode, 0)
UnlockPixels( fn GetGWorldPixMap( srcGW ) )
end if
end fn


// Say you have a PICT handle from FN GetPicture(ID) or something..
// in this case, we created manually.
Local FN LoadWorlds(oneH as handle,twoH as handle)
Dim @tmpDevice as long,tmpWorld as long
gOneWorld = 0
gTwoWorld = 0
g1Rect = [oneH] + _PicFrame
g2Rect = [twoH] + _PicFrame

Call offsetRect(g1Rect,-g1Rect.top,-g1Rect.left)
Call offsetRect(g2Rect,-g2Rect.top,-g2Rect.left)

// Make a GWorld to refresh it
gOneWorld = FN CreateGWorld(g1Rect, 32) // depth of 32 , 16, 8 ,4 ...
gTwoWorld = FN CreateGWorld(g2Rect, 32) // depth of 32 , 16, 8 ,4 ...

Long if gOneWorld
FN LockGW(gOneWorld)
Call GetGWorld(tmpWorld,tmpDevice)// store current port
Call SetGWorld(gOneWorld,0)
Call DrawPicture(oneH,g1Rect)
// Or any other initial drawing you need to do
Call Hunlock(OneH)
Call KillPicture(oneH) // if not a resource handle
Call SetGWorld(tmpWorld,tmpDevice)
Xelse
End// out of RAM most likely if so.
End if
Long if gTwoWorld
FN LockGW(gTwoWorld)
Call GetGWorld(tmpWorld,tmpDevice)// store current port
Call SetGWorld(gTwoWorld,0)
Call DrawPicture(twoH,g2Rect)
// Or any other initial drawing you need to do
Call Hunlock(TwoH)
Call KillPicture(twoH)// if not a resource handle
// such as image from FN GetPicture(resourceID)
Call SetGWorld(tmpWorld,tmpDevice)
Xelse
End // out of RAM most likely if so.
End if

// Now you have GWorlds to refresh your windows from.

END FN


// In DoDialog
Local FN DoDialog
DIM evnt,id
evnt = dialog(0)
id = dialog(evnt)
Select evnt
Case _WndRefresh // or PG equivalent
Long if Id = 1 and gOneWorld <> 0
FN CopyGW2GW(gOneWorld,gOneWndGW,g1Rect, g1Rect,_srcCopy)
End if
Long if Id = 2 and gTwoWorld <> 0
FN CopyGW2GW(gTwoWorld,gTwoWndGW,g2Rect, g2Rect,_srcCopy)
End if
case _WndClose
Select id
case 1
// If not a demo...
//If gOneWorld then Call DisposeGWorld(gOneWorld):gOneWorld = 0
//Window Close id
End
case 2
// If not a demo...
//If gTwoWorld then Call DisposeGWorld(gTwoWorld):gTwoWorld = 0
//Window Close id
End
End Select
end select
End FN

Local FN MakeItSo
Dim @tmpDevice as long,tmpWorld as long
DIM @Pict1H as handle
DIM @Pict2H as handle
DIM i as int

Pict1H = 0
Pict2H = 0

Call SetRect(g1Rect,0,0,300,400)
Call SetRect(g2Rect,0,0,400,300)

// Make a window
Window 1,"OneWorld - Any Key To Quit",@g1Rect,_DocNoGrow
Call GetGWorld(gOneWndGW,gScreenDevice)
Window 2,"TwoWorld - Any Key To Quit",@g2Rect,_DocNoGrow
Call GetGWorld(gTwoWndGW,gScreenDevice)
// If using a resource handle, then the window making could
// be up above in LoadWorlds before the drawing portion.

Window Output 1
CALL GETGWORLD(tmpWorld,tmpDevice)
myPic.srcRect;8 = @g1Rect
myPic.hRes=FN LONG2FIX(72) // 72 DPI
myPic.vRes=FN LONG2FIX(72) // 72 DPI
myPic.version=-2
SETGWORLD(gOneWndGW,0)
Pict1H = FN opencpicture(@myPic)
Color _zCyan
Call PaintRect(g1Rect)
For i = 0 to 24
Color RND(7)
Plot RND(300),rnd(400) to RND(300),rnd(400)
Next i
Call MoveTo(20,20)
Color _ZBlack
Text _SysFont,12
Print "Image 1"
Call ClosePicture
CALL SETGWORLD(tmpWorld,tmpDevice)

Call HLOCK(Pict1H) // Lock it down

Window Output 2
CALL GETGWORLD(tmpWorld,tmpDevice)
myPic.srcRect;8 = @g2Rect
myPic.hRes=FN LONG2FIX(72) // 72 DPI
myPic.vRes=FN LONG2FIX(72) // 72 DPI
myPic.version=-2
SETGWORLD(gTwoWndGW,0)
Pict2H = FN opencpicture(@myPic)
Color _zMagenta
Call PaintRect(g2Rect)
For i = 0 to 24
Color RND(7)
Plot RND(400),rnd(300) to RND(400),rnd(300)
Next i
Call MoveTo(20,20)
Color _ZBlack
Text _SysFont,12
Print "Image 2"
Call ClosePicture
CALL SETGWORLD(tmpWorld,tmpDevice)

Call HLOCK(Pict2H)// Lock it down

// Houston, We have Images
Long if Pict1H <> 0 and Pict2H <> 0
FN LoadWorlds(Pict1H,Pict2H)
XElse
Beep
End If
End FN

"MAIN"

// Reserve some memory
DIM System(2048000)

On dialog FN DoDialog

FN MakeItSo

Do
HandleEvents
until LEN(inkey$) // Any Key To Quit (or close a window via Closebox)

' END FB 3 Program===============