Here is the code that does the calculations and creates the wxBitmap from the calculated color values.
Code: Select all
void FractalCanvas::Calculate(const long width, const long height, long maxIterations, double xMin, double xMax, double yMin, double yMax, std::vector<wxColour> colors)
{
this->bmpFractal = wxBitmap(width, height);
this->CalcVirtualSize();
this->Refresh();
auto token = cts.get_token();
this->isCalculating = true;
concurrency::concurrent_vector<std::vector<wxColour>> bitmapData(height);
concurrency::parallel_for(0, static_cast<int>(height), [&](const int screenY)
{
std::vector<wxColour> row;
for (auto screenX = 0; screenX < width; screenX++)
{
if (concurrency::is_current_task_group_canceling())
{
return;
}
// TODO: Replace with actual Mandelbrot calculation.
row.push_back(wxTheColourDatabase->Find("WHITE"));
}
bitmapData[screenY] = row;
});
{
wxMemoryDC dc(this->bmpFractal);
for (size_t y = 0; y < bitmapData.size(); y++)
{
auto row = bitmapData[y];
for (size_t x = 0; x < row.size(); x++)
{
dc.SetPen(row[x]);
dc.DrawPoint(static_cast<int>(x), static_cast<int>(y));
}
wxTheApp->Yield();
}
}
this->isCalculating = false;
this->Refresh();
}
I was initially going to use concurrency::combinable to give each thread its own wxBitmap to work on and then combine them once all the calculations were done, but I couldn't figure out how to determine which rows each thread had worked on.
I'm pretty sure going the concurrency::combinable route would be more efficient, provided I can figure out how to determine with rows each thread has worked on.