1 Week of C++ practice: Escape time fractal renderer
Runs drawing code off the main thread. Drawing code is split into a number of threads (the constant is currently set to 16). Each thread draws a line at a time; the line starts at the thread index and once a line is done, it moves thread count lines ahead; interleaving the lines like this prevents issues where some threads are likely to have much more work on them because the pixels where more iterations are performed tend to be grouped into specific areas (for instance, pixels that are plotted as black went through all the iterations without diverging.) Previously I split the image into equal parts vertically; after staggering the lines the threads draw, there was a considerable performance increase, as each thread is more likely to have a similar amount of work.
Arbitrary fractal functions
The functions the fractal uses for both the starting value and the recursion are function pointers; in FractalDrawer.h you can edit the functions that class sends to the ComplexFractal class to be run, and make your own escape time fractals.
The fractal functions can take time as an input, which allows the fractal to be animated. You can pause this animation at any time.
the colors are generated by reading from a ramp texture. You can choose the colors that you want the fractal to display by editing this texture.
If you are zooming in or out, while the drawing threads are generating your next frame, the texture will scale using the current progress of the drawing threads. This ensures that there will be smooth transitions in between drawing frames and helps improve the appearance of the program as well as making it easier to see which part of the fractal you are zooming in/out from.
Long Zoom Distance
The floating point type that ComplexFloat class and all other code that is precision dependent uses is defined using a #define which is currently set to long double. You can zoom into the fractal for over a minute before you start seeing pixelation due to the floating point precision breaking down.
Regrets/Issues/Things To Fix:
No GPU acceleration
This project was to practice my C++, not GLSL/HLSL shader writing. As such, the program is quite a bit slower than if I had programmed the fractal generation into a shader. I will probably leave it the way it is, since I got plenty of shader practice at my last job.
Zooming Unresponsiveness With Long Draw Time
In order for the zooming to work correctly, the program has to wait an entire drawing frame so that it can sum up your zoom operation and determine the desired transformation. In situations where the drawing is very slow, this can lead to a feeling of unresponsiveness. Attempts to make this more responsive led to jumping/choppiness when the zoom position was altered mid-drawing or started/stopped mid drawing.
I have Dear ImgUI in the project and plan to implement it, but currently all interaction is done through OpenGL, and a lot of settings are hard coded. I plan to tackle this over the next week.
Fractal Functions Are Hard Coded
The last thing I will try to implement is a way to type in the functions you want to use and have them applied at run time; I currently do not know how to do this in a good way, as the only implementation I can think of at the moment would be very slow (parsing the equation data per iteration). In the long run, if I have time, I will look into a potential way of doing this, if it's possible.