[comp.sys.amiga.tech] Double-Buffering in a window

pa2027@sdcc13.ucsd.edu (Stupendous Man) (12/29/89)

First off, I'd like to thank all those who replied to and helped me
with mutual exclude gadgetry...

Another thing I'm having trouble with is double-buffering in a
window (not the entire screen).  I'd like to be able to draw to an
offscreen bitmap and then switch the offscreen to the bitmap the
window is using.  Is there a fairly straightforward method?

thanks in advance!

-Brad


--
Michael Butler - "Water, water everywhere nor any drop to drink"-
S.T. Coleridge and Iron Maiden////   Brad McQuaid - When reality
obscures your dreams, mind becomes a graveyard of memories, that
wander like the lonely breeze... -Fates Warning, No Exit

mike@ames.arc.nasa.gov (Mike Smithwick) (01/02/90)

["never trust a surgeon with shaving cuts"]

In article <5839@sdcc6.ucsd.edu> pa2027@sdcc13.ucsd.edu (Stupendous Man) writes:
>
>
>I'd like to be able to draw to an
>offscreen bitmap and then switch the offscreen to the bitmap the
>window is using.  Is there a fairly straightforward method?
>

Simple! Just create an offscreen Rastport, render into to it to your
hearts desire, then do a ClipBlit into your window's Rastport. That's
what I do for Geotime. It may not be fast enough for full animation, but
for clean transitions between two images it works fine.

mike



                                                      *** mike smithwick ***

"When I was 18 I joined the centrifigal Air-force"
[disclaimer : nope, I don't work for NASA, I take full blame for my ideas]

a464@mindlink.UUCP (Bruce Dawson) (01/02/90)

     Screens are hardware entities, consisting of a set of rectangular (as
rectangular as a linear chunk of memory can be) bit planes.  They can be moved
by adjusting pointers into the copper list so as to adjust pointers in the
display chip.

     Windows are software entities.  The illusion of hidden portions of windows
and the ability to move windows around is done completely by the grunt method
of picking up data and moving it, and storing hidden stuff off screen.  So no,
you can't double buffer a window by changing pointers.  Some graphics chips let
you have hardware windows, but not the Amiga's.

.Bruce.

pa2027@sdcc13.ucsd.edu (Stupendous Man) (01/02/90)

>Simple! Just create an offscreen Rastport, render into it to your
hearts desire, then do a clipblit....

I did this with BltBitMap, and thought it was fast enough, it
produced an annoying and unprofressional looking flicker. Is
ClipBlit any faster?

What I'd like to know how to do is 'just' switch the address to the
windows bitmap... but then there's no bitmap for a Window structure,
only a NewWindow.

Can it be done?

-brad


--
Michael Butler - "Water, water everywhere nor any drop to drink"-
S.T. Coleridge and Iron Maiden////   Brad McQuaid - When reality
obscures your dreams, mind becomes a graveyard of memories, that
wander like the lonely breeze... -Fates Warning, No Exit

mapjilg@gdr.bath.ac.uk (J I L Gold) (01/03/90)

OK, after the rather vague reply yesterday, here's some source to help
you on your way: this works in a non-Intuition environment. This will
illustrate the principle. (BTW, blitting the regions as suggested by
the others works but can lead to flicker).
  	
	#include <exec/types.h>
		 <graphics/gfx.h>
		 <graphics/rastport.h>
		 <graphics/copper.h>
		 <graphics/regions.h>
		 <graphics/clip.h>
		 <graphics/gfxbase.h>

	struct View View;
	struct ViewPort ViewPort;
	struct RasInfo RasInfos[2];
	struct BitMap BitMaps[2];
	struct RastPort RastPorts[2];
	struct View *OldView;
	struct cprlist *LOF[2],*SHF[2] /* to store copper list 
					  addresses            */
        struct GfxBase *GfxBase;
	.
	.
	main() {
	/* initialisation (opening relevant libraries) */
	.
	.
	OldView = GfxBase->ActiView; /* Save the current screen */
	ViewPort.D(x y)Offset = top left corner of viewport;
	ViewPort.D(Width Height) = size of viewport;
	ViewPort.RasInfo = &RasInfos[0];
	ViewPort.Modes = whatever;
	ViewPort.Next = NULL; /* Only one viewport! */

	RasInfos[0].Next = &RasInfos[1]; 

	/*Allocate the bitmap memory here for both bitmaps */
	.
	.
	/* Now the tricky bit..compute the copper lists for the
	   viewport... */
	MakeVPort(&View,&ViewPort);
	/* ...merge with the system copper list... */
	MrgCop(&View);
	/* ...and save. */
	LOF[0] = View.LOFCprList;
	SHF[0] = View.SHFCprList;
	/* Now set the viewport up to use the second bitmap/rastport
	   etc... */
	ViewPort.RasInfo = &RasInfos[1];
	/* ...and do the same for this bitmap... */
	/* EXCEPT set the copper list pointers in the View
	structure to NULL otherwise Ami assumes that the 
	copper list has already been defined and will not make
	a second one...*/
	View.LOFCprList = View.SHFCprList = NULL;
	MakeVPort(&View,&ViewPort);
	MrgCop(&View);
	LOF[1] = View.LOFCprList;
	SHF[1] = View.SHFCprList;
	/* OK, all set up. To do the buffering, the code will look
	like this... */

	dbuff = 0;
	while (some condition) {
		/* Clear the hidden screen ... */
		SetRast(&RastPorts[dbuff],0); 
		/* Now draw into it... */
		Move(&RastPorts[dbuff],x1,y1);
		Draw(&RastPorts[dbuff],x2,y2);
		/* Now flip the screens by swapping copper lists... */
		View.LOFCprList = LOF[dbuff];
		View.SHFCprList = SHF[dbuff];
		LoadView(&View);
		WaitTOF(); /* Optional but preferable! */
		dbuff ^= 1; /* Next screen */
	}
	LoadView(OldView);
	/* Free up copper list memory... */
	FreeVPortCopLists(&ViewPort);
	for(i=0 ; i < 2 ; i++){
		FreeCprList(LOF[i]);
		FreeCprList(SHF[i]);
        }
	/* Free bitmap memory and tidy up here */
	.
	.
	CloseLibrary(GfxBase);
}

You should be able to do this with Intuition by accesing the relevant
structures through the window structure. Hope this is of help (bloody
better be after all this typing!)
	Happy New Year :-)
	 J.Gold
	 mapjilg@uk.ac.bath.gdr

