Circle in & circle out effect
BlitzMax Forums/BlitzMax Programming/Circle in & circle out effect
| ||
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. |
| ||
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 |
| ||
Clever! |
| ||
Or you can use DrawPoly, like this: |
| ||
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). |