#pragma once /** @brief Base class for a computation module. A run typically - but not necessarily or exclusively - consists of a series of rendering passes. A run is alway created to compute some kind of resource for a RenderTechnique. The type of the resource depends on the type of the run (typically it is a Texture). Runs can be attached to only one Technique (if only one of the Techniques attached to a Renderable can use this resource, and each Renderable requires a unique one), or can be shared between several Techniques and Renderables (for example a cube-map). Runs are updated only once in a frame, but not necessary in each frame. */ class RenderingRun { public: /** @brief Constructor. @param startFrame adds an offset to the current frame number to help evenly distribute updates between frames @param updateInterval photon map update frequency */ RenderingRun(unsigned long startFrame, unsigned long updateInterval); /** @brief Calls updateFrame() if the run needs update according to its starting frame and update interval and has not been allready updated in this frame. */ bool update(unsigned long frameNum) { bool needupdate = needUpdate(frameNum); if(needupdate) { updateFrame(frameNum); lastupdated = frameNum; } return needupdate; } /** @brief Conversion to OgreRenderRun. This function is needed because of virtual inheritance. */ virtual class OgreRenderingRun* asOgreRenderingRun(){return 0;} /** @brief Returns true if two runs can be joined. In some cases special requirements should stand to join two runs (even if they have the same type). Eg.: two caustic cube map generation technique should only be joined if they use the same material when rendering the caustic cubemap. */ virtual bool canJoin(RenderingRun* run){return true;} virtual void freeAllResources()=0; protected: /** @brief Returns if this run needs update This tipically depends on the upate interval and the starting frame number. @param frameNum current frame number */ virtual bool needUpdate(unsigned long frameNum ) { if(frameNum == lastupdated ) return false; if ( updateInterval == 0 ) //update only once { if( lastupdated == 0) { return true; } return false; } else { return ((frameNum - startFrame) % updateInterval == 0); } } /** @brief The number of the last frame this run was updated. */ unsigned long lastupdated; /** @brief The number of the frame this run should be updated first. */ unsigned long startFrame; /** @brief Refresh frequency in frames. */ unsigned long updateInterval; /** @brief This function does the actual update in a frame. @param frameNum current frame number */ virtual void updateFrame(unsigned long frameNum){} };