#pragma once #include "Utils.h" #include "Ember.h" #include "DensityFilter.h" /// /// RendererBase, RenderCallback and EmberStats classes. /// namespace EmberNs { /// /// 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. /// class EMBER_API RenderCallback { public: /// /// Virtual destructor to ensure anything declared in derived classes gets cleaned up. /// virtual ~RenderCallback() { } /// /// Empty progress function to be implemented in derived classes to take action on progress updates. /// /// The ember currently being rendered /// An extra dummy parameter /// The progress fraction from 0-100 /// The stage of iteration. 1 is iterating, 2 is density filtering, 2 is final accumulation. /// The estimated milliseconds to completion of the current stage /// Override should return 0 if an abort is requested, else 1 to continue rendering virtual int ProgressFunc(Ember& ember, void* foo, double fraction, int stage, double etaMs) { return 0; } virtual int ProgressFunc(Ember& ember, void* foo, double fraction, int stage, double etaMs) { return 0; } }; /// /// 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. /// class EMBER_API EmberStats { public: /// /// Constructor which sets all values to 0. /// EmberStats() { Clear(); } void Clear() { m_Iters = 0; m_Badvals = 0; m_IterMs = 0; m_RenderMs = 0; } EmberStats& operator += (const EmberStats& stats) { m_Iters += stats.m_Iters; m_Badvals += stats.m_Badvals; m_IterMs += stats.m_IterMs; m_RenderMs += stats.m_RenderMs; return *this; } size_t m_Iters, m_Badvals; double m_IterMs, m_RenderMs; }; /// /// 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. /// enum eRendererType { CPU_RENDERER, OPENCL_RENDERER }; /// /// 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. /// class EMBER_API RendererBase : public EmberReport { //using EmberReport::m_ErrorReport; public: RendererBase(); virtual ~RendererBase() { } //Non-virtual processing functions. void ChangeVal(std::function func, eProcessAction action); size_t HistMemoryRequired(size_t strips); pair MemoryRequired(size_t strips, bool includeFinal, bool threadedWrite); vector> RandVec(); bool PrepFinalAccumVector(vector& pixels); //Virtual processing functions. virtual bool Ok() const; virtual size_t MemoryAvailable(); virtual void SetEmber(Ember& ember, eProcessAction action = FULL_RENDER) { } virtual void SetEmber(vector>& embers) { } virtual void SetEmber(Ember& ember, eProcessAction action = FULL_RENDER) { } virtual void SetEmber(vector>& embers) { } virtual bool RandVec(vector>& randVec); //Abstract processing functions. virtual bool CreateDEFilter(bool& newAlloc) = 0; virtual bool CreateSpatialFilter(bool& newAlloc) = 0; virtual bool CreateTemporalFilter(bool& newAlloc) = 0; virtual void ComputeBounds() = 0; virtual void ComputeQuality() = 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(const 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(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); bool Transparency() const; void Transparency(bool transparency); void Callback(RenderCallback* callback); void ThreadCount(size_t threads, const char* seedString = nullptr); size_t BytesPerChannel() const; void BytesPerChannel(size_t bytesPerChannel); 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 void NumChannels(size_t numChannels); virtual size_t ThreadCount() const; virtual eRendererType RendererType() 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(); bool InRender(); bool InFinalAccum(); void* m_ProgressParameter; protected: bool m_EarlyClip; bool m_YAxisUp; bool m_Transparency; bool m_LockAccum; bool m_InRender; bool m_InFinalAccum; bool m_InsertPalette; bool m_ReclaimOnResize; bool m_CurvesSet; volatile bool m_Abort; size_t m_SuperRasW; size_t m_SuperRasH; size_t m_SuperSize; size_t m_GutterWidth; size_t m_DensityFilterOffset; size_t m_NumChannels; size_t m_BytesPerChannel; size_t m_ThreadsToUse; size_t m_VibGamCount; size_t m_LastTemporalSample; size_t m_LastIter; double m_LastIterPercent; eThreadPriority m_Priority; eProcessAction m_ProcessAction; eProcessState m_ProcessState; eInteractiveFilter m_InteractiveFilter; EmberStats m_Stats; RenderCallback* m_Callback; vector m_SubBatch; vector m_BadVals; vector> m_Rand; auto_ptr m_TaskGroup; CriticalSection m_RenderingCs, m_AccumCs, m_FinalAccumCs, m_ResizeCs; Timing m_RenderTimer, m_IterTimer, m_ProgressTimer; }; }