mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-21 05:00:06 -05:00
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:
parent
f5a707ea63
commit
2df1f7a52b
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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")
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,7 @@ private:
|
||||
bool SetMemory();
|
||||
|
||||
int m_MemoryCellIndex;
|
||||
int m_ItersCellIndex;
|
||||
int m_PathCellIndex;
|
||||
OpenCLWrapper m_Wrapper;
|
||||
Timing m_RenderTimer;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user