From 570d3bcf1d35a21ecedf0cdaf3efca842fa9150a Mon Sep 17 00:00:00 2001 From: mfeemster Date: Sun, 3 Aug 2014 16:16:10 -0700 Subject: [PATCH] 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. --- .../FractoriumInstaller.wixproj | 2 +- .../VS2010/FractoriumInstaller/Product.wxs | 4 +- Data/Bench.xlsx | Bin 10405 -> 13500 bytes Data/Version History.txt | 13 ++++- Source/Ember/DensityFilter.h | 1 + Source/Ember/Ember.h | 7 ++- Source/Ember/EmberDefines.h | 2 +- Source/Ember/Renderer.cpp | 24 ++++----- Source/Ember/TemporalFilter.h | 17 ++++++ Source/Ember/Variations03.h | 14 +++-- Source/Ember/VariationsDC.h | 4 +- Source/Ember/Xform.h | 9 ++-- Source/EmberAnimate/EmberAnimate.rc | 8 +-- Source/EmberCL/RendererCL.cpp | 2 +- Source/EmberGenome/EmberGenome.rc | 8 +-- Source/EmberRender/EmberRender.rc | 8 +-- Source/EmberTester/EmberTester.cpp | 26 ++++++++++ Source/Fractorium/AboutDialog.ui | 2 +- .../Fractorium/FinalRenderEmberController.cpp | 49 +++++++++--------- .../Fractorium/FinalRenderEmberController.h | 15 +++--- Source/Fractorium/Fractorium.rc | Bin 4574 -> 4574 bytes 21 files changed, 135 insertions(+), 80 deletions(-) diff --git a/Builds/MSVC/VS2010/FractoriumInstaller/FractoriumInstaller.wixproj b/Builds/MSVC/VS2010/FractoriumInstaller/FractoriumInstaller.wixproj index 3f2416b..a20adbe 100644 --- a/Builds/MSVC/VS2010/FractoriumInstaller/FractoriumInstaller.wixproj +++ b/Builds/MSVC/VS2010/FractoriumInstaller/FractoriumInstaller.wixproj @@ -6,7 +6,7 @@ 3.7 {c8096c47-e358-438c-a520-146d46b0637d} 2.0 - Fractorium_Beta_0.4.1.0 + Fractorium_Beta_0.4.1.1 Package $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets diff --git a/Builds/MSVC/VS2010/FractoriumInstaller/Product.wxs b/Builds/MSVC/VS2010/FractoriumInstaller/Product.wxs index 9c1a3e7..1b211f4 100644 --- a/Builds/MSVC/VS2010/FractoriumInstaller/Product.wxs +++ b/Builds/MSVC/VS2010/FractoriumInstaller/Product.wxs @@ -1,6 +1,6 @@ - + @@ -13,7 +13,7 @@ - + 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 E1I?{|#Q*>R diff --git a/Data/Version History.txt b/Data/Version History.txt index f6eefff..32ec0e3 100644 --- a/Data/Version History.txt +++ b/Data/Version History.txt @@ -1,4 +1,15 @@ -0.4.0.9 Beta 07/29/2014 +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. + +--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. + +0.4.1.0 Beta 07/29/2014 --Bug Fixes Final render dialog didn't create the renderer properly on first run when more than one platform was present. diff --git a/Source/Ember/DensityFilter.h b/Source/Ember/DensityFilter.h index 5f45c16..4bb2725 100644 --- a/Source/Ember/DensityFilter.h +++ b/Source/Ember/DensityFilter.h @@ -312,6 +312,7 @@ public: inline T MinRad() const { return m_MinRad; } inline T MaxRad() const { return m_MaxRad; } inline T Curve() const { return m_Curve; } + inline unsigned int Supersample() const { return m_Supersample; } inline unsigned int KernelSize() const { return m_KernelSize; } inline unsigned int MaxFilterIndex() const { return m_MaxFilterIndex; } inline unsigned int MaxFilteredCounts() const { return m_MaxFilteredCounts; } diff --git a/Source/Ember/Ember.h b/Source/Ember/Ember.h index 47c3594..18019c4 100644 --- a/Source/Ember/Ember.h +++ b/Source/Ember/Ember.h @@ -143,9 +143,12 @@ public: for (unsigned int i = 0; i < ember.XformCount(); i++) { - Xform xform = *ember.GetXform(i);//Will call assignment operator to convert between types T and U. + if (Xform* p = ember.GetXform(i)) + { + Xform xform = *p;//Will call assignment operator to convert between types T and U. - AddXform(xform); + AddXform(xform); + } } Xform finalXform = *ember.FinalXform();//Will call assignment operator to convert between types T and U. diff --git a/Source/Ember/EmberDefines.h b/Source/Ember/EmberDefines.h index e6b5be5..403237b 100644 --- a/Source/Ember/EmberDefines.h +++ b/Source/Ember/EmberDefines.h @@ -25,7 +25,7 @@ namespace EmberNs extern void sincos(double x, double *s, double *c); #endif -#define EMBER_VERSION "0.4.1.0" +#define EMBER_VERSION "0.4.1.1" #define EPS6 T(1e-6) #define EPS std::numeric_limits::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 dc962b8..5311569 100644 --- a/Source/Ember/Renderer.cpp +++ b/Source/Ember/Renderer.cpp @@ -263,12 +263,12 @@ bool Renderer::CreateTemporalFilter(bool& newAlloc) newAlloc = false; //Use intelligent testing so it isn't created every time a new ember is passed in. - if ((m_TemporalFilter.get() == NULL) || - (m_Ember.m_Passes != m_LastEmber.m_Passes) || - (m_Ember.m_TemporalSamples != m_LastEmber.m_TemporalSamples) || + if ((!m_TemporalFilter.get()) || + (m_Ember.m_Passes != m_TemporalFilter->Passes()) || + (m_Ember.m_TemporalSamples != m_TemporalFilter->TemporalSamples()) || (m_Ember.m_TemporalFilterType != m_TemporalFilter->FilterType()) || - (m_Ember.m_TemporalFilterWidth != m_LastEmber.m_TemporalFilterWidth) || - (m_Ember.m_TemporalFilterExp != m_LastEmber.m_TemporalFilterExp)) + (m_Ember.m_TemporalFilterWidth != m_TemporalFilter->FilterWidth()) || + (m_Ember.m_TemporalFilterExp != m_TemporalFilter->FilterExp())) { m_TemporalFilter = auto_ptr>( TemporalFilterCreator::Create(m_Ember.m_TemporalFilterType, m_Ember.m_Passes, m_Ember.m_TemporalSamples, m_Ember.m_TemporalFilterWidth, m_Ember.m_TemporalFilterExp)); @@ -296,10 +296,10 @@ bool Renderer::PrepFinalAccumVector(vector& pixels) if (m_ReclaimOnResize) { if (pixels.size() != size) + { pixels.resize(size); - - if (m_ReclaimOnResize) pixels.shrink_to_fit(); + } } else { @@ -850,11 +850,11 @@ bool Renderer::CreateDEFilter(bool& newAlloc) if (m_Ember.m_MaxRadDE > 0) { //Use intelligent testing so it isn't created every time a new ember is passed in. - if ((m_DensityFilter.get() == NULL) || + if ((!m_DensityFilter.get()) || (m_Ember.m_MinRadDE != m_DensityFilter->MinRad()) || (m_Ember.m_MaxRadDE != m_DensityFilter->MaxRad()) || (m_Ember.m_CurveDE != m_DensityFilter->Curve()) || - (m_Ember.m_Supersample != m_LastEmber.m_Supersample)) + (m_Ember.m_Supersample != m_DensityFilter->Supersample())) { m_DensityFilter = auto_ptr>(new DensityFilter(m_Ember.m_MinRadDE, m_Ember.m_MaxRadDE, m_Ember.m_CurveDE, m_Ember.m_Supersample)); newAlloc = true; @@ -889,10 +889,10 @@ bool Renderer::CreateSpatialFilter(bool& newAlloc) newAlloc = false; //Use intelligent testing so it isn't created every time a new ember is passed in. - if ((m_SpatialFilter.get() == NULL) || + if ((!m_SpatialFilter.get()) || (m_Ember.m_SpatialFilterType != m_SpatialFilter->FilterType()) || (m_Ember.m_SpatialFilterRadius != m_SpatialFilter->FilterRadius()) || - (m_Ember.m_Supersample != m_LastEmber.m_Supersample) || + (m_Ember.m_Supersample != m_SpatialFilter->Supersample()) || (m_PixelAspectRatio != m_SpatialFilter->PixelAspectRatio())) { m_SpatialFilter = auto_ptr>( @@ -1007,7 +1007,7 @@ void Renderer::ThreadCount(unsigned int threads, const char* seedStr #ifdef ISAAC_FLAM3_DEBUG QTIsaac isaac(0, 0, 0, seeds); #else - QTIsaac isaac(newSize, newSize * newSize, newSize * newSize * newSize, seeds); + QTIsaac isaac(newSize, newSize * 2, newSize * 3, seeds); #endif m_Rand.push_back(isaac); diff --git a/Source/Ember/TemporalFilter.h b/Source/Ember/TemporalFilter.h index e4d8e93..6785ebb 100644 --- a/Source/Ember/TemporalFilter.h +++ b/Source/Ember/TemporalFilter.h @@ -40,9 +40,13 @@ public: { unsigned int i, steps = passes * temporalSamples; + m_Passes = passes; + m_TemporalSamples = temporalSamples; + m_FilterWidth = filterWidth; m_Deltas.resize(steps); m_Filter.resize(steps); m_FilterType = filterType; + m_FilterExp = 1; if (steps == 1) { @@ -83,6 +87,10 @@ public: { if (this != &filter) { + m_Passes = filter.m_Passes; + m_TemporalSamples = filter.m_TemporalSamples; + m_FilterWidth = filter.m_FilterWidth; + m_FilterExp = filter.m_FilterExp; m_SumFilt = filter.m_SumFilt; m_Deltas = filter.m_Deltas; m_Filter = filter.m_Filter; @@ -127,6 +135,10 @@ public: /// Accessors. /// size_t Size() const { return m_Filter.size(); } + unsigned int Passes() const { return m_Passes; } + unsigned int TemporalSamples() const { return m_TemporalSamples; } + T FilterWidth() const { return m_FilterWidth; } + T FilterExp() const { return m_FilterExp; } T SumFilt() const { return m_SumFilt; } T* Deltas() { return &m_Deltas[0]; } T* Filter() { return &m_Filter[0]; } @@ -151,6 +163,10 @@ protected: } T m_SumFilt;//The sum of all filter values. + T m_FilterWidth; + T m_FilterExp; + unsigned int m_Passes; + unsigned int m_TemporalSamples; vector m_Deltas;//Delta vector. vector m_Filter;//Filter vector. eTemporalFilterType m_FilterType;//The type of filter this is. @@ -192,6 +208,7 @@ public: maxFilt = m_Filter[i]; } + m_FilterExp = filterExp; FinishFilter(maxFilt); } } diff --git a/Source/Ember/Variations03.h b/Source/Ember/Variations03.h index 0a68b6e..4e4ebe4 100644 --- a/Source/Ember/Variations03.h +++ b/Source/Ember/Variations03.h @@ -20,7 +20,7 @@ public: void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { - T temp = 1 / cos(helper.In.y) + m_Effect * T(M_PI); + T temp = 1 / Zeps(cos(helper.In.y)) + m_Effect * T(M_PI); helper.Out.x = m_Weight * (tanh(helper.In.x) * temp); helper.Out.y = m_Weight * (tanh(helper.In.y) * temp); @@ -36,7 +36,7 @@ public: string effect = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t temp = 1 / cos(vIn.y) + " << effect << " * M_PI;\n" + << "\t\treal_t temp = 1 / Zeps(cos(vIn.y)) + " << effect << " * M_PI;\n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (tanh(vIn.x) * temp);\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (tanh(vIn.y) * temp);\n" @@ -276,11 +276,9 @@ public: void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { - T r = pow(helper.m_PrecalcSqrtSumSquares, m_Dist); + T r = Zeps(pow(helper.m_PrecalcSqrtSumSquares, m_Dist)); int n = Floor(m_Power * rand.Frand01()); - T alpha = helper.m_PrecalcAtanyx + n * M_2PI / Floor(m_Power); - //int n = (int)floor(m_Power * rand.Frand01()); - //T alpha = helper.m_PrecalcAtanyx + n * M_2PI / floor(m_Power); + T alpha = helper.m_PrecalcAtanyx + n * M_2PI / Zeps((T)Floor(m_Power)); T sina = sin(alpha); T cosa = cos(alpha); @@ -299,9 +297,9 @@ public: string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t r = pow(precalcSqrtSumSquares, " << dist << ");\n" + << "\t\treal_t r = Zeps(pow(precalcSqrtSumSquares, " << dist << "));\n" << "\t\tint n = floor(" << power << " * MwcNext01(mwc));\n" - << "\t\treal_t alpha = precalcAtanyx + n * M_2PI / floor(" << power << ");\n" + << "\t\treal_t alpha = precalcAtanyx + n * M_2PI / Zeps(floor(" << power << "));\n" << "\t\treal_t sina = sin(alpha);\n" << "\t\treal_t cosa = cos(alpha);\n" << "\n" diff --git a/Source/Ember/VariationsDC.h b/Source/Ember/VariationsDC.h index 9a2f943..f370638 100644 --- a/Source/Ember/VariationsDC.h +++ b/Source/Ember/VariationsDC.h @@ -23,7 +23,7 @@ public: void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) { T r = helper.m_PrecalcSumSquares; - T r4_1 = r / 4 + 1; + T r4_1 = Zeps(r / 4 + 1); r4_1 = m_Weight / r4_1; helper.Out.x = r4_1 * helper.In.x; @@ -49,7 +49,7 @@ public: ss << "\t{\n" << "\t\treal_t r = precalcSumSquares;\n" - << "\t\treal_t r4_1 = r / 4 + 1;\n" + << "\t\treal_t r4_1 = Zeps(r / 4 + 1);\n" << "\t\tr4_1 = xform->m_VariationWeights[" << varIndex << "] / r4_1;\n" << "\n" << "\t\tvOut.x = r4_1 * vIn.x;\n" diff --git a/Source/Ember/Xform.h b/Source/Ember/Xform.h index aabe4dd..f027bb9 100644 --- a/Source/Ember/Xform.h +++ b/Source/Ember/Xform.h @@ -171,9 +171,12 @@ public: for (unsigned int i = 0; i < xform.TotalVariationCount(); i++) { Variation* var = NULL; - - xform.GetVariation(i)->Copy(var);//Will convert from type U to type T. - AddVariation(var);//Will internally call SetPrecalcFlags(). + + if (Variation* varOrig = xform.GetVariation(i)) + { + varOrig->Copy(var);//Will convert from type U to type T. + AddVariation(var);//Will internally call SetPrecalcFlags(). + } } if (TotalVariationCount() == 0) diff --git a/Source/EmberAnimate/EmberAnimate.rc b/Source/EmberAnimate/EmberAnimate.rc index e25027b..6bd8ff9 100644 --- a/Source/EmberAnimate/EmberAnimate.rc +++ b/Source/EmberAnimate/EmberAnimate.rc @@ -49,8 +49,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,4,1,0 - PRODUCTVERSION 0,4,1,0 + FILEVERSION 0,4,1,1 + PRODUCTVERSION 0,4,1,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -67,12 +67,12 @@ BEGIN BEGIN VALUE "CompanyName", "Open Source" VALUE "FileDescription", "Renders fractal flames as animations with motion blur" - VALUE "FileVersion", "0.4.1.0" + VALUE "FileVersion", "0.4.1.1" VALUE "InternalName", "EmberAnimate.rc" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "OriginalFilename", "EmberAnimate.rc" VALUE "ProductName", "Ember Animate" - VALUE "ProductVersion", "0.4.1.0" + VALUE "ProductVersion", "0.4.1.1" END END BLOCK "VarFileInfo" diff --git a/Source/EmberCL/RendererCL.cpp b/Source/EmberCL/RendererCL.cpp index 800ee13..28fc380 100644 --- a/Source/EmberCL/RendererCL.cpp +++ b/Source/EmberCL/RendererCL.cpp @@ -49,7 +49,7 @@ RendererCL::RendererCL(unsigned int platform, unsigned int device, bool share m_PaletteFormat.image_channel_order = CL_RGBA; m_PaletteFormat.image_channel_data_type = CL_FLOAT; m_FinalFormat.image_channel_order = CL_RGBA; - m_FinalFormat.image_channel_data_type = CL_UNORM_INT8;//Change if this ever supports 2BPP outputs for PNG. + m_FinalFormat.image_channel_data_type = CL_UNORM_INT8;//Change if this ever supports 2BPC outputs for PNG. Init(platform, device, shared, outputTexID);//Init OpenCL upon construction and create programs that will not change. } diff --git a/Source/EmberGenome/EmberGenome.rc b/Source/EmberGenome/EmberGenome.rc index 3824869..12be5b4 100644 --- a/Source/EmberGenome/EmberGenome.rc +++ b/Source/EmberGenome/EmberGenome.rc @@ -49,8 +49,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,4,1,0 - PRODUCTVERSION 0,4,1,0 + FILEVERSION 0,4,1,1 + PRODUCTVERSION 0,4,1,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -67,12 +67,12 @@ BEGIN BEGIN VALUE "CompanyName", "Open Source" VALUE "FileDescription", "Manipulates fractal flames parameter files" - VALUE "FileVersion", "0.4.1.0" + VALUE "FileVersion", "0.4.1.1" VALUE "InternalName", "EmberGenome.rc" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "OriginalFilename", "EmberGenome.rc" VALUE "ProductName", "Ember Genome" - VALUE "ProductVersion", "0.4.1.0" + VALUE "ProductVersion", "0.4.1.1" END END BLOCK "VarFileInfo" diff --git a/Source/EmberRender/EmberRender.rc b/Source/EmberRender/EmberRender.rc index df68541..0ee29ce 100644 --- a/Source/EmberRender/EmberRender.rc +++ b/Source/EmberRender/EmberRender.rc @@ -49,8 +49,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,4,1,0 - PRODUCTVERSION 0,4,1,0 + FILEVERSION 0,4,1,1 + PRODUCTVERSION 0,4,1,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -67,12 +67,12 @@ BEGIN BEGIN VALUE "CompanyName", "Open Source" VALUE "FileDescription", "Renders fractal flames as single images" - VALUE "FileVersion", "0.4.1.0" + VALUE "FileVersion", "0.4.1.1" VALUE "InternalName", "EmberRender.rc" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "OriginalFilename", "EmberRender.rc" VALUE "ProductName", "Ember Render" - VALUE "ProductVersion", "0.4.1.0" + VALUE "ProductVersion", "0.4.1.1" END END BLOCK "VarFileInfo" diff --git a/Source/EmberTester/EmberTester.cpp b/Source/EmberTester/EmberTester.cpp index 0fc0e1d..e49b626 100644 --- a/Source/EmberTester/EmberTester.cpp +++ b/Source/EmberTester/EmberTester.cpp @@ -1074,6 +1074,28 @@ bool TestVarAssignVals() return success; } +bool TestZepsFloor() +{ + bool success = true; + VariationList vlf; + vector zeps; + + zeps.push_back("Zeps(floor"); + + for (size_t i = 0; i < vlf.Size(); i++) + { + Variation* var = vlf.GetVariation(i); + + if (SearchVar(var, zeps, false)) + { + cout << "Variation " << var->Name() << " contains Zeps(floor()). This is fine for the GPU, but ensure the CPU uses Zeps((T)Floor())." << endl; + success = false; + } + } + + return success; +} + bool TestConstants() { bool success = true; @@ -1864,6 +1886,10 @@ int _tmain(int argc, _TCHAR* argv[]) TestVarAssignVals(); t.Toc("TestVarAssignVals()"); + t.Tic(); + TestZepsFloor(); + t.Toc("TestZepsFloor()"); + t.Tic(); TestConstants(); t.Toc("TestConstants()"); diff --git a/Source/Fractorium/AboutDialog.ui b/Source/Fractorium/AboutDialog.ui index 83a5853..5382776 100644 --- a/Source/Fractorium/AboutDialog.ui +++ b/Source/Fractorium/AboutDialog.ui @@ -52,7 +52,7 @@ - <html><head/><body><p align="center"><br/><span style=" font-size:12pt;">Fractorium 0.4.1.0 Beta</span></p><p align="center"><span style=" font-size:10pt;"><br/>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"><span style=" font-size:10pt;">Matt Feemster</span></p></body></html> + <html><head/><body><p align="center"><br/><span style=" font-size:12pt;">Fractorium 0.4.1.1 Beta</span></p><p align="center"><span style=" font-size:10pt;"><br/>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"><span style=" font-size:10pt;">Matt Feemster</span></p></body></html> Qt::RichText diff --git a/Source/Fractorium/FinalRenderEmberController.cpp b/Source/Fractorium/FinalRenderEmberController.cpp index f65ba26..a2b147e 100644 --- a/Source/Fractorium/FinalRenderEmberController.cpp +++ b/Source/Fractorium/FinalRenderEmberController.cpp @@ -83,16 +83,16 @@ template FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderDialog* finalRender) : FinalRenderEmberControllerBase(finalRender) { - m_PreviewRenderer = auto_ptr>(new EmberNs::Renderer()); - m_PreviewRenderer->Callback(NULL); - m_PreviewRenderer->NumChannels(4); - m_PreviewRenderer->ReclaimOnResize(true); + m_FinalPreviewRenderer = auto_ptr>(new EmberNs::Renderer()); + 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::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::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::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 void FinalRenderEmberController::SetEmber(const Ember void FinalRenderEmberController::CopyEmber(Ember& ember) { ember = m_Ember; } template void FinalRenderEmberController::SetEmberFile(const EmberFile& emberFile) { m_EmberFile = emberFile; } template void FinalRenderEmberController::CopyEmberFile(EmberFile& emberFile) { emberFile = m_EmberFile; } +template void FinalRenderEmberController::SetOriginalEmber(Ember& ember) { m_OriginalEmber = ember; } template double FinalRenderEmberController::OriginalAspect() { return double(m_OriginalEmber.m_OrigFinalRasW) / m_OriginalEmber.m_OrigFinalRasH; } #ifdef DO_DOUBLE template void FinalRenderEmberController::SetEmber(const Ember& ember, bool verbatim) { m_Ember = ember; } @@ -273,8 +274,6 @@ template void FinalRenderEmberController::CopyEmber(Ember void FinalRenderEmberController::SetEmberFile(const EmberFile& emberFile) { m_EmberFile = emberFile; } template void FinalRenderEmberController::CopyEmberFile(EmberFile& emberFile) { emberFile = m_EmberFile; } template void FinalRenderEmberController::SetOriginalEmber(Ember& ember) { m_OriginalEmber = ember; } -#else -template void FinalRenderEmberController::SetOriginalEmber(Ember& ember) { m_OriginalEmber = ember; } #endif /// @@ -313,7 +312,7 @@ int FinalRenderEmberController::ProgressFunc(Ember& 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::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::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::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::ResetProgress(bool total) template void FinalRenderEmberController::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(); } } /// diff --git a/Source/Fractorium/FinalRenderEmberController.h b/Source/Fractorium/FinalRenderEmberController.h index 5d59556..373d7d0 100644 --- a/Source/Fractorium/FinalRenderEmberController.h +++ b/Source/Fractorium/FinalRenderEmberController.h @@ -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& ember) { } #ifdef DO_DOUBLE virtual void SetOriginalEmber(Ember& ember) { } -#else - virtual void SetOriginalEmber(Ember& ember) { } #endif virtual double OriginalAspect() { return 1; } @@ -79,10 +78,9 @@ protected: double m_PureIterTime; QFuture m_Result; - QFuture m_PreviewResult; - std::function m_RenderFunc; - std::function m_PreviewRenderFunc; - vector m_PreviewFinalImage; + QFuture m_FinalPreviewResult; + std::function m_FinalRenderFunc; + std::function m_FinalPreviewRenderFunc; FractoriumSettings* m_Settings; FractoriumFinalRenderDialog* m_FinalRender; @@ -108,14 +106,13 @@ public: virtual void CopyEmber(Ember& ember); virtual void SetEmberFile(const EmberFile& emberFile); virtual void CopyEmberFile(EmberFile& emberFile); + virtual void SetOriginalEmber(Ember& ember); #ifdef DO_DOUBLE virtual void SetEmber(const Ember& ember, bool verbatim = false); virtual void CopyEmber(Ember& ember); virtual void SetEmberFile(const EmberFile& emberFile); virtual void CopyEmberFile(EmberFile& emberFile); virtual void SetOriginalEmber(Ember& ember); -#else - virtual void SetOriginalEmber(Ember& ember); #endif virtual double OriginalAspect(); virtual int ProgressFunc(Ember& ember, void* foo, double fraction, int stage, double etaMs); @@ -135,7 +132,7 @@ protected: Ember m_PreviewEmber; EmberFile m_EmberFile; EmberToXml m_XmlWriter; - auto_ptr> m_PreviewRenderer; + auto_ptr> m_FinalPreviewRenderer; }; template class FinalRenderEmberController; diff --git a/Source/Fractorium/Fractorium.rc b/Source/Fractorium/Fractorium.rc index 1de293964dd67bf03287b0d7b037c89fb6154138..a4c5e63a289f8c0adb554be974b698ac1c6885c5 100644 GIT binary patch delta 46 wcmcbod{23U7YC!^WN!{bM#Igu9PG?Mjv|-%WC32W&6~KHm>}HEXLyBJ04;k9tN;K2 delta 42 wcmcbod{23U7YC!kWN!{bMuW|@9PG@K6}TiO3-F3<-o(ws1mbKy!z;uB00}z_MgRZ+