0.4.1.1 Beta 08/03/2014

--Bug Fixes
Spatial filter would not be correctly recreated on subsequent runs of
differing supersample values during final render.
Fix DCBubble, Funnel, SphericalN,
Wrong logic with some usage of DO_DOUBLE. Only relevant for testing.
Use uint64 for iters/sec calculation on final render dialog. int was
overflowing on extremely fast GPU renders.

--Code Changes
Make density, spatial and temporal filters preserve the values they were
created with. This helps in determining when a new instance is needed.
Better NULL checks when copying embers and xforms.
Rename members in FractoriumEmberControllerBase.h to omit duplicating
the members declared in the base.
This commit is contained in:
mfeemster
2014-08-03 16:16:10 -07:00
parent 152318a567
commit 570d3bcf1d
21 changed files with 135 additions and 80 deletions

View File

@ -52,7 +52,7 @@
</font>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;br/&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Fractorium 0.4.1.0 Beta&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;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.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Matt Feemster&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;br/&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Fractorium 0.4.1.1 Beta&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;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.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Matt Feemster&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>

View File

@ -83,16 +83,16 @@ template<typename T>
FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderDialog* finalRender)
: FinalRenderEmberControllerBase(finalRender)
{
m_PreviewRenderer = auto_ptr<EmberNs::Renderer<T, T>>(new EmberNs::Renderer<T, T>());
m_PreviewRenderer->Callback(NULL);
m_PreviewRenderer->NumChannels(4);
m_PreviewRenderer->ReclaimOnResize(true);
m_FinalPreviewRenderer = auto_ptr<EmberNs::Renderer<T, T>>(new EmberNs::Renderer<T, T>());
m_FinalPreviewRenderer->Callback(NULL);
m_FinalPreviewRenderer->NumChannels(4);
m_FinalPreviewRenderer->ReclaimOnResize(true);
m_PreviewRenderFunc = [&]()
m_FinalPreviewRenderFunc = [&]()
{
m_PreviewCs.Enter();//Thread prep.
m_PreviewRun = true;
m_PreviewRenderer->Abort();
m_FinalPreviewRenderer->Abort();
QLabel* widget = m_FinalRender->ui.FinalRenderPreviewLabel;
unsigned int maxDim = 100u;
@ -106,21 +106,20 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
m_PreviewEmber = m_Ember;
m_PreviewEmber.m_Quality = 100;
m_PreviewEmber.m_Supersample = 1;
m_PreviewEmber.m_TemporalSamples = 1;
m_PreviewEmber.m_FinalRasW = min(maxDim, unsigned int(scalePercentage * m_Ember.m_FinalRasW));
m_PreviewEmber.m_FinalRasH = min(maxDim, unsigned int(scalePercentage * m_Ember.m_FinalRasH));
m_PreviewEmber.m_PixelsPerUnit = scalePercentage * m_Ember.m_PixelsPerUnit;
while (!m_PreviewRenderer->Aborted() || m_PreviewRenderer->InRender())
while (!m_FinalPreviewRenderer->Aborted() || m_FinalPreviewRenderer->InRender())
QApplication::processEvents();
m_PreviewRenderer->EarlyClip(m_FinalRender->EarlyClip());
m_PreviewRenderer->YAxisUp(m_FinalRender->YAxisUp());
m_PreviewRenderer->Transparency(m_FinalRender->Transparency());
m_PreviewRenderer->SetEmber(m_PreviewEmber);
m_FinalPreviewRenderer->EarlyClip(m_FinalRender->EarlyClip());
m_FinalPreviewRenderer->YAxisUp(m_FinalRender->YAxisUp());
m_FinalPreviewRenderer->Transparency(m_FinalRender->Transparency());
m_FinalPreviewRenderer->SetEmber(m_PreviewEmber);
if (m_PreviewRenderer->Run(m_PreviewFinalImage) == RENDER_OK)
if (m_FinalPreviewRenderer->Run(m_PreviewFinalImage) == RENDER_OK)
{
QImage image(m_PreviewEmber.m_FinalRasW, m_PreviewEmber.m_FinalRasH, QImage::Format_RGBA8888);//The label wants RGBA.
memcpy(image.scanLine(0), m_PreviewFinalImage.data(), m_PreviewFinalImage.size() * sizeof(m_PreviewFinalImage[0]));//Memcpy the data in.
@ -135,7 +134,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
//The main rendering function which will be called in a Qt thread.
//A backup Xml is made before the rendering process starts just in case it crashes before finishing.
//If it finishes successfully, delete the backup file.
m_RenderFunc = [&]()
m_FinalRenderFunc = [&]()
{
size_t i;
@ -243,6 +242,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
m_Ember.m_TemporalSamples = 1;
m_Renderer->SetEmber(m_Ember);
m_PureIterTime = 0;
memset(m_FinalImage.data(), 0, m_FinalImage.size() * sizeof(m_FinalImage[0]));
m_RenderTimer.Tic();//Toc() is called in the progress function.
if (m_Renderer->Run(m_FinalImage) != RENDER_OK)
@ -266,6 +266,7 @@ template <typename T> void FinalRenderEmberController<T>::SetEmber(const Ember<f
template <typename T> void FinalRenderEmberController<T>::CopyEmber(Ember<float>& ember) { ember = m_Ember; }
template <typename T> void FinalRenderEmberController<T>::SetEmberFile(const EmberFile<float>& emberFile) { m_EmberFile = emberFile; }
template <typename T> void FinalRenderEmberController<T>::CopyEmberFile(EmberFile<float>& emberFile) { emberFile = m_EmberFile; }
template <typename T> void FinalRenderEmberController<T>::SetOriginalEmber(Ember<float>& ember) { m_OriginalEmber = ember; }
template <typename T> double FinalRenderEmberController<T>::OriginalAspect() { return double(m_OriginalEmber.m_OrigFinalRasW) / m_OriginalEmber.m_OrigFinalRasH; }
#ifdef DO_DOUBLE
template <typename T> void FinalRenderEmberController<T>::SetEmber(const Ember<double>& ember, bool verbatim) { m_Ember = ember; }
@ -273,8 +274,6 @@ template <typename T> void FinalRenderEmberController<T>::CopyEmber(Ember<double
template <typename T> void FinalRenderEmberController<T>::SetEmberFile(const EmberFile<double>& emberFile) { m_EmberFile = emberFile; }
template <typename T> void FinalRenderEmberController<T>::CopyEmberFile(EmberFile<double>& emberFile) { emberFile = m_EmberFile; }
template <typename T> void FinalRenderEmberController<T>::SetOriginalEmber(Ember<double>& ember) { m_OriginalEmber = ember; }
#else
template <typename T> void FinalRenderEmberController<T>::SetOriginalEmber(Ember<float>& ember) { m_OriginalEmber = ember; }
#endif
/// <summary>
@ -313,7 +312,7 @@ int FinalRenderEmberController<T>::ProgressFunc(Ember<T>& ember, void* foo, doub
QFileInfo original(filename);
EmberStats stats = m_Renderer->Stats();
QString iters = QLocale(QLocale::English).toString(stats.m_Iters);
QString itersPerSec = QLocale(QLocale::English).toString(int(stats.m_Iters / (m_PureIterTime / 1000.0)));
QString itersPerSec = QLocale(QLocale::English).toString(unsigned __int64(stats.m_Iters / (m_PureIterTime / 1000.0)));
if (m_GuiState.m_DoAll && m_EmberFile.m_Embers.size() > 1)
filename = original.absolutePath() + QDir::separator() + m_GuiState.m_Prefix + QString::fromStdString(m_EmberFile.m_Embers[m_FinishedImageCount].m_Name) + m_GuiState.m_Suffix + "." + m_GuiState.m_DoAllExt;
@ -409,7 +408,7 @@ bool FinalRenderEmberController<T>::Render()
//parallel iteration loops inside of the CPU renderer to finish. The result is that
//the renderer ends up using ThreadCount - 1 to iterate, instead of ThreadCount.
//By using a Qt thread here, and tbb inside the renderer, all cores can be maxed out.
m_Result = QtConcurrent::run(m_RenderFunc);
m_Result = QtConcurrent::run(m_FinalRenderFunc);
m_Settings->sync();
return true;
}
@ -469,7 +468,7 @@ bool FinalRenderEmberController<T>::CreateRenderer(eRendererType renderType, uns
m_Renderer->Callback(this);
m_Renderer->NumChannels(channels);
m_Renderer->ReclaimOnResize(false);
m_Renderer->ReclaimOnResize(true);
m_Renderer->EarlyClip(m_FinalRender->EarlyClip());
m_Renderer->YAxisUp(m_FinalRender->YAxisUp());
m_Renderer->ThreadCount(m_FinalRender->ThreadCount());
@ -506,9 +505,9 @@ unsigned __int64 FinalRenderEmberController<T>::SyncAndComputeMemory()
m_Renderer->NumChannels(channels);
m_Renderer->ComputeBounds();
CancelPreviewRender();
//m_PreviewResult = QtConcurrent::run(m_PreviewRenderFunc);
//while (!m_PreviewResult.isRunning()) { QApplication::processEvents(); }//Wait for it to start up.
m_PreviewRenderFunc();
//m_FinalPreviewResult = QtConcurrent::run(m_PreviewRenderFunc);
//while (!m_FinalPreviewResult.isRunning()) { QApplication::processEvents(); }//Wait for it to start up.
m_FinalPreviewRenderFunc();
return m_Renderer->MemoryRequired(true);
}
@ -536,11 +535,11 @@ void FinalRenderEmberController<T>::ResetProgress(bool total)
template <typename T>
void FinalRenderEmberController<T>::CancelPreviewRender()
{
m_PreviewRenderer->Abort();
m_FinalPreviewRenderer->Abort();
while (m_PreviewRenderer->InRender()) { QApplication::processEvents(); }
while (m_FinalPreviewRenderer->InRender()) { QApplication::processEvents(); }
while (m_PreviewRun) { QApplication::processEvents(); }
while (m_PreviewResult.isRunning()) { QApplication::processEvents(); }
while (m_FinalPreviewResult.isRunning()) { QApplication::processEvents(); }
}
/// <summary>

View File

@ -61,10 +61,9 @@ public:
virtual unsigned __int64 SyncAndComputeMemory() { return 0; }
virtual QString Name() const { return ""; }
virtual void ResetProgress(bool total = true) { }
virtual void SetOriginalEmber(Ember<float>& ember) { }
#ifdef DO_DOUBLE
virtual void SetOriginalEmber(Ember<double>& ember) { }
#else
virtual void SetOriginalEmber(Ember<float>& ember) { }
#endif
virtual double OriginalAspect() { return 1; }
@ -79,10 +78,9 @@ protected:
double m_PureIterTime;
QFuture<void> m_Result;
QFuture<void> m_PreviewResult;
std::function<void (void)> m_RenderFunc;
std::function<void (void)> m_PreviewRenderFunc;
vector<unsigned char> m_PreviewFinalImage;
QFuture<void> m_FinalPreviewResult;
std::function<void (void)> m_FinalRenderFunc;
std::function<void (void)> m_FinalPreviewRenderFunc;
FractoriumSettings* m_Settings;
FractoriumFinalRenderDialog* m_FinalRender;
@ -108,14 +106,13 @@ public:
virtual void CopyEmber(Ember<float>& ember);
virtual void SetEmberFile(const EmberFile<float>& emberFile);
virtual void CopyEmberFile(EmberFile<float>& emberFile);
virtual void SetOriginalEmber(Ember<float>& ember);
#ifdef DO_DOUBLE
virtual void SetEmber(const Ember<double>& ember, bool verbatim = false);
virtual void CopyEmber(Ember<double>& ember);
virtual void SetEmberFile(const EmberFile<double>& emberFile);
virtual void CopyEmberFile(EmberFile<double>& emberFile);
virtual void SetOriginalEmber(Ember<double>& ember);
#else
virtual void SetOriginalEmber(Ember<float>& ember);
#endif
virtual double OriginalAspect();
virtual int ProgressFunc(Ember<T>& ember, void* foo, double fraction, int stage, double etaMs);
@ -135,7 +132,7 @@ protected:
Ember<T> m_PreviewEmber;
EmberFile<T> m_EmberFile;
EmberToXml<T> m_XmlWriter;
auto_ptr<EmberNs::Renderer<T, T>> m_PreviewRenderer;
auto_ptr<EmberNs::Renderer<T, T>> m_FinalPreviewRenderer;
};
template class FinalRenderEmberController<float>;

Binary file not shown.