Older Version
Newer Version
RodBird
Sep 15, 2016
- "Reverted to Jan 30, 2016 2:34 pm: Reverted deleted article"
RodBird
Sep 15, 2016
- "Reverted to Jan 30, 2016 2:34 pm: Reverted deleted article"
Having fun with the blitter
authorTable of Contents
What is it?
If you like messing with graphics the blitter could be your best friend. Back in the early days graphics used to be written to and from a memory location by the processor itself. The PC used a videosync timer to poll the memory and paint the graphics to the screen. You had to code carefully to be sure your drawing was finished before the videosync kicked in.Blitting hardware was developed to allow large areas of graphics to be copied and pasted in memory without requiring processor cycles. This vastly improved animation and drawing that could be achieved between videosync events.
Graphics have evolved still more and now its all "surfaces" and openGL rendering or DirectX rendering, but you can still have a lot of fun with the blitter.
Display Timing
How fast can we show blitted graphics? Notice I said "show". A moden PC's graphics card renders screen images at 60hz, or a frame every 16.6ms. Now the blitter is much much faster than this but there is little point in blitting for blittings sake if the graphic image is only shown once every 16.6ms.So its best to use the Liberty BASIC TIMER statement to control a drawing loop to slow things down and not waste time drawing graphics that are never seen.
While the TIMER uses millisecond values you will find that 16.6ms is the smallest value it can discern. Run the code below and see how the TIMER value jumps in 16.6ms increments. This is because Windows updates it's clock at 60hz.
So, don't try and run your TIMER loop faster than 17ms, the TIMER statement won't run any faster.
In actual fact animation will run perfectly well at lower speed. The speed of your processor and graphics card will determine what is achievable but stay in tune with your PC, anything between 50ms and 100ms provide watchable animation.
Blitter Functionality
Blitting swaps one area of graphic for another. The blitter can merge, overwrite or transparently combine the graphics. It can flip, mirror, stretch or shrink the image as it does so. Animation is achieved by moving one image relative to the other.Blitting is usually associated with animation though it is equally happy stretching, blending, flipping or compressing static images.
Blitter code
You will need to cut and paste these blitter functions to the foot of each of the following code examples. We will run an example then explain what the functions do.How fast is the Blitter?
Lets run some unrestricted code on your machine to see what blitting performance you get. The code will create a copy of your screen, select an image into it and then blit it back to the screen repeatedly. It is important to remember that we are not blitting directly to the screen in front of you but to the memory that defines that screen, lets call it the screen buffer. The blitting will be very fast, run it now.Fantastic result? unbelievably fast? you bet. On my machine which is a middle of the road laptop I rendered the half megabyte of graphics in 420 milliseconds, that's over 2300 frames per second, wow!
Now of course you didn't see anything. First because it was a black image blitted over a black image but more importantly the screen buffer was rendered to the LCD or Glass display much more slowly at 60 frames per second, very much slower indeed. So even if the image was changing you would only see 38 of those 2300 frames we rendered to memory.
That's great news, it means that if we need to, we can blit in massive amounts of graphics between video display updates.
Device Contexts
The blitter is made available to us via API calls from Liberty BASIC. Obviously before we can blit anything we need somewhere to blit from and somewhere to blit to. Typically we would blit to the screen buffer. So how do we access this buffer?We need to find it's address and would use an API call to do so.
This obtains a ulong number which is the pointer to the Device Context (DC) that Windows created for our graphicbox. So the screen buffer is in fact the DC that Windows has created behind the scenes.
Now we create a copy of that DC.
Then we fill it with some graphics by getting a handle to our "bmp" image and selecting it into the new DC.
And that's all we need to start blitting! DCs are amorphous things, if you select in a large bmp you can have lots of graphics in one location to blit from.
Once you have finished with a DC you must release and delete it.
That's a whistle stop tour of DCs, check the following link for help on API and DCs under the GDI banner.
http://lbpe.wikispaces.com/GDI
Basic Blitting
Lets draw ourselves some graphics to blit from. We use the left 225 pixels of the screen to draw some stars and then replicate that in the next 225 pixels giving us a 450 pixel image that will scroll without an obvious end. Confused? Don't worry the tutorial is about blitting not game graphics (That might be next).Then I draw a little circle in the remaining 50 pixels. Use the debugger to step through and see what's happening. Now when I start blitting I take the first 225 pixels from the memory DC and blit them to the buffer DC but stretch them width ways up to 500 pixels. In this way you cut out little parts of the memory DC and fill the buffer DC. Next iteration I move the source 5 pixels to the right in the graphics DC and so repetitively move the star background to the left.
Then I cut out the little circle and blit it a couple of times same size into the buffer. Net result a scrolling background with two sprites moving about. Well they would be sprites if I had used TransparentBlt, notice that the circle backgrounds overwrite when they cross over. If I had used TransparentBlt you would just see the white circles.
So there are several call you can make BitBlt, StretchBlt PrlBlt and TransparentBlt each has it's own strength some can flip and mirror some can't, one can do it transparently, basically pick your blitter call by the functionality you wish.
Double Buffering
Double buffering is something you will eventually come to. When you render large or complex images or start to render text you will find that the image starts to flicker. The solution is to double buffer. Very simply we draw all the complex graphics to an intermediate DC and then on a regular basis blit its contents to the screen buffer DC and leave it alone. This ensures there is a stable copy of what we want displayed and provides rock solid graphics.The flicker is rooted in how Windows updates it's screen, the videosync is not made available to us as many windows may wish redrawn or updated. So the screen refresh happens randomly as far as we are concerned. Right in the middle of drawing a line or rendering some text. But because we can blit a single screen image so quickly with the blitter it rarely, if ever, is half drawn when the refresh occurs.
One of the other great things about blitting is that you do not use up graphics memory, each DC consumes a finite amount of memory but after that you are just blitting between them and no other graphics memory is consumed.
Adding Text
We use another API call to render text to our DC. This action in itself triggers the need for the double buffer. Here we create the same moving background but ignore the circle sprite and instead render two sets of text. The text API calls firstly set the text background color to be transparent. Then they set the text color and render the text.Seasick?
Ok scrolling stars and text gets a bit boring. Do you get seasick? Check out this rolling ocean. Use the mouse or arrow keys to turn and speed up or slow down. It kinda gives the impression of being on a rolling ocean swell. The ocean.bmp has four strips for the horizon which I blit into the top of the picture depending on what the heading is. Then I blit four copies of the sea section. I roll these up and down using a sine curve and I also roll them forward to create more movement. The further away section rolls least and they double up their movement the nearer the bottom of the screen they are.Its just like having multiple backgrounds in the sprite engine. There is lots of time to draw sprites on top of this moving background. Doing so creates a pretty cool game environment.
Copy this bmp to your own PC
Where Now?
Actually the only barrier is your imagination.Happy coding
rodbird@hotmail.com
Table of Contents