/* ZRendererBase.hpp Author: James Russell Created: 3/23/2011 Purpose: Base implementation of the ZRenderer class, which handles many of the details that are common to multi threaded renderers. License: TODO */ #pragma once #ifndef _ZRENDERERBASE_HPP #define _ZRENDERERBASE_HPP #include #include //Forward Declarations struct ZFrameData; //Maximum number of concurrent frame contexts #ifndef ZRB_MAX_FRAME_CONTEXT_COUNT #define ZRB_MAX_FRAME_CONTEXT_COUNT (4) #endif //Default slab allocation of Draw Objects, will auto correct at runtime if exceeded #ifndef ZRB_DEFAULT_DRAWDATA_COUNT #define ZRB_DEFAULT_DRAWDATA_COUNT (128) #endif //Default buffer size for a draw list #ifndef ZRB_DEFAULT_DRAWDATA_BUFFER_SIZE #define ZRB_DEFAULT_DRAWDATA_BUFFER_SIZE (128) #endif /* Used to contain only the minimum data necessary to draw geometry and hold no ownership (in smart pointer terms) over the parameters. */ struct ZDrawData { ZShaderProgram* ShaderProgram; //The shader program we will be drawing with ZShaderParams* ShaderParams; //The shader parameters we will be using ZVertexParams* VertexParams; //The vertex parameters we will be using ZIndexParams* IndexParams; //The index parameters we will be using ZRenderState RenderState; //The renderer state we will be using int DrawGroup; //The draw group for drawing data ZFrameData* Parent; //The parent ZFrameData struct that holds ownership //Default Constructor ZDrawData() : ShaderProgram(NULL), ShaderParams(NULL), VertexParams(NULL), IndexParams(NULL), RenderState(), DrawGroup(-1), Parent(NULL) { } }; /* Used to contain references to the data necessary to draw geometry per frame. Holds strong references long enough to ensure parameters do not get deleted. */ struct ZFrameData { ZArray< ZPtr > ShaderPrograms; //The shader programs we will be using ZArray< ZPtr > ShaderParams; //The shader parameters we will be using ZArray< ZPtr > VertexParams; //The vertex parameters we will be using ZArray< ZPtr > IndexParams; //The index parameters we will be using ZPtr RenderTarget; //The render target for this frame ZArray > DrawData; //Our set of draw data //Concurrency Control Variables ZMutex FrameLock; ZEvent FrameEndSignal; ZEvent FrameStartSignal; }; /* ZRendererBase class, which can be extended by GL-specific renderers. */ class ZRendererBase : public ZRenderer { private: //The renderer lock ZMutex RendererLock; //Current Render Phase volatile ZRenderPhase Phase; //Slab allocator for ZFrameData ZSlabAllocator DrawDataAllocator; //Slab allocator for ZFrameData ZSlabAllocator FrameDataAllocator; //The frame data available queue (available for use) ZRingBuffer > FrameAvailableQueue; //The frame data render queue (pending renders) ZRingBuffer > FrameRenderQueue; //The frame data we are rendering ZFrameData* CurrentFrame; protected: //Capabilities mapping ZHashMap Capabilities; //Protected Constructor ZRendererBase(); /* virtual protected ZRendererBase::init This will be called by ZRendererBase::Init and should handle subclass initialization. @return (bool) - true if successful, false otherwise */ virtual bool init() = 0; /* virtual protected ZRendererBase::shutdown This will be called by ZRendererBase::Shutdown and should handle subclass shutdown. @return (void) */ virtual void shutdown() = 0; /* virtual protected ZRendererBase::Draw Method which should, given a list of render data, draw it to the provided render target. @param _renderList - the sorted list of draw data objects to draw @param _renderTarget - the render target to draw to @return (void) */ virtual void Draw(ZArray >& _renderList, ZRenderTarget* _renderTarget) = 0; public: /* Destructor. */ virtual ~ZRendererBase(); ////////////////////////// /* Lifecycle Operations */ ////////////////////////// //Subclass Implementation virtual bool Init(); //Subclass Implementation virtual void Shutdown(); /////////////////////////// /* Renderer Data Getters */ /////////////////////////// //Subclass Override virtual const ZHashMap& GetCapabilities(); //Subclass Override virtual ZRenderPhase GetRenderPhase(); ////////////////////////// /* Logistics Operations */ ////////////////////////// //Subclass Implementation virtual ZPtr CreateDrawParams(ZDrawParamsType _type); //Not Implemented virtual ZPtr CreateDataBuffer(ZDataBufferType _type, ZDataBufferUsage _usage, size_t _size ) = 0; //Not Implemented virtual ZPtr CreateFrameBufferRenderTarget(size_t _width, size_t _height) = 0; //Not Implemented virtual ZPtr CreateRenderBuffer(ZRenderBufferType _type, size_t _width, size_t _height) = 0; //Not Implemented virtual ZPtr CreateSampler() = 0; //Not Implemented virtual ZPtr CreateShader(ZShaderType _type) = 0; //Not Implemented virtual ZPtr CreateShaderProgram() = 0; //Not Implemented virtual ZPtr CreateTexture(ZTextureType _type, ZTextureFormat _format, ZTextureUsage _usage, const ZBitmap& _bitmap, bool _generateMipmaps) = 0; //Not Implemented virtual ZPtr CreateWindowRenderTarget(SST_Window _window, size_t _screenIndex) = 0; //////////////////////// /* Frame Data Getters */ //////////////////////// //Subclass Implementation virtual ZRenderTarget* GetFrameRenderTarget(ZFrameContext _frameContext); ////////////////////////// /* Rendering Operations */ ////////////////////////// //Subclass Implementation virtual ZFrameContext BeginFrame(ZPtr _canvas); virtual void EndFrame(ZFrameContext _frameContext); //Subclass Implementation virtual void SubmitDrawData(ZFrameContext _frameContext, ZPtr _shaderProgram, ZPtr _shaderParams, ZPtr _vertexParams, ZPtr _indexParams, const ZRenderState& _renderState, int _drawGroup = 0 ); //Subclass Implementation virtual void RenderFrame(ZFrameContext _frameContext); //Subclass Implementation virtual void WaitFrameStart(ZFrameContext _frameContext); //Subclass Implementation virtual void WaitFrameEnd(ZFrameContext _frameContext); //Implementation of the render thread virtual ZThreadReturn run(uint64_t _dt); }; #endif