diff --git a/Source/Ember/Affine2D.cpp b/Source/Ember/Affine2D.cpp index 8661c08..8b1bf6a 100644 --- a/Source/Ember/Affine2D.cpp +++ b/Source/Ember/Affine2D.cpp @@ -101,28 +101,6 @@ bool Affine2D::operator == (const Affine2D& affine) IsClose(F(), affine.F()); } -/// -/// * operator to multiply this affine transform by another and return the result. -/// -/// The Affine2D to multiply by -/// A new Affine2D which is the product of the multiplication -template -Affine2D& Affine2D::operator * (const Affine2D& affine) -{ - v2T x = affine.X(); - v2T y = affine.Y(); - v2T o = affine.O(); - v2T tx = TransformNormal(x); - v2T ty = TransformNormal(y); - v2T to = TransformNormal(o); - - X(tx); - Y(ty); - O(to); - - return *this; -} - /// /// * operator to multiply this affine transform by a vec2 and return the result as a vec2. /// @@ -277,7 +255,7 @@ template typename m2T Affine2D::ToMat2ColMajor() const { return m2T(A(), B(),//Col0... - D(), E());//1 + D(), E());//1 } /// @@ -288,7 +266,7 @@ template typename m2T Affine2D::ToMat2RowMajor() const { return m2T(A(), D(),//Col0... - B(), E());//1 + B(), E());//1 } /// @@ -299,10 +277,10 @@ typename m2T Affine2D::ToMat2RowMajor() const template typename m4T Affine2D::ToMat4ColMajor(bool center) const { - m4T mat(A(), B(), 0, center ? 0 : C(),//Col0... - D(), E(), 0, center ? 0 : F(),//1 - 0, 0, 1, 0,//2 - 0, 0, 0, 1);//3 + m4T mat(A(), B(), 0, center ? 0 : C(), //Col0... + D(), E(), 0, center ? 0 : F(), //1 + 0, 0, 1, 0, //2 + 0, 0, 0, 1);//3 return mat; } @@ -316,9 +294,9 @@ template typename m4T Affine2D::ToMat4RowMajor(bool center) const { m4T mat(A(), D(), 0, 0, - B(), E(), 0, 0, - 0, 0, 1, 0, - center ? 0 : C(), center ? 0 : F(), 0, 1); + B(), E(), 0, 0, + 0, 0, 1, 0, + center ? 0 : C(), center ? 0 : F(), 0, 1); return mat; } diff --git a/Source/Ember/Affine2D.h b/Source/Ember/Affine2D.h index 6e0f54c..3bfb232 100644 --- a/Source/Ember/Affine2D.h +++ b/Source/Ember/Affine2D.h @@ -69,7 +69,6 @@ public: } bool operator == (const Affine2D& affine); - Affine2D& operator * (const Affine2D& affine); v2T operator * (const v2T& v); void MakeID(); diff --git a/Source/Ember/Renderer.h b/Source/Ember/Renderer.h index 8c0a6e3..80494f5 100644 --- a/Source/Ember/Renderer.h +++ b/Source/Ember/Renderer.h @@ -50,12 +50,12 @@ public: virtual ~Renderer(); //Non-virtual processing functions. - void ComputeCamera(); void AddEmber(Ember& ember); bool AssignIterator(); //Virtual processing functions overriden from RendererBase. virtual void ComputeBounds() override; + virtual void ComputeCamera() override; virtual void SetEmber(Ember& ember, eProcessAction action = FULL_RENDER) override; virtual void SetEmber(vector>& embers) override; virtual bool CreateDEFilter(bool& newAlloc) override; diff --git a/Source/Ember/RendererBase.cpp b/Source/Ember/RendererBase.cpp index 9d82832..8b14263 100644 --- a/Source/Ember/RendererBase.cpp +++ b/Source/Ember/RendererBase.cpp @@ -273,20 +273,20 @@ size_t RendererBase::MemoryAvailable() /// Non-virtual renderer properties, getters only. /// -size_t RendererBase::SuperRasW() const { return m_SuperRasW; } -size_t RendererBase::SuperRasH() const { return m_SuperRasH; } -size_t RendererBase::SuperSize() const { return m_SuperSize; } -size_t RendererBase::FinalRowSize() const { return FinalRasW() * PixelSize(); } -size_t RendererBase::FinalDimensions() const { return FinalRasW() * FinalRasH(); } -size_t RendererBase::FinalBufferSize() const { return FinalRowSize() * FinalRasH(); } -size_t RendererBase::PixelSize() const { return NumChannels() * BytesPerChannel(); } -size_t RendererBase::GutterWidth() const { return m_GutterWidth; } -size_t RendererBase::DensityFilterOffset() const { return m_DensityFilterOffset; } -size_t RendererBase::TotalIterCount() const { return (size_t)((size_t)Round(ScaledQuality()) * FinalRasW() * FinalRasH()); }//Use Round() because there can be some roundoff error when interpolating. -size_t RendererBase::ItersPerTemporalSample() const { return (size_t)ceil(double(TotalIterCount()) / double(Passes() * TemporalSamples())); } -eProcessState RendererBase::ProcessState() const { return m_ProcessState; } -eProcessAction RendererBase::ProcessAction() const { return m_ProcessAction; } -EmberStats RendererBase::Stats() const { return m_Stats; } +size_t RendererBase::SuperRasW() const { return m_SuperRasW; } +size_t RendererBase::SuperRasH() const { return m_SuperRasH; } +size_t RendererBase::SuperSize() const { return m_SuperSize; } +size_t RendererBase::FinalRowSize() const { return FinalRasW() * PixelSize(); } +size_t RendererBase::FinalDimensions() const { return FinalRasW() * FinalRasH(); } +size_t RendererBase::FinalBufferSize() const { return FinalRowSize() * FinalRasH(); } +size_t RendererBase::PixelSize() const { return NumChannels() * BytesPerChannel(); } +size_t RendererBase::GutterWidth() const { return m_GutterWidth; } +size_t RendererBase::DensityFilterOffset() const { return m_DensityFilterOffset; } +size_t RendererBase::TotalIterCount(size_t strips) const { return (size_t)((size_t)Round(ScaledQuality()) * FinalRasW() * FinalRasH() * strips); }//Use Round() because there can be some roundoff error when interpolating. +size_t RendererBase::ItersPerTemporalSample() const { return (size_t)ceil(double(TotalIterCount(1)) / double(Passes() * TemporalSamples())); }//Temporal samples is used with animation, which doesn't support strips, so pass 1. +eProcessState RendererBase::ProcessState() const { return m_ProcessState; } +eProcessAction RendererBase::ProcessAction() const { return m_ProcessAction; } +EmberStats RendererBase::Stats() const { return m_Stats; } /// /// Non-virtual render properties, getters and setters. diff --git a/Source/Ember/RendererBase.h b/Source/Ember/RendererBase.h index 27c6c40..d83438f 100644 --- a/Source/Ember/RendererBase.h +++ b/Source/Ember/RendererBase.h @@ -115,25 +115,26 @@ public: virtual bool CreateSpatialFilter(bool& newAlloc) = 0; virtual bool CreateTemporalFilter(bool& newAlloc) = 0; virtual void ComputeBounds() = 0; + virtual void ComputeCamera() = 0; virtual eRenderStatus Run(vector& finalImage, double time = 0, size_t subBatchCountOverride = 0, bool forceOutput = false, size_t finalOffset = 0) = 0; virtual EmberImageComments ImageComments(EmberStats& stats, size_t printEditDepth = 0, bool intPalette = false, bool hexPalette = true) = 0; virtual DensityFilterBase* GetDensityFilter() = 0; //Non-virtual renderer properties, getters only. - size_t SuperRasW() const; - size_t SuperRasH() const; - size_t SuperSize() const; - size_t FinalRowSize() const; - size_t FinalDimensions() const; - size_t FinalBufferSize() const; - size_t PixelSize() const; - size_t GutterWidth() const; - size_t DensityFilterOffset() const; - size_t TotalIterCount() const; - size_t ItersPerTemporalSample() const; - eProcessState ProcessState() const; - eProcessAction ProcessAction() const; - EmberStats Stats() const; + size_t SuperRasW() const; + size_t SuperRasH() const; + size_t SuperSize() const; + size_t FinalRowSize() const; + size_t FinalDimensions() const; + size_t FinalBufferSize() const; + size_t PixelSize() const; + size_t GutterWidth() const; + size_t DensityFilterOffset() const; + size_t TotalIterCount(size_t strips) const; + size_t ItersPerTemporalSample() const; + eProcessState ProcessState() const; + eProcessAction ProcessAction() const; + EmberStats Stats() const; //Non-virtual render getters and setters. bool LockAccum() const; diff --git a/Source/Ember/SpatialFilter.h b/Source/Ember/SpatialFilter.h index 5e4b421..6743221 100644 --- a/Source/Ember/SpatialFilter.h +++ b/Source/Ember/SpatialFilter.h @@ -142,7 +142,7 @@ public: } //Attempt to normalize, and increase the filter width if the values were too small. - if (!Normalize()) + if (Normalize()) { m_FinalFilterWidth = fwidth; break; diff --git a/Source/EmberAnimate/EmberAnimate.cpp b/Source/EmberAnimate/EmberAnimate.cpp index a5745f6..d05aa2d 100644 --- a/Source/EmberAnimate/EmberAnimate.cpp +++ b/Source/EmberAnimate/EmberAnimate.cpp @@ -300,7 +300,8 @@ bool EmberAnimate(EmberOptions& opt) stats = renderer->Stats(); comments = renderer->ImageComments(stats, opt.PrintEditDepth(), opt.IntPalette(), opt.HexPalette()); os.str(""); - os << comments.m_NumIters << " / " << renderer->TotalIterCount() << " (" << std::fixed << std::setprecision(2) << ((double)stats.m_Iters/(double)renderer->TotalIterCount() * 100) << "%)"; + size_t iterCount = renderer->TotalIterCount(1); + os << comments.m_NumIters << " / " << iterCount << " (" << std::fixed << std::setprecision(2) << ((double)stats.m_Iters / (double)iterCount * 100) << "%)"; VerbosePrint("\nIters ran/requested: " + os.str()); VerbosePrint("Bad values: " << stats.m_Badvals); diff --git a/Source/EmberRender/EmberRender.cpp b/Source/EmberRender/EmberRender.cpp index c2e7e05..f717735 100644 --- a/Source/EmberRender/EmberRender.cpp +++ b/Source/EmberRender/EmberRender.cpp @@ -262,8 +262,7 @@ bool EmberRender(EmberOptions& opt) //TotalIterCount() is actually using ScaledQuality() which does not get reset upon ember assignment, //so it ends up using the correct value for quality * strips. - writeSuccess = false; - iterCount = renderer->TotalIterCount(); + iterCount = renderer->TotalIterCount(1); comments = renderer->ImageComments(stats, opt.PrintEditDepth(), opt.IntPalette(), opt.HexPalette()); os.str(""); os << comments.m_NumIters << " / " << iterCount << " (" << std::fixed << std::setprecision(2) << (((double)stats.m_Iters / (double)iterCount) * 100) << "%)"; @@ -286,6 +285,8 @@ bool EmberRender(EmberOptions& opt) finalImagep = finalImage.data(); } + writeSuccess = false; + if (opt.Format() == "png") writeSuccess = WritePng(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.BitsPerChannel() / 8, opt.PngComments(), comments, opt.Id(), opt.Url(), opt.Nick()); else if (opt.Format() == "jpg") diff --git a/Source/Fractorium/FinalRenderDialog.cpp b/Source/Fractorium/FinalRenderDialog.cpp index cdb19be..3e0e59f 100644 --- a/Source/Fractorium/FinalRenderDialog.cpp +++ b/Source/Fractorium/FinalRenderDialog.cpp @@ -55,6 +55,7 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set SetupSpinner (table, this, row, 1, m_StripsSpin, spinHeight, 1, 64, 1, SIGNAL(valueChanged(int)), SLOT(OnStripsChanged(int)), true, 1, 1, 1); m_MemoryCellIndex = row++;//Memory usage. + m_ItersCellIndex = row++;//Iters. m_PathCellIndex = row; QStringList comboList; @@ -698,7 +699,10 @@ bool FractoriumFinalRenderDialog::SetMemory() { if (isVisible() && CreateControllerFromGUI(true)) { - ui.FinalRenderParamsTable->item(m_MemoryCellIndex, 1)->setText(ToString(m_Controller->SyncAndComputeMemory())); + pair p = m_Controller->SyncAndComputeMemory(); + + ui.FinalRenderParamsTable->item(m_MemoryCellIndex, 1)->setText(ToString(p.first)); + ui.FinalRenderParamsTable->item(m_ItersCellIndex, 1)->setText(ToString(p.second)); return true; } diff --git a/Source/Fractorium/FinalRenderDialog.h b/Source/Fractorium/FinalRenderDialog.h index 6d5d1a8..e34de69 100644 --- a/Source/Fractorium/FinalRenderDialog.h +++ b/Source/Fractorium/FinalRenderDialog.h @@ -110,6 +110,7 @@ private: bool SetMemory(); int m_MemoryCellIndex; + int m_ItersCellIndex; int m_PathCellIndex; OpenCLWrapper m_Wrapper; Timing m_RenderTimer; diff --git a/Source/Fractorium/FinalRenderDialog.ui b/Source/Fractorium/FinalRenderDialog.ui index c82d260..602ec80 100644 --- a/Source/Fractorium/FinalRenderDialog.ui +++ b/Source/Fractorium/FinalRenderDialog.ui @@ -565,13 +565,13 @@ 0 - 178 + 198 16777215 - 178 + 198 @@ -680,6 +680,11 @@ Memory Usage + + + Iterations + + Output @@ -769,23 +774,20 @@ - Output - - - The output file path for rendering a single flame, or folder location for rendering multiple flames + Iterations - + 0 - Prefix + Output - The prefix to attach to all image filenames + The output file path for rendering a single flame, or folder location for rendering multiple flames @@ -794,6 +796,19 @@ + + Prefix + + + The prefix to attach to all image filenames + + + + + + + + Suffix @@ -801,7 +816,7 @@ The suffix to attach to all image filenames - + diff --git a/Source/Fractorium/FinalRenderEmberController.cpp b/Source/Fractorium/FinalRenderEmberController.cpp index c293651..13ede86 100644 --- a/Source/Fractorium/FinalRenderEmberController.cpp +++ b/Source/Fractorium/FinalRenderEmberController.cpp @@ -566,8 +566,10 @@ void FinalRenderEmberController::ResetProgress(bool total) /// /// If successful, memory required in bytes, else zero. template -size_t FinalRenderEmberController::SyncAndComputeMemory() +pair FinalRenderEmberController::SyncAndComputeMemory() { + pair p(0, 0); + if (m_Renderer.get()) { bool b = false; @@ -579,12 +581,14 @@ size_t FinalRenderEmberController::SyncAndComputeMemory() m_Renderer->CreateTemporalFilter(b); m_Renderer->NumChannels(channels); m_Renderer->ComputeBounds(); + m_Renderer->ComputeCamera(); CancelPreviewRender(); m_FinalPreviewRenderFunc(); - return m_Renderer->MemoryRequired(m_FinalRenderDialog->Strips(), true); + p.first = m_Renderer->MemoryRequired(m_FinalRenderDialog->Strips(), true); + p.second = m_Renderer->TotalIterCount(m_FinalRenderDialog->Strips()); } - return 0; + return p; } /// diff --git a/Source/Fractorium/FinalRenderEmberController.h b/Source/Fractorium/FinalRenderEmberController.h index 7743a4d..48b97fc 100644 --- a/Source/Fractorium/FinalRenderEmberController.h +++ b/Source/Fractorium/FinalRenderEmberController.h @@ -63,7 +63,7 @@ public: virtual void SyncGuiToEmbers(size_t widthOverride = 0, size_t heightOverride = 0) { } virtual void SyncCurrentToSizeSpinners(bool scale, bool size) { } virtual void ResetProgress(bool total = true) { } - virtual size_t SyncAndComputeMemory() { return 0; } + virtual pair SyncAndComputeMemory() { return pair(0, 0); } virtual double OriginalAspect() { return 1; } virtual QString ComposePath(const QString& name) { return ""; } @@ -121,7 +121,7 @@ public: virtual void SyncGuiToEmbers(size_t widthOverride = 0, size_t heightOverride = 0) override; virtual void SyncCurrentToSizeSpinners(bool scale, bool size) override; virtual void ResetProgress(bool total = true) override; - virtual size_t SyncAndComputeMemory() override; + virtual pair SyncAndComputeMemory() override; virtual double OriginalAspect() override { return double(m_Ember->m_OrigFinalRasW) / m_Ember->m_OrigFinalRasH; } virtual QString Name() const override { return QString::fromStdString(m_Ember->m_Name); } virtual QString ComposePath(const QString& name) override; diff --git a/Source/Fractorium/FractoriumParams.cpp b/Source/Fractorium/FractoriumParams.cpp index f56a783..4c10628 100644 --- a/Source/Fractorium/FractoriumParams.cpp +++ b/Source/Fractorium/FractoriumParams.cpp @@ -520,6 +520,7 @@ void FractoriumEmberController::FillParamTablesAndPalette() m_Fractorium->m_CenterXSpin->SetValueStealth(m_Ember.m_CenterX); m_Fractorium->m_CenterYSpin->SetValueStealth(m_Ember.m_CenterY); m_Fractorium->m_ScaleSpin->SetValueStealth(m_Ember.m_PixelsPerUnit); + m_Fractorium->m_ZoomSpin->SetValueStealth(m_Ember.m_Zoom); m_Fractorium->m_RotateSpin->SetValueStealth(m_Ember.m_Rotate); m_Fractorium->m_ZPosSpin->SetValueStealth(m_Ember.m_CamZPos); m_Fractorium->m_PerspectiveSpin->SetValueStealth(m_Ember.m_CamPerspective); @@ -582,6 +583,7 @@ void FractoriumEmberController::ParamsToEmber(Ember& ember) ember.m_CenterX = m_Fractorium->m_CenterXSpin->value(); ember.m_CenterY = m_Fractorium->m_CenterYSpin->value(); ember.m_PixelsPerUnit = m_Fractorium->m_ScaleSpin->value(); + ember.m_Zoom = m_Fractorium->m_ZoomSpin->value(); ember.m_Rotate = m_Fractorium->m_RotateSpin->value(); ember.m_CamZPos = m_Fractorium->m_ZPosSpin->value(); ember.m_CamPerspective = m_Fractorium->m_PerspectiveSpin->value(); diff --git a/Source/Fractorium/GLWidget.cpp b/Source/Fractorium/GLWidget.cpp index cc36078..f546e94 100644 --- a/Source/Fractorium/GLWidget.cpp +++ b/Source/Fractorium/GLWidget.cpp @@ -713,7 +713,7 @@ void GLWidget::wheelEvent(QWheelEvent* e) if (GLEmberControllerBase* controller = GLController()) controller->Wheel(e); - QGLWidget::wheelEvent(e); + //Do not call QGLWidget::wheelEvent(e) because this should only affect the scale and not the position of the scroll bars. } /// @@ -727,17 +727,15 @@ void GLWidget::resizeEvent(QResizeEvent* e) { if (m_Fractorium) { - //qDebug() << "GLWidget::resizeEvent() : w, h: " << width() << ", " << height() << ". oldsize: " << e->oldSize().width() << ", " << e->oldSize().height(); - //m_Fractorium->m_WidthSpin->setValue(width()); - //m_Fractorium->m_HeightSpin->setValue(height()); - - // if (GLEmberControllerBase* controller = GLController()) - // controller->SyncSizes();//For some reason the base resize can't be called here or else it causes a crash. } - - //QGLWidget::resizeEvent(e); } +/// +/// Set the dimensions of the drawing area. +/// This will be called from the main window's SyncSizes() function. +/// +/// Width in pixels +/// Height in pixels void GLWidget::SetDimensions(int w, int h) { setFixedSize(w, h);