Time for lunch

9 11 2010

Ha, it’s been a while since I’ve managed to come up with a pun-like title. But let’s step aside from what is probably my own askew sense of humor and into the realms of C#. Yes that’s right, I’ve left the barren wasteland that is ActionScript 3.0 in favour of greener pastures, namely C# [read as C-Sharp but don’t ask me why, I guess C++Java sounded weird].

DISCLAIMER: In no way am I suggesting that C# is anything other than its own language. Though clearly inspirsed by C++ and Java at first. It has now evolved into something which is different and stands, quite proudly, on its own.

Right, what am I doing?
Several things and all at once. My main tasks for the past week and a half have brushed me against the GDI+, Windows Forms and XML. The entire project was a supposedly simple implementation of an animation/drawing type application. I say supposedly since I’ve never touched GDI+, barely glimpsed Forms for College [and possibly the worst teacher in the world, but more on that on a different post] and well, I’ve been mucking around XML with ActionScript so I felt fairly comfortable there. Also, there is no such thing as a useful program that is also simple…

Let me get this out of the way now, if there is one thing ActionScript 3.0 got right it’s the XML support; easy and fun. C#, not so much, I’ve ended up using the XmlDocument object which represented my entire file and just iterated over the nodes I wanted, plus created a couple of useful static functions for extracting things like Size and PointF. On that note I would also like to say that creating a coherent data model and a unified application-based interface for extracting said data is a practice I heartily recommand as it will save time down the line.

What about the other two though? Well, Forms and the GDI+ API weren’t terribly hard to come to grips with to be honest, C# being a fairly intuitive sort of language and Visual Studio 2010 being a fairly [read, very very very] intuitive IDE [when it doesn’t crash :P]. I did come across several issues however.

The first of which is the flicker effect. That is, invalidating the Form forces a redraw of the “screen” but with only one buffer the whole process flickers worse than a drunken firefly. Solution -> double buffering. How?

Normally I would simply have my rendering loop running at full steam and flipping buffers like there’s no tomorrow, normally. The problem here is that a Form is an event based system, forever loops [unless stuck in a different thread] are a big no-no. There are a few ways out there of doing it and I’m sure mine is far from optimal, but it works and is simple to implement. Here’s how I solved it:

Create BackBuffer;
Create RenderTimer;
Every time the RenderTimer ticks, update the BackBuffer, flip and clear.

I’ll talk about the RenderTimer right after but for now all you need to know is that, like everything else, the Windows.Forms.Timer is an event based object which generates a Tick event every X interval [programmer provides the X] and I’ve just used the Toolbox to attach it to the main form. The rest of the code looks something like this:

//Data you'll need, stick it somewhere private.
  private Graphics      _frontBuffer = null;
  private Bitmap        _imageBuffer = null;
  private Graphics      _backBuffer  = null;
private void InitializeDoubleBuffer()
{
  _frontBuffer = this.CreateGraphics();
  _imageBuffer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height, _frontBuffer);
  _backBuffer = Graphics.FromImage(_imageBuffer);
}

Provide a simple interface for something which can be drawn [derive and override as required]:

interface IDraw
{
  void Draw(Graphics surface);
}

and finally in the tick event:

shape.Draw(_backBuffer);
_frontBuffer.DrawImageUnscaled(_imageBuffer, 0, 0);
_backBuffer.Clear(Color.Black);

And voila! flicker-free rendering.

I was going to talk about the timer system and the problems I’ve had with synchronizing the animations but I’ve ran out of time, there’s work tomorrow and, yup you guessed it… Still need to do the dishes 😀
Good Night!

“the black flame of evil is burning and growing, Queen… queen of the dark horizons! “

Advertisements

Actions

Information

One response

9 11 2010
Tatham

That’s a good way of doing manual double-buffering, expecially useful if you don’t want the system to make certain assumptions for you about the transparency of the background or if you want to expand it into a more complex double-buffered system.
If you just want to limit that flicker though, you could always try setting the ControlStates property on the form to use double-buffering as
SetControl(ControlStyle.UserPaint | ControlStyle.AllPaintinginWmPaint | ControlStyle.DoubleBuffer);

Great post!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: