1

I've not really worked with graphics before, but I need to design a screen saver that animates, ie. moves a company logo around the screen, bouncing off the sides.

So far, using GDIPLUS, I do the following ...

Image1: IGPImage; 
Image2: IGPImage;

Image1 := TGPImage.Create('background.png');
Image2 := TGPImage.Create('logo.png');

and draw it as follows, in the OnPaint event of a TPaintBox. A TTimer component provides the event to Invalidate the TPaintBox.

procedure TFormMain.PaintBox1Paint(Sender: TObject);
var
  GPGraphics: IGPGraphics;
  i: integer;
begin
  GPGraphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);

  //Restore the background
  GPGraphics.DrawImage(Image1, 0, 0);

  // Determine the next position of the logo
  // We will also determine here if we are at the edges (not shown)
  X := X + 1;
  Y := Y + 1;

  // Draw the logo somewhere on the screen
  GPGraphics.DrawImage(Image2, X, Y);
end;

The result however is not completely satisfactory as the logo flickers a bit and the movement across the screen (1680x1050 pixels, 32 bit colour), takes forever to reach any sides. I have no idea how to speed it up whilst retaining a smooth transition of the logo across the screen.

I currently use Delphi XE on Windows XP.

halfer
  • 19,824
  • 17
  • 99
  • 186
Pieter van Wyk
  • 2,316
  • 9
  • 48
  • 65
  • 1
    Some samples: [bouncing ball](http://stackoverflow.com/a/16446087/282848), [moving triangles](http://stackoverflow.com/a/7224075/282848), etc. Of course, for more advanced/smooth graphics, you need to abandon the GDI and have a look at OpenGL (or Direct X). – Andreas Rejbrand Jul 15 '13 at 15:47
  • 2
    Anyhow, don't use a `TPaintBox`. Draw directly onto the form! – Andreas Rejbrand Jul 15 '13 at 15:52
  • 2
    And, if you're going to just draw a PNG image, you don't need to use GDI+. A `TPngImage` rendered by pure GDI will be enough. Of course, the advice from the first comment still applies. For smooth full screen animations, GDI nor GDI+ are not enough. – TLama Jul 15 '13 at 16:03
  • Andreas, Thank you for the examples. I will definitely use some or all of it. I will definitely also have a look at OpenGL and Direct-X. I may just learn something! – Pieter van Wyk Jul 15 '13 at 21:29
  • 1
    Custom screen savers are so very 1990s. Nowadays most default power schemes turn the monitor off completely after a while to save on consumption. – 500 - Internal Server Error Jul 15 '13 at 23:01

1 Answers1

0

I know it is an old question, but it deserve an answer.

To avoid flickering with GDI+, as with many other graphic systems, you need to blast your complete image to the screen.

In your case, this means you have to create a bitmap having the size of the screen, paint the background to that bitmap, then paint whatever image you like to that bitmap and finally draw the bitmap on screen. This won't flick at all.

Of course the bitmap need to be create only once and reused at will. The OnPaint will draw that bitmap. Elsewhere, your timer routine, you draw into the bitmap then you invalidate the window which in turn will trigger an OnPaint event.

fpiette
  • 11,983
  • 1
  • 24
  • 46