Board index » delphi » GDI+ Too much flashing

GDI+ Too much flashing


2004-07-22 11:12:26 PM
delphi199
I'm developing an app that requires a little animation. - Slide show
transitions, active cute buttons, textured back grounds etc.
What's the best method for this?
I've tried VCL's TCanvas - but the results weren't so pleasing. (The
help files aren't very useful so it is difficult for me improve results.)
GDI+ looks much better, and is easier to use - perhaps it is because the
help is better - but my slide transitions sometimes flash.
Should I be using OpenGL? If so how do I get started? Am I right in
saying that OpenGL only works well with Delphi 7 (not D8)?
Should I be using something else entirely: Flash? Any others?
Any thoughts, comments or advice would be greatly appreciated,
Andyb
P.S. Here's the code of one transition that flashes sometimes.
What am I doing wrong?
NB: it only flashes when using either tsSwipexxx, but not with tsRevealxxx.
var
dst, src: RectangleF;
strt: cardinal; // Cardinal is an unsigned integer - for timer
step: integer;
begin
for step := 0 to COUNT_STEPS_SWIPE do
begin
// Get start time of this loop
strt := GetTicks;
// Get coords of Souce image
SetSwipe_SourceCoords(style, step, src);
SetSwipe_DestCoords(style, step, dst);
a1a.Draw_Image(g_target, img_source, dst, src, false); // false =
no transparency
// Do events
Application.DoEvents;
// Wait
Wait(MILLISECS_SWIPE, strt);
end;
// Tidyup
Transition_TidyUp;
end;
// Rect sizes got here:
procedure SetSwipe_SourceCoords(const style: TTransitionStyle; const
step: integer; var src_rect: RectangleF);
var
w, h: single;
begin
w := img_source.Width * step / COUNT_STEPS_SWIPE;
h := img_source.Height * step / COUNT_STEPS_SWIPE;
case style of
// StartGet from image left
tsSwipeLeft, tsRevealLeft:
src_rect := RectangleF.Create( 0, 0, w, img_source.Height );
// Start from image right
tsSwipeRight:
src_rect := RectangleF.Create( img_source.Width - w, 0, w,
img_source.Height );
tsRevealRight:
src_rect := RectangleF.Create( img_source.Width - w, 0,
img_source.Width, img_source.Height );
// Start from image top
tsSwipeUp, tsRevealDown:
src_rect := RectangleF.Create( 0, 0, img_source.Width, h );
// Start from image bottom
tsSwipeDown:
src_rect := RectangleF.Create( 0, img_source.Height - h,
img_source.Width, h );
tsRevealUp:
src_rect := RectangleF.Create( 0, img_source.Height - h,
img_source.Width, img_source.Height );
end;
end;
procedure SetSwipe_DestCoords(const style: TTransitionStyle; const step:
integer; var dst_rect: RectangleF);
var
w, h: single;
begin
w := rect.Width * step / COUNT_STEPS_SWIPE;
h := rect.Height * step / COUNT_STEPS_SWIPE;
case style of
// To draw from left
tsSwipeRight, tsRevealLeft:
dst_rect := RectangleF.Create( rect.Left, rect.Top, w, rect.Height );
// Draw from right
tsSwipeLeft:
dst_rect := RectangleF.Create( rect.Left + rect.Width - w,
rect.Top, w, rect.Height );
tsRevealRight:
dst_rect := RectangleF.Create( rect.Left + rect.Width - w,
rect.Top, rect.Width, rect.Height );
// Draw from top
tsSwipeDown, tsRevealDown:
dst_rect := RectangleF.Create( rect.Left, rect.Top, rect.Width, h );
// Draw from bottom
tsSwipeUp:
dst_rect := RectangleF.Create( rect.Left, rect.Top + rect.Height -
h, rect.Width, h );
tsRevealUp:
dst_rect := RectangleF.Create( rect.Left, rect.Top + rect.Height -
h, rect.Width, rect.Height );
end;
end;
// Drawing done here
procedure A1Artist.Draw_Image(g: Graphics; img: Image; const dst_rect,
src_rect: RectangleF; const add_transparency: boolean = true); // overload
var
bmp: Bitmap;
begin
// Correct gamma
g.CompositingQuality := CompositingQuality.GammaCorrected;
//g.CompositingQuality := CompositingQuality.Default;
// Make the bitmap's background transparent
if add_transparency then
begin
bmp := Bitmap.Create(img);
bmp.MakeTransparent;
g.DrawImage(bmp, dst_rect, src_rect, GraphicsUnit.Pixel);
bmp.Free;
end else // no transparency
g.DrawImage(img, dst_rect, src_rect, GraphicsUnit.Pixel);
end;
 
 

Re:GDI+ Too much flashing

