Circle in & circle out effect

BlitzMax Forums/BlitzMax Programming/Circle in & circle out effect

salric(Posted 2006) [#1]
Hi all,

I'm trying to create a transition effect where the screen is wiped to black by a circle that zooms to the center. To clarify, when the effect starts, the circle is larger than the screen and keeps reducing in size to the point where there is a single pixel in the middle. At the 1/2 way point you would have 1/2 the screen in the middle still visible within the circle, everything outside the circle would be black.

I hope I've been clear in trying to explain the effect, it if helps I think batman (the TV series had a similar effect except the circle was the batman logo?

My problems are:

1) Pixmaps are too slow to draw a circle mask each frame
2) How does one draw an 'inverse circle' quickly ? i.e. a rect with a circle punched out of the middle

Can anyone think of an easy way to achieve this effect keeping in mind that I would like to keep the game animating while the transition is in progress (i.e. the effect should make minimal use of resources)

Anyhow - I look forward to any help that you can provide.


salric(Posted 2006) [#2]
It seems that writing the above question helped me answer it, in particular - the description of 'circle punched out of the middle of a rect' gave me an idea.

How I've achieved the effect is quite simple in the end; I make a masked image with a circle punched out of the middle, draw this image over the everything (scaled) and then draw rects on all sides of it - I've included the code for anyone that's interested.


' circle mask effect

Graphics 640,480,0
AutoMidHandle True
'create the mask image
Local timask=CreateImage(640,480,1,MASKEDIMAGE | DYNAMICIMAGE | FILTEREDIMAGE)
'set mask color to white
SetMaskColor 255,255,255
'draw white circle on black b/g
SetColor 255,255,255
DrawOval 0,0,640,480
'grab background into timask
GrabImage timask,0,0

Local done:Int=False
Local sc:Float=2

Repeat
	Cls
	For a=1 To 5000
		SetColor Rand(1,255),Rand(1,255),Rand(1,255)
		Plot Rand(1,640),Rand(1,480)
	Next

		'reduce scale of mask
	sc=sc-.01

	'draw boxes on either side of circle mask
	SetScale 1,1
	SetColor 0,0,0
	DrawRect 0,0,640,ImageHeight(timask)/2-(ImageHeight(timask)/2*sc)
	DrawRect 0,ImageHeight(timask)/2+(ImageHeight(timask)/2*sc),640,480
	DrawRect 0,0,ImageWidth(timask)/2-(ImageWidth(timask)/2*sc),480
	DrawRect ImageWidth(timask)/2+(ImageWidth(timask)/2*sc),0,640,480
	


	'draw circle mask
	SetScale sc,sc
	SetColor 255,255,255
	DrawImage timask,ImageWidth(timask)/2,ImageHeight(timask)/2
	
	Flip
	If KeyDown(key_escape) Then done=True
Until done=True




Ziltch(Posted 2006) [#3]
Clever!


fredborg(Posted 2006) [#4]
Or you can use DrawPoly, like this:



ImaginaryHuman(Posted 2006) [#5]
The way I do this in OpenGL is pre-draw a screen full of circles, starting with the biggest diameter and working down, changing the color value by 1 for each circle, and only drawing 256 circles in total. I save this as an alpha pixmap and upload it as a GL_ALPHA texture. Then I switch off drawing to alpha, but draw a textured quad over the screen with the alpha texture map, set up so that bits greater than a given value are drawn to the stencil buffer. Then I draw the `game screen`, taking the stencil into account so that only pixels not stencilled are drawn. This way you can do per-pixel wipes (hint: distort the image containing the circles).