Multi programming with "windows.h" logic/loop?

I started my current program (a Mandelbrot) on an Arduino Due and a 480X320 TFT LCD. It was/is in C++. It (the screen) was also very small and (the sketch) was very slow.... :( I decided to port the program (sketch) to my desktop and Visual Studio Express 2015 and a 1920X1080 TV monitor.

Anyway, my problem....

As you see I have included the "CALLBACK WndProc" method. Also, as the comment, the mandelbrot method runs in the WM_PAINT "case". It paints the (generic) mandelbrot(straight forward, nothing special and not relevant to my question) increases the "zoom" value from 1 to 70 trillion in 10% steps, 339 displays altogether. The run takes about 40 minutes and at 70 trillion zoom the display gets "blocky" as I suspect I have reached the "precision" limit of "doubles & floats"!?

During this 40 minutes I can't click the mouse nor touch the keyboard nor allow the screensaver to cut in nor switch to another process without the process "freezing"! I suspect while the mandelbrot displays 339 times it must switch off multi programming or something. If I "click" the "close(X)" gadget a requester comes up saying "Not responding" and I have to "force close" the program, which is "frozen".

After the 40 minutes, the last screen just stays on the display but if I click the "X" it closes down correctly and properly obviously because the WM_PAINT process is complete?

My question....

How do I allow the program to respond to the mouse, keyboard, process changes, loss of focus etc? I would (later) like to use the mouse to change the "focus" of the mandelbrot zooming process etc? Use the keyboard to enter new focus co-ordinates and iteration counts etc?

Obviously, by displaying 339 "zoomed" mandelbrots I'm switching something "off" and a mouse or keyboard "press" freezes the process!?

I read SOME hints about multi-threading???? There isn't much on the web about this :(

I didn't know whether to put this topic in "Beginners" or "Programming" forums?

Also (much later) could I process the displays as/into a video file? AVI, WMV or MP4. I'm not particular. :) Or could I output each display as a JPG, PNG, bitmap, ... or some "picture" format and create a video from the snapshots?

I am a retired analyst/programmer (mainframes and batch processes and a total newbie in C++) and this isn't homework :D

JFYI the Arduino takes 15 minutes to paint the 480X320 mandelbrot and my desktop takes 7 seconds to paint the same 1920X1080 one :D



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {/* Window Procedure WndProc */
	switch (message) {

	case WM_PAINT:
		SetWindowHandle(hwnd);
		madelbrot();//display, increase zoom, redisplay, 300 times
		break;

	case WM_CLOSE:
		if (MessageBox(hwnd, "Really quit?", "My Mandelbrot Fractal - Programming Techniques", MB_OKCANCEL) == IDOK) DestroyWindow(hwnd);
		return 0;// Else: User canceled. Do nothing.

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE) {
			PostQuitMessage(0);
			return 0;
		}
		g_Keys[wParam & 0xFF] = true;
		break;

	case WM_KEYUP:
		g_Keys[wParam & 0xFF] = false;
		break;

	default:
		break; // FAIL to call DefWindowProc //
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
Honestly, I suggest using a graphics API like OpenGL to do all the rendering.
Thanks, I WILL (eventually). I thought I would use first principles first.

Won't I be up against the same sort of thing with Direct3D or OpenGL anyway too?

Lack of multi programming etc?
Maybe you could find out first where the actual bottleneck of your program is. If the calculations take most of the time saving a little time by the rendering doesn't help much. AFAIK a mandelbrot is a ordinary bitmap and a graphics library seems a bit of an over-kill. A while ago I saw a MFC app doing beautiful mandelbrot graphics with the ordinary Windows GDI.
Thanks for your reply Thomas but I think I AM using Windows GDI?

Apart from CreateWindow and a couple of other window related functions I am ONLY using SetPixel.

A mandelbrot is basically 2 "for" loops and the evaluation of the formula

Z = Z*Z + c

setting/choosing a colour and SetPixel....

I think my problem is the fact that my logic exists completely in WM_PAINT which seems to tie up the program so nothing else in WndProc ever gets a chance to run?

I am hoping one of you smart non-newbies can suggest how else I should go about laying out my processing? :)

I am searching for C++ mandelbrot code to see how everyone ELSE does it but no luck so far. It is slow work being a newbie ;)
Last edited on
The run takes about 40 minutes and at 70 trillion zoom the display gets "blocky" as I suspect I have reached the "precision" limit of "doubles & floats"!?