mapjilg@gdr.bath.ac.uk (J I L Gold) (01/04/90)

In article <885@mindlink.UUCP> a464@mindlink.UUCP (Bruce Dawson) writes:
>
>     Screens are hardware entities, consisting of a set of rectangular (as
>rectangular as a linear chunk of memory can be) bit planes.  They can be moved
>by adjusting pointers into the copper list so as to adjust pointers in the
>display chip.
>
>     Windows are software entities.  The illusion of hidden portions of windows
>and the ability to move windows around is done completely by the grunt method
>of picking up data and moving it, and storing hidden stuff off screen.  So no,
>you can't double buffer a window by changing pointers.  Some graphics chips let
>you have hardware windows, but not the Amiga's.
>

Um, ok! But, a window still has an associated ViewPort,RastPort,BitMap etc. So
you can still re-connect your own BitMap to the existing one,still have access
to the copper lists through the ViewPort, and make use of RemakeDisplay() to
re-calculate the copper lists. No?
 
 -- 

-- 
#------------------------------------------------------------------------------#
# Paranoia is thinking that if something CAN'T go wrong it will still go wrong.#
#------------------------------------------------------------------------------#
#  J.Gold                            |    mapjilg@uk.ac.bath.gdr               #

a464@mindlink.UUCP (Bruce Dawson) (01/05/90)

     All of the windows in a screen share the same bitmap (at least for their
visible portions, which is what you're interested in).  So, if you want to
double buffer one window, you've got to double buffer all of them.  The entire
screen gets flipped all at once.  So, unless you first copy the contents of the
entire screen to the hidden buffer, the other windows are going to flashing on
and off as you flip bitmaps.

.Bruce.

new@udel.edu (Darren New) (01/06/90)

In article <1990Jan4.104416.15515@gdt.bath.ac.uk> you write:
>In article <885@mindlink.UUCP> a464@mindlink.UUCP (Bruce Dawson) writes:
>>
>>     Screens are hardware entities, consisting of a set of rectangular (as
>>     Windows are software entities.  The illusion of hidden portions of windows
>Um, ok! But, a window still has an associated ViewPort,RastPort,BitMap etc. So
>you can still re-connect your own BitMap to the existing one,still have access
>to the copper lists through the ViewPort, and make use of RemakeDisplay() to
>re-calculate the copper lists. No?

I'm fairly sure that the ViewPort for all windows on the same screen is the
same pointer.  Also, I think the RastPort is a pointer into a bigger BitMap.
The only way to do what you want under intuition (as far as I know) is to
use a super-bitmap window (use your wheels, it is what they are for...)
This gives you a private area that can be scrolled onto and off of
another screen, but still probably not at full copper-pointing speed.
Consider that you cannot have two views on the same scanline...
How would you change a pointer on one window to have it display different
memory than the memory in the window just to the left of it? -- Darren

mapjilg@gdr.bath.ac.uk (J I L Gold) (01/10/90)

In article <897@mindlink.UUCP> a464@mindlink.UUCP (Bruce Dawson) writes:
>
>     All of the windows in a screen share the same bitmap (at least for their
>visible portions, which is what you're interested in).  So, if you want to
>double buffer one window, you've got to double buffer all of them.  The entire
>screen gets flipped all at once.  So, unless you first copy the contents of the
>entire screen to the hidden buffer, the other windows are going to flashing on
>and off as you flip bitmaps.
>

However you do have access to the layers through CopySBitMap() and SyncSBitMap()
which I'm reliably informed do the job nicely!
-- 
J.Gold | mapjilg@uk.ac.bath.gdr

-- 
#------------------------------------------------------------------------------#
# Paranoia is thinking that if something CAN'T go wrong it will still go wrong.#
#------------------------------------------------------------------------------#
#  J.Gold                            |    mapjilg@uk.ac.bath.gdr               #

jsmith@alias.UUCP (Jeff Smith) (01/11/90)

I have only done simple double buffering on the Amiga, but I use a techniqwe
that, while it is a kludge, works well enough for my purposes. Having picked
up this thread 'already in progress' I'm not sure if this has been mentioned
or not. Disclaimers thus suitably behind us...

I usually open two, coincident windows and write to one, then the other.
The act of swapping buffers is just a matter of promoting the back window
to the front. You have to watch for WINDOWDRAG events and make sure that
if the user moves one window, the other moves with it, but those are trivial
niceties. 

I'm certain that there are other methods that will work much faster, but this
is a quick hack that I have put into a link module of my own. If and when a
better method comes my way, I'll probably switch.

Hope somebody can use this.

Smitty

hassell@tramp.Colorado.EDU (Christopher Hassell) (01/12/90)

<1990Jan10.134148.21435@gdt.bath.ac.uk> mapjilg@gdr.bath.ac.uk (J I L Gold) :
# In article <897@mindlink.UUCP> a464@mindlink.UUCP (Bruce Dawson) writes:
# >
# >     All of the windows in a screen share the same bitmap (at least for their
# >visible portions, which is what you're interested in).  So, if you want to
#>double buffer one window, you've got to double buffer all of them.  The entire
#>screen gets flipped all at once.  So, unless you first copy the contents of 
	the
#>entire screen to the hidden buffer, the other windows are going to flashing on
# >and off as you flip bitmaps.
# >
# 
# However you do have access to the layers through CopySBitMap() and SyncSBitMap()
# which I'm reliably informed do the job nicely!
# -- 
# J.Gold | mapjilg@uk.ac.bath.gdr
# 

Those ARE valid software techniques.  I'm not giving any advice here... just
dreaming a bit:

But ..... it would be nice 
	A: if the copper could blit stuff around CONSTANTLY (as in every scan)			from a different and wierd portion of separate memory
	B: if there was a simple option in the copper which allowed you to
		SIMPLY CHANGE THE SCAN-ADDRESS WITHIN A SCAN-LINE AND WORSE.

If/When the amiga basically cannot keep its innards together and it explodes
into a multiprocessing machine (which should be alot more blase' to make in la
future).... wouldn't it be nice to LITERALLY have "windows" into memory....
windows into displays that are configured who-knows-where in that Meg or two
your A500 enjoys?

So much for problems with multitasking and display-haggling... they wouldn't
even need to be resolved by a window manager... below a certain level... they,
screen conflicts, would simply never occur because the screen only chose to
listen to specific parts of any program's actual workings.

I like the idea personally... if I get enough money.. I might even try to hack
something like that together on a little dead Apple //+ (where everything is
socketed). 

It would be mucho nicer on the amiga, of course.

Your arguments are valid for what should be done.  I believe that there are
"windowing" graphics-management chips out there which do exactly what I said...
but they are definately high-end and somewhat restrictive.

Latuh.
# -- 
# #------------------------------------------------------------------------------#
# # Paranoia is thinking that if something CAN'T go wrong it will still go wrong.#
# #------------------------------------------------------------------------------#
# #  J.Gold                            |    mapjilg@uk.ac.bath.gdr               #


### C>H> ### { uunet!rutgers!sunybcs , ncar , nbires } !boulder!tramp!hassell