Affine2D: Remove * operator, it's unused.

RendererBase: Add ComputeCamera() as a virtual function. Add strips parameter to TotalIterCount().

Renderer: Implement ComputeCamera() as an override.

SpatialFilter: Ensure filters that are too small are made large enough to create.

FinalRenderDialog: Add estimated iters table row and populate on all UI updates.

FractoriumParams: Zoom was not being saved, loaded. Fixed.

GLWidget: Prevent mouse wheel event from being passed to the scroll bars. It should only affect the scale.
This commit is contained in:
mfeemster 2014-10-18 12:56:37 -07:00
parent f5a707ea63
commit 2df1f7a52b
15 changed files with 94 additions and 90 deletions

View File

@ -101,28 +101,6 @@ bool Affine2D<T>::operator == (const Affine2D<T>& affine)
IsClose(F(), affine.F());
}
/// <summary>
/// * operator to multiply this affine transform by another and return the result.
/// </summary>
/// <param name="affine">The Affine2D to multiply by</param>
/// <returns>A new Affine2D which is the product of the multiplication</returns>
template <typename T>
Affine2D<T>& Affine2D<T>::operator * (const Affine2D<T>& 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;
}
/// <summary>
/// * operator to multiply this affine transform by a vec2 and return the result as a vec2.
/// </summary>
@ -277,7 +255,7 @@ template <typename T>
typename m2T Affine2D<T>::ToMat2ColMajor() const
{
return m2T(A(), B(),//Col0...
D(), E());//1
D(), E());//1
}
/// <summary>
@ -288,7 +266,7 @@ template <typename T>
typename m2T Affine2D<T>::ToMat2RowMajor() const
{
return m2T(A(), D(),//Col0...
B(), E());//1
B(), E());//1
}
/// <summary>
@ -299,10 +277,10 @@ typename m2T Affine2D<T>::ToMat2RowMajor() const
template <typename T>
typename m4T Affine2D<T>::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 T>
typename m4T Affine2D<T>::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;
}

View File

@ -69,7 +69,6 @@ public:
}
bool operator == (const Affine2D<T>& affine);
Affine2D<T>& operator * (const Affine2D<T>& affine);
v2T operator * (const v2T& v);
void MakeID();

View File

@ -50,12 +50,12 @@ public:
virtual ~Renderer();
//Non-virtual processing functions.
void ComputeCamera();
void AddEmber(Ember<T>& ember);
bool AssignIterator();
//Virtual processing functions overriden from RendererBase.
virtual void ComputeBounds() override;
virtual void ComputeCamera() override;
virtual void SetEmber(Ember<T>& ember, eProcessAction action = FULL_RENDER) override;
virtual void SetEmber(vector<Ember<T>>& embers) override;
virtual bool CreateDEFilter(bool& newAlloc) override;

View File

@ -273,20 +273,20 @@ size_t RendererBase::MemoryAvailable()
/// Non-virtual renderer properties, getters only.
/// </summary>
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; }
/// <summary>
/// Non-virtual render properties, getters and setters.

View File

@ -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<unsigned char>& 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;

View File

@ -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;

View File

@ -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);

View File

@ -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")

View File

@ -55,6 +55,7 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
SetupSpinner<SpinBox, int> (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<size_t, size_t> 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;
}

View File

@ -110,6 +110,7 @@ private:
bool SetMemory();
int m_MemoryCellIndex;
int m_ItersCellIndex;
int m_PathCellIndex;
OpenCLWrapper m_Wrapper;
Timing m_RenderTimer;

View File

@ -565,13 +565,13 @@
<property name="minimumSize">
<size>
<width>0</width>
<height>178</height>
<height>198</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>178</height>
<height>198</height>
</size>
</property>
<property name="focusPolicy">
@ -680,6 +680,11 @@
<string>Memory Usage</string>
</property>
</row>
<row>
<property name="text">
<string>Iterations</string>
</property>
</row>
<row>
<property name="text">
<string>Output</string>
@ -769,23 +774,20 @@
</item>
<item row="5" column="0">
<property name="text">
<string>Output</string>
</property>
<property name="toolTip">
<string>The output file path for rendering a single flame, or folder location for rendering multiple flames</string>
<string>Iterations</string>
</property>
</item>
<item row="5" column="1">
<property name="text">
<string/>
<string>0</string>
</property>
</item>
<item row="6" column="0">
<property name="text">
<string>Prefix</string>
<string>Output</string>
</property>
<property name="toolTip">
<string>The prefix to attach to all image filenames</string>
<string>The output file path for rendering a single flame, or folder location for rendering multiple flames</string>
</property>
</item>
<item row="6" column="1">
@ -794,6 +796,19 @@
</property>
</item>
<item row="7" column="0">
<property name="text">
<string>Prefix</string>
</property>
<property name="toolTip">
<string>The prefix to attach to all image filenames</string>
</property>
</item>
<item row="7" column="1">
<property name="text">
<string/>
</property>
</item>
<item row="8" column="0">
<property name="text">
<string>Suffix</string>
</property>
@ -801,7 +816,7 @@
<string>The suffix to attach to all image filenames</string>
</property>
</item>
<item row="7" column="1">
<item row="8" column="1">
<property name="text">
<string/>
</property>

View File

@ -566,8 +566,10 @@ void FinalRenderEmberController<T>::ResetProgress(bool total)
/// </summary>
/// <returns>If successful, memory required in bytes, else zero.</returns>
template <typename T>
size_t FinalRenderEmberController<T>::SyncAndComputeMemory()
pair<size_t, size_t> FinalRenderEmberController<T>::SyncAndComputeMemory()
{
pair<size_t, size_t> p(0, 0);
if (m_Renderer.get())
{
bool b = false;
@ -579,12 +581,14 @@ size_t FinalRenderEmberController<T>::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;
}
/// <summary>

View File

@ -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<size_t, size_t> SyncAndComputeMemory() { return pair<size_t, size_t>(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<size_t, size_t> 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;

View File

@ -520,6 +520,7 @@ void FractoriumEmberController<T>::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<T>::ParamsToEmber(Ember<T>& 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();

View File

@ -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.
}
/// <summary>
@ -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);
}
/// <summary>
/// Set the dimensions of the drawing area.
/// This will be called from the main window's SyncSizes() function.
/// </summary>
/// <param name="w">Width in pixels</param>
/// <param name="h">Height in pixels</param>
void GLWidget::SetDimensions(int w, int h)
{
setFixedSize(w, h);