mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-07-12 03:04:51 -04:00
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:
@ -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>
|
||||
|
Reference in New Issue
Block a user