Thursday, 17 May 2012

Windows Stuff

I've been fairly busy as of late, but haven't had much time to write down any of the stuff I've been up to.  I feel like I'm reaching a really exciting point in my programming journey.  I'm finding a load of ways in which I can apply programming and come up with new things.

If there's one thing I've worked on the most over the last month and a bit is Windows programming.  I've been reading through Petzold's beastly "Programming Windows" (5th edition) and I'm pretty much at the end.  I would really recommend this book if you're going to attempt Windows programming.

One thing that amazes me with Petzold is his ability to be an expert in everything he touches on, even things like image processing and audio.  But he's also concise, really clear, and an engaging writer.  His code examples are great and good for demonstrating his point.  The book overall is the perfect learning tool and reference.

Anyway, the reason I decided to devote my time to Petzold's epic is partly because I bought it 4 years ago, but mainly because I felt really limited just knowing how to write console programs.  Knowing an API well like Win32 API gives you another set of tools for programming, especially in the world of audio programming.  There were probably much simpler routes of action, and maybe as a low level programmer I should have ditched Windows for Linux by now.  Anyway, I bought the book 4 years ago, and haven't really regretted it.

As proof of my efforts, I came up with a project that would be a culmination of as many topics (in the Petzold book) as possible (it was originally just an implementation of multithreading, but I figured it'd be more fun to see how much stuff I could put in).  The program generates a graphical representation of the Mandelbrot set - a freaky maths pheneoma which when visualised is an amazing fractal.  I chose it because it's a task that is really easy to split up and send to different threads, and requires a fair few calculations (it's done pixel by pixel).  In short, each pixel is converted to a complex number and then a simple rule is tested on that point.  This is done iteratively, if the pixel starts to diverge (the modulus goes past a threshold) then we say that's a lighter colour.  Otherwise, the less the pixel budges, the blacker it is.  If this isn't satisfying, which it shouldn't be because I never told you the rule, I'll direct you to a more in-depth explanation.

I kind of wish I'd done this bit right at the start, and done a bit more coverage of the initial stages and the horrendous bug I couldn't get rid of for a while.  So far I'd say I'm 3/4s done.  The core features are mostly down, apart from the zoom in feature (which I've prepared for in how I've structured everything).  On the todo list is a "Properties" dialog box, program icons and graying out of menu items when they can't be used.

Still, I'm pretty proud of what's in already.  The multithreading part works, and I've done it so the threads are all set off at the start of the program, then stopped and restarted by something called an "event object".  The program could very easily be scaled up to hundreds of threads, although the overhead for even 4 seems to be quite large most of the time!  I also implemented bitmap saving (which took some Device Independent Bitmap stuff) and copying to the clipboard.  Plus, the main feature - the visualisation of the set - is really cool, and it's been fun playing with different colours.

Fortunately the horrendous bug was a small flaw in the calculation for each pixel.  Specifically, it was during the function that squared complex numbers.  It meant the real part of the complex number was being changed, but then the new real part was used again in the computation of the imaginary part.  The outcome was a fairly ugly Mandelbrot set.  Still, I prefer bugs I can see / hear because they're blindingly obvious!

Below is a Mandelbrot set I made earlier, which I'm pretty pleased with...

Basically pure program output - no print screening or editing afterwards
 The program isn't finished, but the output itself isn't going to change unless I get round to implementing a zoom feature.  When I finish it I'll put a link up to the code or something.

No comments:

Post a Comment