diff --git a/Builds/MSVC/Installer/FractoriumInstaller.wixproj b/Builds/MSVC/Installer/FractoriumInstaller.wixproj
index 780446d..b7e4885 100644
--- a/Builds/MSVC/Installer/FractoriumInstaller.wixproj
+++ b/Builds/MSVC/Installer/FractoriumInstaller.wixproj
@@ -6,7 +6,7 @@
3.7
{c8096c47-e358-438c-a520-146d46b0637d}
2.0
- Fractorium_1.0.0.12
+ Fractorium_1.0.0.13
Package
$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets
$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
diff --git a/Builds/MSVC/Installer/Product.wxs b/Builds/MSVC/Installer/Product.wxs
index 45f22d7..53f5076 100644
--- a/Builds/MSVC/Installer/Product.wxs
+++ b/Builds/MSVC/Installer/Product.wxs
@@ -1,6 +1,6 @@
-
+
@@ -13,7 +13,7 @@
-
+
::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
#define ISAAC_SIZE 4
diff --git a/Source/Ember/Renderer.cpp b/Source/Ember/Renderer.cpp
index 9bfa595..a348f78 100644
--- a/Source/Ember/Renderer.cpp
+++ b/Source/Ember/Renderer.cpp
@@ -528,8 +528,15 @@ eRenderStatus Renderer::Run(vector& finalImage, double time, si
sampleItersToDo = std::min(sampleItersToDo, itersPerTemporalSample - m_LastIter);
EmberStats stats = Iterate(sampleItersToDo, temporalSample);//The heavy work is done here.
+ //Abort does not indicate an error, it just means the process was interrupted, most likely by the user on the GUI.
+ if (m_Abort)
+ {
+ success = eRenderStatus::RENDER_ABORT;
+ goto Finish;
+ }
+
//If no iters were executed, something went catastrophically wrong.
- if (stats.m_Iters == 0)
+ if (!stats.m_Success && stats.m_Iters == 0)
{
AddToReport("Zero iterations ran, rendering failed, aborting.\n");
success = eRenderStatus::RENDER_ERROR;
@@ -537,12 +544,6 @@ eRenderStatus Renderer::Run(vector& finalImage, double time, si
goto Finish;
}
- if (m_Abort)
- {
- success = eRenderStatus::RENDER_ABORT;
- goto Finish;
- }
-
//Accumulate stats whether this batch ran to completion or exited prematurely.
m_LastIter += stats.m_Iters;//Sum of iter count of all threads, reset each temporal sample.
m_Stats.m_Iters += stats.m_Iters;//Sum of iter count of all threads, cumulative from beginning to end.
diff --git a/Source/Ember/RendererBase.h b/Source/Ember/RendererBase.h
index df91b7c..4d616e1 100644
--- a/Source/Ember/RendererBase.h
+++ b/Source/Ember/RendererBase.h
@@ -61,6 +61,7 @@ public:
void Clear()
{
+ m_Success = true;
m_Iters = 0;
m_Badvals = 0;
m_IterMs = 0;
@@ -69,6 +70,7 @@ public:
EmberStats& operator += (const EmberStats& stats)
{
+ m_Success &= stats.m_Success;
m_Iters += stats.m_Iters;
m_Badvals += stats.m_Badvals;
m_IterMs += stats.m_IterMs;
@@ -76,6 +78,7 @@ public:
return *this;
}
+ bool m_Success = true;
size_t m_Iters, m_Badvals;
double m_IterMs, m_RenderMs;
};
diff --git a/Source/EmberCL/RendererCL.cpp b/Source/EmberCL/RendererCL.cpp
index ab48dc8..2a90744 100644
--- a/Source/EmberCL/RendererCL.cpp
+++ b/Source/EmberCL/RendererCL.cpp
@@ -787,9 +787,9 @@ eRenderStatus RendererCL::AccumulatorToFinalImage(vector& pixel
template
EmberStats RendererCL::Iterate(size_t iterCount, size_t temporalSample)
{
- bool b = true;
EmberStats stats;//Do not record bad vals with with GPU. If the user needs to investigate bad vals, use the CPU.
static std::string loc = __FUNCTION__;
+ bool& b = stats.m_Success;
//Only need to do this once on the beginning of a new render. Last iter will always be 0 at the beginning of a full render or temporal sample.
if (m_LastIter == 0)
@@ -868,15 +868,10 @@ EmberStats RendererCL::Iterate(size_t iterCount, size_t temporalSamp
dev->m_Calls = 0;
b = RunIter(iterCount, temporalSample, stats.m_Iters);
-
- if (!b || stats.m_Iters == 0)//If no iters were executed, something went catastrophically wrong.
- m_Abort = true;
-
stats.m_IterMs = m_IterTimer.Toc();
}
else
{
- m_Abort = true;
ErrorStr(loc, "Iiteration failed", nullptr);
}
@@ -1000,7 +995,7 @@ bool RendererCL::RunIter(size_t iterCount, size_t temporalSample, si
auto& wrapper = m_Devices[dev]->m_Wrapper;
intmax_t itersRemaining = 0;
- while (b && (atomLaunchesRan.fetch_add(1) + 1 <= launches) && ((itersRemaining = atomItersRemaining.load()) > 0) && !m_Abort)
+ while (b && (atomLaunchesRan.fetch_add(1) + 1 <= launches) && ((itersRemaining = atomItersRemaining.load()) > 0) && success && !m_Abort)
{
//Check if the user wanted to suspend the process.
while (Paused())
@@ -1053,7 +1048,6 @@ bool RendererCL::RunIter(size_t iterCount, size_t temporalSample, si
1)))
{
success = false;
- m_Abort = true;
ErrorStr(loc, "Error running iteration program", m_Devices[dev].get());
atomLaunchesRan.fetch_sub(1);
break;
@@ -1117,7 +1111,7 @@ bool RendererCL::RunIter(size_t iterCount, size_t temporalSample, si
Join(threadVec);
itersRan = atomItersRan.load();
- if (m_Devices.size() > 1)//Determine whether/when to sum histograms of secondary devices with the primary.
+ if (success && m_Devices.size() > 1)//Determine whether/when to sum histograms of secondary devices with the primary.
{
if (((TemporalSamples() == 1) || (temporalSample == TemporalSamples() - 1)) &&//If there are no temporal samples (not animating), or the current one is the last... (probably doesn't matter anymore since we never use multiple renders for a single frame when animating, instead each frame gets its own renderer).
((m_LastIter + itersRan) >= ItersPerTemporalSample()))//...and the required number of iters for that sample have completed...
@@ -1270,7 +1264,6 @@ eRenderStatus RendererCL::RunDensityFilter()
//t2.Tic();
if (b && !(b = RunDensityFilterPrivate(kernelIndex, gridW, gridH, blockSizeW, blockSizeH, chunkSizeW, chunkSizeH, colChunkPass, rowChunkPass)))
{
- m_Abort = true;
ErrorStr(loc, "Running DE filter program for row chunk "s + std::to_string(rowChunkPass) + ", col chunk "s + std::to_string(colChunkPass) + " failed", m_Devices[0].get());
}
diff --git a/Source/Fractorium/AboutDialog.ui b/Source/Fractorium/AboutDialog.ui
index 114b15c..bf83fcc 100644
--- a/Source/Fractorium/AboutDialog.ui
+++ b/Source/Fractorium/AboutDialog.ui
@@ -58,7 +58,7 @@
QFrame::NoFrame
- <html><head/><body><p align="center">Fractorium 1.0.0.12</p><p align="center"><span style=" font-size:10pt;">A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><a href="http://fractorium.com"><span style=" text-decoration: underline; color:#0000ff;">fractorium.com</span></a></p></body></html>
+ <html><head/><body><p align="center">Fractorium 1.0.0.13</p><p align="center"><span style=" font-size:10pt;">A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><a href="http://fractorium.com"><span style=" text-decoration: underline; color:#0000ff;">fractorium.com</span></a></p></body></html>
Qt::RichText
diff --git a/Source/Fractorium/FinalRenderDialog.cpp b/Source/Fractorium/FinalRenderDialog.cpp
index 3cd5a65..9d149e2 100644
--- a/Source/Fractorium/FinalRenderDialog.cpp
+++ b/Source/Fractorium/FinalRenderDialog.cpp
@@ -700,6 +700,8 @@ void FractoriumFinalRenderDialog::Pause(bool paused)
m_Controller->Pause(false);
ui.FinalRenderPauseButton->setText("Pause");
}
+
+ ui.FinalRenderStartButton->setEnabled(!paused);
}
///
diff --git a/Source/Fractorium/FractoriumRender.cpp b/Source/Fractorium/FractoriumRender.cpp
index cc8fcd0..81a267d 100644
--- a/Source/Fractorium/FractoriumRender.cpp
+++ b/Source/Fractorium/FractoriumRender.cpp
@@ -394,8 +394,9 @@ bool FractoriumEmberController::Render()
{
//if (m_Renderer->Run(m_FinalImage, 0) == RENDER_OK)//Full, non-incremental render for debugging.
bool update = iterBegin || m_Fractorium->m_Settings->ContinuousUpdate();
+ eRenderStatus result;
- if (m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, update) == eRenderStatus::RENDER_OK)//Force output on iterBegin or if the settings specify to always do it.
+ if ((result = m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, update)) == eRenderStatus::RENDER_OK)//Force output on iterBegin or if the settings specify to always do it.
{
//The amount to increment sub batch while rendering proceeds is purely empirical.
//Change later if better values can be derived/observed.
@@ -491,7 +492,7 @@ bool FractoriumEmberController::Render()
//}
}
}
- else//Something went very wrong, show error report.
+ else if (result != eRenderStatus::RENDER_ABORT)//If error was returned, something went very wrong, show error report.
{
auto errors = m_Renderer->ErrorReport();
success = false;