Ok I dont know if it is me or i over looked it, but you could prob'ly try
Enabling DoubleBuffering...i.e. DoubleBuffered:=True; on the form create
and see if that works(It should, it did for me)
"Andyb" <XXXX@XXXXX.COM>writes
Quote
I'm developing an app that requires a little animation. - Slide show
transitions, active cute buttons, textured back grounds etc.

What's the best method for this?

I've tried VCL's TCanvas - but the results weren't so pleasing. (The
help files aren't very useful so it is difficult for me improve results.)

GDI+ looks much better, and is easier to use - perhaps it is because the
help is better - but my slide transitions sometimes flash.

Should I be using OpenGL? If so how do I get started? Am I right in
saying that OpenGL only works well with Delphi 7 (not D8)?

Should I be using something else entirely: Flash? Any others?


Any thoughts, comments or advice would be greatly appreciated,
Andyb


P.S. Here's the code of one transition that flashes sometimes.
What am I doing wrong?

NB: it only flashes when using either tsSwipexxx, but not with
tsRevealxxx.

var
dst, src: RectangleF;
strt: cardinal; // Cardinal is an unsigned integer - for timer
step: integer;
begin
for step := 0 to COUNT_STEPS_SWIPE do
begin
// Get start time of this loop
strt := GetTicks;

// Get coords of Souce image
SetSwipe_SourceCoords(style, step, src);
SetSwipe_DestCoords(style, step, dst);

a1a.Draw_Image(g_target, img_source, dst, src, false); // false =
no transparency

// Do events
Application.DoEvents;

// Wait
Wait(MILLISECS_SWIPE, strt);
end;

// Tidyup
Transition_TidyUp;
end;

// Rect sizes got here:

procedure SetSwipe_SourceCoords(const style: TTransitionStyle; const
step: integer; var src_rect: RectangleF);
var
w, h: single;
begin
w := img_source.Width * step / COUNT_STEPS_SWIPE;
h := img_source.Height * step / COUNT_STEPS_SWIPE;

case style of
// StartGet from image left
tsSwipeLeft, tsRevealLeft:
src_rect := RectangleF.Create( 0, 0, w, img_source.Height );

// Start from image right
tsSwipeRight:
src_rect := RectangleF.Create( img_source.Width - w, 0, w,
img_source.Height );

tsRevealRight:

src_rect := RectangleF.Create( img_source.Width - w, 0,
img_source.Width, img_source.Height );

// Start from image top
tsSwipeUp, tsRevealDown:
src_rect := RectangleF.Create( 0, 0, img_source.Width, h );

// Start from image bottom
tsSwipeDown:
src_rect := RectangleF.Create( 0, img_source.Height - h,
img_source.Width, h );

tsRevealUp:
src_rect := RectangleF.Create( 0, img_source.Height - h,
img_source.Width, img_source.Height );
end;
end;

procedure SetSwipe_DestCoords(const style: TTransitionStyle; const step:
integer; var dst_rect: RectangleF);
var
w, h: single;
begin
w := rect.Width * step / COUNT_STEPS_SWIPE;
h := rect.Height * step / COUNT_STEPS_SWIPE;

case style of
// To draw from left
tsSwipeRight, tsRevealLeft:
dst_rect := RectangleF.Create( rect.Left, rect.Top, w,
rect.Height );

// Draw from right
tsSwipeLeft:
dst_rect := RectangleF.Create( rect.Left + rect.Width - w,
rect.Top, w, rect.Height );

tsRevealRight:
dst_rect := RectangleF.Create( rect.Left + rect.Width - w,
rect.Top, rect.Width, rect.Height );

// Draw from top
tsSwipeDown, tsRevealDown:
dst_rect := RectangleF.Create( rect.Left, rect.Top, rect.Width, h );

// Draw from bottom
tsSwipeUp:
dst_rect := RectangleF.Create( rect.Left, rect.Top + rect.Height -
h, rect.Width, h );

tsRevealUp:
dst_rect := RectangleF.Create( rect.Left, rect.Top + rect.Height -
h, rect.Width, rect.Height );
end;
end;

// Drawing done here

procedure A1Artist.Draw_Image(g: Graphics; img: Image; const dst_rect,
src_rect: RectangleF; const add_transparency: boolean = true); // overload
var
bmp: Bitmap;
begin
// Correct gamma
g.CompositingQuality := CompositingQuality.GammaCorrected;
//g.CompositingQuality := CompositingQuality.Default;

// Make the bitmap's background transparent
if add_transparency then
begin
bmp := Bitmap.Create(img);
bmp.MakeTransparent;
g.DrawImage(bmp, dst_rect, src_rect, GraphicsUnit.Pixel);
bmp.Free;
end else // no transparency
g.DrawImage(img, dst_rect, src_rect, GraphicsUnit.Pixel);
end;

 

Re:GDI+ Too much flashing

Thanks Neel,
Quote
Enabling DoubleBuffering...i.e. DoubleBuffered:=True; on the form create
but this only works for VCL, not Winforms. Does anyone know?
Very hopefully,
Andyb