MattB Posted December 17, 2003 Posted December 17, 2003 Hello. I am exploring .NET programming using C# and GDI+. My end program is going to be a vector drawing program (similiar to Adobe Illustrator, although not that complex). I've started learning about GDI+, and it seems to have all the functions I want (alpha, gradients, beziers, antialiasing, etc.), but I am struggling with this performance problem when I used doublebuffering. Whenever my form is large (i.e. maximized), there is a noticable effort when refreshing the screen. I've tried without doublebuffering, but the screen flicker is also unacceptable. Here is some sample code that demonstrates this (not complete code, only what you'd have to add to a new project): using System.Drawing; using System.Drawing.Drawing2D; namespace GDI__Test { public class Form1 : Form { private GraphicsPath _oShape; private Pen _oPen; private SolidBrush _oBrush; public Form1() { base.SetStyle(ControlStyles.DoubleBuffer, true); base.SetStyle(ControlStyles.UserPaint, true); base.SetStyle(ControlStyles.AllPaintingInWmPaint, true); _oShape = new GraphicsPath(); _oPen = new Pen(Color.Black, 2.0F); _oBrush = new SolidBrush(Color.Yellow); } private void Form1_MouseMove(object sender, MouseEventArgs e) { _oShape.Dispose(); _oShape = new GraphicsPath(); _oShape.AddEllipse(e.X, e.Y, 100, 150); _oShape.CloseFigure(); this.Invalidate(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics loGraphics = e.Graphics; loGraphics.SmoothingMode = SmoothingMode.AntiAlias; loGraphics.FillPath(_oBrush, _oShape); loGraphics.DrawPath(_oPen, _oShape); } } } When you move the shape with the maximized window, it isn't locked to the mouse, it's jumpy and laggs behind and then catches up (like it's on a chain). The cause seems to be the amount of time it takes to redraw the form. I have tried this on several computers (all of which we would hope to support in the end product), and it seems that the CPU is the only thing that makes a difference. I've ran it on a) P4, 1.6GHz, 256MB RAM, 64MB Video; b) P3, 1.1GHz, 512MB RAM, 64MB Video, this is my development machine; c) P3, 733MHz, 384MB RAM, 128MB Video. On computer a) best performance; b) unacceptable drawing delays; c) brutal. This seems to be a common problem with DoubleBuffering. I've downloaded and ran Bob Powell's example (from http://www.bobpowell.net/doublebuffer.htm), and it too has this problem when I run it maximized (his rotations are very choppy as opposed to when running in the initial window size)...and he's doing his own manual double buffering in that example. I've also found this newsgroup post (http://groups.google.ca/groups?hl=en&lr=&ie=UTF-8&th=c7369dbf1e058f5c&seekm=%2322klulACHA.2228%40tkmsftngp02&frame=off) about the same problem with no real solution (I tried the PixelFormat.Format32bppPArgb with no luck). And I can't revert to using GDI, because I need the alpha and antialising stuff, right? I've heard a suggestion that I should not be repainting (invalidating) the entire form all the time and that this might be a cause of the problem. Using the above example as an example, it would be more efficient if I only invalidated the union of the shape's original bounding rect and the shape's new bounding rect. My question is how do I do this? I've tried using the System.Drawing.Region class, but I could only fill the region..I want to be able to tell the form to actually only repaint a part of the display. Could someone point me in the right direction so I can try this out to see if this will solve my problem. Alternatively, does anyone have any other suggestions? I am thinking about investigating DirectX as I hear that it is much faster (although does it have all the capabilities, like anti-aliasing and alpha?). I would really like to stick with GDI+ as it seems to be a good and simple object model to follow. Thanks for any info... - Matt Budd Quote
Camaro Z28 Posted December 19, 2003 Posted December 19, 2003 Hi, Create a bitmap. Apply all of your various graphics to that bitmap in memory. Then apply it to your form. It is fast and you will have no flicker at all. Hope it helps. Jason Quote Visual Basic Code Source FREE Visual Basic Source Code
itguru80 Posted February 3, 2004 Posted February 3, 2004 Hi, I have also found the same thing, using the SetStyle(....) commands, although it is supposed to work, in fact doesn't work all that well. I think you may need to completely ovveride the OnPaint method, and handle that yourself. I am also interested in anyone's opinion of Managed DirectX for .NET and the performance of that, if anyone has had any experience with that. Peter Quote
wyrd Posted February 3, 2004 Posted February 3, 2004 GDI+ is just ungodly slow. Use GDI instead, and if that's still not good enough, use DirectDraw. Quote Gamer extraordinaire. Programmer wannabe.
NK2000 Posted February 3, 2004 Posted February 3, 2004 as far as i know you can change how the app paints everything on screen, but i dont have the variables in mind at the moment, i just can tell you if you want to have fast graphics there is no way around dx, but normally you should also get it to work with gdi+ just use doublebuffering, so create a bitmap with same size as your drawing surface and then just draw all in that hidden bitmap at the onpaint you just draw this one bitmap Quote
sem00009 Posted February 19, 2004 Posted February 19, 2004 How to apply the bitmap? How can I apply such a bitmap to my control? Using the graphics.DrawImage() on my control method causes already the unwanted flickering with GDI+. Can I do something like. MyControl.Graphics = myBitmap.Graphics ? Thanks, Franz Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.