mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-21 21:20:07 -05:00
1dfbd4eff2
-Add new preset dimensions to the right click menu of the width and height fields in the editor. -Change QSS stylesheets to properly handle tabs. -Make tabs rectangular by default. For some reason, they had always been triangular. --Bug fixes -Incremental rendering times in the editor were wrong. --Code changes -Migrate to Qt6. There is probably more work to be done here. -Migrate to VS2022. -Migrate to Wix 4 installer. -Change installer to install to program files for all users. -Fix many VS2022 code analysis warnings. -No longer use byte typedef, because std::byte is now a type. Revert all back to unsigned char. -Upgrade OpenCL headers to version 3.0 and keep locally now rather than trying to look for system files. -No longer link to Nvidia or AMD specific OpenCL libraries. Use the generic installer located at OCL_ROOT too. -Add the ability to change OpenCL grid dimensions. This was attempted for investigating possible performance improvments, but made no difference. This has not been verified on Linux or Mac yet.
238 lines
8.4 KiB
C++
238 lines
8.4 KiB
C++
#pragma once
|
|
|
|
#include "Utils.h"
|
|
#include "Ember.h"
|
|
#include "DensityFilter.h"
|
|
|
|
/// <summary>
|
|
/// RendererBase, RenderCallback and EmberStats classes.
|
|
/// </summary>
|
|
|
|
namespace EmberNs
|
|
{
|
|
/// <summary>
|
|
/// Function pointers present a major restriction when dealing
|
|
/// with member functions, and that is they can only point to
|
|
/// static ones. So instead of a straight function pointer, use
|
|
/// a callback class with a single virtual callback
|
|
/// member function.
|
|
/// Template argument expected to be float or double.
|
|
/// </summary>
|
|
class EMBER_API RenderCallback
|
|
{
|
|
public:
|
|
RenderCallback() = default;
|
|
RenderCallback(RenderCallback& callback) = delete;
|
|
|
|
/// <summary>
|
|
/// Virtual destructor to ensure anything declared in derived classes gets cleaned up.
|
|
/// </summary>
|
|
virtual ~RenderCallback() = default;
|
|
|
|
/// <summary>
|
|
/// Empty progress function to be implemented in derived classes to take action on progress updates.
|
|
/// </summary>
|
|
/// <param name="ember">The ember currently being rendered</param>
|
|
/// <param name="foo">An extra dummy parameter</param>
|
|
/// <param name="fraction">The progress fraction from 0-100</param>
|
|
/// <param name="stage">The stage of iteration. 1 is iterating, 2 is density filtering, 2 is final accumulation.</param>
|
|
/// <param name="etaMs">The estimated milliseconds to completion of the current stage</param>
|
|
/// <returns>Override should return 0 if an abort is requested, else 1 to continue rendering</returns>
|
|
virtual int ProgressFunc(Ember<float>& ember, void* foo, double fraction, int stage, double etaMs) { return 0; }
|
|
virtual int ProgressFunc(Ember<double>& ember, void* foo, double fraction, int stage, double etaMs) { return 0; }
|
|
};
|
|
|
|
/// <summary>
|
|
/// Render statistics for the number of iterations ran,
|
|
/// number of bad values calculated during iteration, and
|
|
/// the total time for the entire render from the start of
|
|
/// iteration to the end of final accumulation.
|
|
/// </summary>
|
|
class EMBER_API EmberStats
|
|
{
|
|
public:
|
|
/// <summary>
|
|
/// Constructor which sets all values to 0.
|
|
/// </summary>
|
|
EmberStats() noexcept
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void Clear() noexcept
|
|
{
|
|
m_Success = true;
|
|
m_Iters = 0;
|
|
m_Badvals = 0;
|
|
m_IterMs = 0;
|
|
m_RenderMs = 0;
|
|
}
|
|
|
|
EmberStats& operator += (const EmberStats& stats) noexcept
|
|
{
|
|
m_Success &= stats.m_Success;
|
|
m_Iters += stats.m_Iters;
|
|
m_Badvals += stats.m_Badvals;
|
|
m_IterMs += stats.m_IterMs;
|
|
m_RenderMs += stats.m_RenderMs;
|
|
return *this;
|
|
}
|
|
|
|
bool m_Success = true;
|
|
size_t m_Iters, m_Badvals;
|
|
double m_IterMs, m_RenderMs;
|
|
};
|
|
|
|
/// <summary>
|
|
/// The types of available renderers.
|
|
/// Add more in the future as different rendering methods are experimented with.
|
|
/// Possible values might be: CPU+OpenGL, Particle, Inverse.
|
|
/// </summary>
|
|
enum class eRendererType : et { CPU_RENDERER, OPENCL_RENDERER };
|
|
|
|
/// <summary>
|
|
/// A base class with virtual functions to allow both templating and polymorphism to work together.
|
|
/// Derived classes will implement all of these functions.
|
|
/// Note that functions which return a decimal number use the most precise type, double.
|
|
/// </summary>
|
|
class EMBER_API RendererBase : public EmberReport
|
|
{
|
|
public:
|
|
RendererBase();
|
|
RendererBase(const RendererBase& renderer) = delete;
|
|
RendererBase& operator = (const RendererBase& renderer) = delete;
|
|
virtual ~RendererBase() = default;
|
|
|
|
//Non-virtual processing functions.
|
|
void ChangeVal(std::function<void(void)> func, eProcessAction action);
|
|
size_t HistMemoryRequired(size_t strips);
|
|
pair<size_t, size_t> MemoryRequired(size_t strips, bool includeFinal, bool threadedWrite);
|
|
vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>> RandVec();
|
|
bool PrepFinalAccumVector(vector<v4F>& pixels);
|
|
|
|
//Virtual processing functions.
|
|
virtual bool Ok() const;
|
|
virtual size_t MemoryAvailable();
|
|
virtual void SetEmber(const Ember<float>& ember, eProcessAction action = eProcessAction::FULL_RENDER, bool prep = false) { }
|
|
virtual void SetEmber(const Ember<double>& ember, eProcessAction action = eProcessAction::FULL_RENDER, bool prep = false) { }
|
|
virtual bool RandVec(vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>>& randVec);
|
|
|
|
//Abstract processing functions.
|
|
virtual bool CreateDEFilter(bool& newAlloc) = 0;
|
|
virtual bool CreateSpatialFilter(bool& newAlloc) = 0;
|
|
virtual bool CreateTemporalFilter(bool& newAlloc) = 0;
|
|
virtual void Prepare() = 0;
|
|
virtual void ComputeBounds() = 0;
|
|
virtual void ComputeQuality() = 0;
|
|
virtual void ComputeCamera() = 0;
|
|
virtual eRenderStatus Run(vector<v4F>& finalImage, double time = 0, size_t subBatchCountOverride = 0, bool forceOutput = false, size_t finalOffset = 0) = 0;
|
|
virtual EmberImageComments ImageComments(const EmberStats& stats, size_t printEditDepth = 0, 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(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;
|
|
void LockAccum(bool lockAccum);
|
|
bool EarlyClip() const;
|
|
void EarlyClip(bool earlyClip);
|
|
bool YAxisUp() const;
|
|
void YAxisUp(bool yup);
|
|
bool InsertPalette() const;
|
|
void InsertPalette(bool insertPalette);
|
|
bool ReclaimOnResize() const;
|
|
void ReclaimOnResize(bool reclaimOnResize);
|
|
void Callback(RenderCallback* callback);
|
|
void ThreadCount(size_t threads, const char* seedString = nullptr);
|
|
size_t BytesPerChannel() const;
|
|
size_t NumChannels() const;
|
|
eThreadPriority Priority() const;
|
|
void Priority(eThreadPriority priority);
|
|
eInteractiveFilter InteractiveFilter() const;
|
|
void InteractiveFilter(eInteractiveFilter filter);
|
|
|
|
//Virtual render properties, getters and setters.
|
|
virtual size_t ThreadCount() const;
|
|
virtual eRendererType RendererType() const;
|
|
virtual bool Shared() const;
|
|
|
|
//Abstract render properties, getters only.
|
|
virtual size_t TemporalSamples() const = 0;
|
|
virtual size_t HistBucketSize() const = 0;
|
|
virtual size_t FinalRasW() const = 0;
|
|
virtual size_t FinalRasH() const = 0;
|
|
virtual size_t SubBatchSize() const = 0;
|
|
virtual size_t FuseCount() const = 0;
|
|
virtual double ScaledQuality() const = 0;
|
|
virtual double LowerLeftX(bool gutter = true) const = 0;
|
|
virtual double LowerLeftY(bool gutter = true) const = 0;
|
|
virtual double UpperRightX(bool gutter = true) const = 0;
|
|
virtual double UpperRightY(bool gutter = true) const = 0;
|
|
|
|
//Non-virtual threading control.
|
|
void Reset();
|
|
void EnterRender();
|
|
void LeaveRender();
|
|
void EnterFinalAccum();
|
|
void LeaveFinalAccum();
|
|
void EnterResize();
|
|
void LeaveResize();
|
|
void Abort();
|
|
bool Aborted();
|
|
void Pause(bool pause);
|
|
bool Paused();
|
|
bool InRender();
|
|
bool InFinalAccum();
|
|
|
|
void* m_ProgressParameter = nullptr;
|
|
protected:
|
|
bool m_EarlyClip = false;
|
|
bool m_YAxisUp = false;
|
|
bool m_LockAccum = false;
|
|
bool m_InRender = false;
|
|
bool m_InFinalAccum = false;
|
|
bool m_InsertPalette = false;
|
|
bool m_ReclaimOnResize = false;
|
|
bool m_CurvesSet = false;
|
|
volatile bool m_Abort = false;
|
|
volatile bool m_Pause = false;
|
|
size_t m_SuperRasW;
|
|
size_t m_SuperRasH;
|
|
size_t m_SuperSize = 0;
|
|
size_t m_GutterWidth;
|
|
size_t m_DensityFilterOffset;
|
|
size_t m_NumChannels = 4;
|
|
size_t m_BytesPerChannel = 4;
|
|
size_t m_ThreadsToUse;
|
|
size_t m_VibGamCount;
|
|
size_t m_LastTemporalSample = 0;
|
|
size_t m_LastIter = 0;
|
|
double m_LastIterPercent = 0;
|
|
eThreadPriority m_Priority = eThreadPriority::NORMAL;
|
|
eProcessAction m_ProcessAction = eProcessAction::FULL_RENDER;
|
|
eProcessState m_ProcessState = eProcessState::NONE;
|
|
eInteractiveFilter m_InteractiveFilter = eInteractiveFilter::FILTER_LOG;
|
|
EmberStats m_Stats;
|
|
RenderCallback* m_Callback = nullptr;
|
|
vector<size_t> m_SubBatch;
|
|
vector<size_t> m_BadVals;
|
|
vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>> m_Rand;
|
|
std::recursive_mutex m_RenderingCs, m_AccumCs, m_FinalAccumCs, m_ResizeCs;
|
|
Timing m_RenderTimer, m_IterTimer, m_ProgressTimer;
|
|
};
|
|
}
|