Picture Motion--Avoid The Flicker
By Cevahir PARLAK
http://www.macrotech.bigstep.com
Introduction
What I do is place a visible PaintBox on the form for where I want to show the graphics. I then have an equal sized but invisible (visible=false) Image control. I prepare the graphic output in the invisible Image, which servers as the buffer. I then copy the invisible Image to the visible PaintBox.
The real trick here is using a PaintBox control (in the System control set) as the visible component, and Image control (in the Additional control set) for the invisible controls. For some reason this is the only combination that seems to work, though you could probably use a Forms canvas in place of the PaintBox canvas.
Not only does the CopyRect() method work well here, all the other drawing methods of a canvas can be used in this was.
As the result of this program you will see a strategic B2 Bomber Plane attacking Al Unser Junior at Michigan 500.
First Step
The problem with TImage is that it descends from TGraphicControl (which in turn descends from TControl) which means that it does not reside inside it's own window. TImage, TLabel, and TShape all derive from TGraphicControl. Moving these types of controls around (by changing the Top and Left properties) will cause flicker . This is because when moved, they need constant repainting (unlike TWinControl descendants which don't need constant repainting when moved) to be displayed in the new location. Windows itself knows the location of window controls, but knows nothing about TGraphicControls. It is very analogous to having a posterboard: TWinControls are pinned to the posterboard, while TGraphicControls are drawn on the posterboard. It's really easy to move the pinned controls around by simply unpinning them then changing their location. The controls that are drawn directly to the posterboard need to be erased then redrawn. Does this make sense? So the easiest thing to do is Parent the GraphicControl descendant on a WinControl, and move the WinControl (such as a TPanel). Using a TPanel component, be sure to set the FullRepaint property to false.
At this point I decided to create a component that derived from TwinControl but Borland suggests using TCustomControl which has the OnPaint event.I followed it and created TImageWindow.Moving a TImageWindow over a background image causes less flicker.TImageWindow has a Round property that rounds the image.I will use that property while I explain Rotating Bitmaps Using Scanline.
Second Step
Third Step
To use DirectX with Delphi you will need DelphiX package.
Fourth Step
After loading Delphi X you can change TPaintBox with DXPaintBox to convert the project to a DirectX project.
Fifth Step
Sixth Step
To Rotate Bitmaps Download this project.
Seventh Step
If you wonder how I created all those background Images in the Double Buffering Projects read these lines carefully.
First I notify you that you don’t need Video Capture Devices to capture videos!!!
Run the Capture program and then open your AVI file.The frames of your AVI will be saved under directory C:\Screen\Screen1.bmp~Screen2.bmp............~Screeni.bmp
I run my Cart Racing and Captured the Bitmaps that way.But there were other cars on the track and it was very difficult to save bitmaps while playing and later I played a replay with the view of front wing and no opponent car running.The bitmaps ( I captured more than 100) I have got that way are similar to RamBmp.bmp.As you see there are many other things in this Bitmap.Now I have to clip the Track part of this pictures and save them to a file.First I opened RawBmp with MSPAINT and by moving mouse I find the position of Rectangle which has the track picture : Rect(201,204,655,544).
I will copy this part of picture to Rect(0,0,655-201,544-204) of another bitmap.At this point We should make
Image1.Width:=655-201;
Image1.Height:=544-204;
Now all I have to do is just copying that part of picture from RawBmp to a new bitmap file.
The source code for that is as follows:
procedure TForm1.ClipBmpClick(Sender: TObject);
var
Bitmap: TBitmap;
MyRect, MyOther: TRect;
begin
MyRect := Rect(201,204,655,544); // rect of source bitmap
MyOther:=Rect(0,0,655-201,544-204); // rect of destination bitmap
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('c:\Screen\Screen'+IntToStr(i)+'.bmp');
//Image1.Canvas.BrushCopy(MyRect, Bitmap, MyRect, clNone); this creates a transparent bitmap
Image1.Canvas.CopyRect(MyOther,Bitmap.Canvas,MyRect);
Image1.Picture.Bitmap.SaveToFile('C:\Cart1\Michigan'+IntToStr(i)+'.bmp');
Bitmap.Free;
i:=i+1;
end;
The result bitmap is Michigan.bmp.The size of RawBmp is more than 1.5 MB and the size of Michigan.bmp is 302 KB.That is too much for a game program because you will need hundreds of frames for a good game and The size of your program will be very large.For this reason,I added a BmpToJpg routine to convert bitmaps to jpg.