Yes, that's what happens.

I did a mandelbrot program a while ago just for amusement. The calculation is the thing which takes up all the time, the plotting of pixels, while you may want to optimise it, is not the biggest issue. I ended up with three threads, one for the windows interface, to keep the program responsive to mouse actions and so on.

Initially I had one thread to perform the calculation and plot it, in a line-by-line fashion. Then it occurred to me to set up a second thread to also do the calculation, plotting line-by line. There were various strategies to share out the work. On a multi-core processor you might use more than just a pair of threads, but beyond a certain point too many threads will slow it down, depends on the hardware.

Also (much later) could I process the displays as/into a video file? AVI, WMV or MP4. I'm not particular. :) Or could I output each display as a JPG, PNG, bitmap, ... or some "picture" format and create a video from the snapshots?

I used existing library code to save each image to a file, jpeg format I think, though I might have used some uncompressed format, don't remember.

The fun part was using Virtualdub to turn the bunch of images into a video file. If you arrange for them to be numbered in a recognisable sequence, such as img000.jpg, img001.jpg, img002.jpg etc then virtualdub will automatically be able to load them if you just specify the first image.

http://www.virtualdub.org/
Last edited on
Thanks for your reply Chervil :)

Since you can't plot until the calculation is complete how does putting the plotting and the calculation in different threads help?

I would love to know how you put the windows interface (WndProc?) in it's own thread?

Did YOUR program allow you to change to do something else and not "freeze"? That is, run in the background?

Trying to watch while (possibly) 3000 mandelbrots run would be a bit tedious. :( Did you ever make a movie or such? Something that would run for a couple of minutes? A 1% zoom increase would run for about 2 hours single threading whereas a movie of that would be spectacular in 2 minutes :)

I would ideally like to kick it off (making a movie or at least capturing each scan) then doing something else while it ran in the background? Watch TV? ;)

I have just looked at a program that uses 128 bit math but it is in CL(?). Looks impressive but ....
I'm not sure I'll be able to give more specific help as I seem to be one of the few using C++builder (which is still alive and well under the Embarcadero name).

Though the principles are going to be the same, I used a number of features specific to that technology, and though I'm perfectly willing to share my code (PM me if you like) it may not help that much.

Did you ever make a movie or such?
yes, I edited my previous post, you may have been typing your reply at the same time.
When I had a go at this, my logic was a bit different. I didn't put my code in the WM_PAINT section.

Bearing in mind that I used C++ builder, which though it does the same things, doesn't directly expose the message loop. So the code can appear different, though the effect is the same.

Anyway, in my code the main mandelbrot calculation loop draws the image onto a buffer. There is no update of the screen at all. Except, after every few hundred pixels have been drawn, the screen is re-drawn with the contents of the buffer.

In effect, my WM_PAINT code simply draws the contents of the buffer onto the screen.

Last edited on
closed account (E0p9LyTq)
Since the discussion is about Mandelbrot Sets, here's something to reflect on:

Obfuscating your Mandelbrot code
http://www.codeproject.com/Articles/2228/Obfuscating-your-Mandelbrot-code
Terrific FurryGuy. :)

I would prefer optimisation to obfuscation though. It isn't so important on a 4Ghz processor desktop but on an Arduino Due of 80Mhz that can take 15 minutes to paint a "deep" zoomed brot! Or worse an Arduino Nano that takes 75 minutes to paint ONE Mandelbrot!?

I have this feeling that I can SAVE a couple of floating point multiplies somewhere????

I have also played with a 1K Mandelbrot that runs AND zooms in real time! Granted not "deep" zooms but zooms nonetheless..... It is obfuscated and I have been trying to extract the logic of that!? It does some weird and wonderful things to stay under 1K.

I have enough trouble just trying to be understand the WndProc cycle. :(
Last edited on
Topic archived. No new replies allowed.