/* ZRenderer.hpp Authors: Patrick Baggett , Chris Ertel , James Russell Created: 3/20/2011 Purpose: Defines an interface for rendering to screen in graphics-library agnostic fashion. License: TODO */ #pragma once #ifndef _ZRENDERER_HPP #define _ZRENDERER_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include //Forward Declarations class ZRenderer; //Typedef for a frame context (opaque handle) typedef void* ZFrameContext; //Rendering phases the ZRenderer can exist in enum ZRenderPhase { ZRP_UNINITIALIZED, //Renderer has yet to be initialized ZRP_IDLE, //Renderer is idle (no frame contexts currently created) ZRP_FRAME_ACCEPTING, //Renderer is accepting SubmitDrawData calls (frame contexts have been created) ZRP_FRAME_RENDERING, //Renderer is rendering Geometry (a frame context is rendering) ZRP_SIZE }; //Render State Structure, used to set up a render state for SubmitDrawData calls struct ZRenderState { public: //The default constructor for render state initializes to a sane configuration ZRenderState() : EnableStencilTest(false), EnableBlend(true), SourceBlendFunc(SBFV_SRC_ALPHA), DestBlendFunc(DBFV_ONE_MINUS_SRC_ALPHA), blendR(0), blendG(0), blendB(0), blendA(0), EnableCullTest(false), EnableDepthTest(true), DepthFunc(DFV_LESS_THAN), EnableDepthWrite(true) { } ///////////////////////////////// /* Draw Sort Relevant Settings */ ///////////////////////////////// // BLENDING uint32_t EnableBlend:1; //Enables Blending uint32_t SourceBlendFunc:4; //Specifies Source Blending Function uint32_t DestBlendFunc:3; //Specifies Destination Blending Function enum SourceBlendFuncValue //Values for the Source Blend Function { SBFV_ZERO, SBFV_ONE, SBFV_SRC_COLOR, SBFV_ONE_MINUS_SRC_COLOR, SBFV_DST_COLOR, SBFV_ONE_MINUS_DST_COLOR, SBFV_SRC_ALPHA, SBFV_ONE_MINUS_SRC_ALPHA, SBFV_DST_ALPHA, SBFV_ONE_MINUS_DST_ALPHA, SBFV_CONSTANT_COLOR, SBFV_ONE_MINUS_CONSTANT_COLOR, SBFV_CONSTANT_ALPHA, SBFV_ONE_MINUS_CONSTANT_ALPHA, SBFV_SRC_ALPHA_SATURATE, SBFV_SIZE }; enum DestBlendFuncValue //Values for the Destination Blend Function { DBFV_ZERO, DBFV_ONE, DBFV_SRC_COLOR, DBFV_ONE_MINUS_SRC_COLOR, DBFV_DST_COLOR, DBFV_ONE_MINUS_DST_COLOR, DBFV_SRC_ALPHA, DBFV_ONE_MINUS_SRC_ALPHA, DBFV_DST_ALPHA, DBFV_ONE_MINUS_DST_ALPHA, DBFV_CONSTANT_COLOR, DBFV_ONE_MINUS_CONSTANT_COLOR, DBFV_CONSTANT_ALPHA, DBFV_ONE_MINUS_CONSTANT_ALPHA, DBFV_SIZE }; float blendR; //Red value used when blending needs a constant color float blendG; //Green value used when blending needs a constant color float blendB; //Blue value used when blending needs a constant color float blendA; //Alpha value used when blending needs a constant color // DEPTH uint32_t EnableDepthTest:1; //Bit Enables Depth Testing uint32_t EnableDepthWrite:1; //Sets Depth Buffer to Read Only (Depth Values are not written) uint32_t DepthFunc:3; //Specifies Depth Function enum DepthFuncValue //Values for the Depth Function { DFV_NEVER, DFV_LESS_THAN, DFV_EQUAL, DFV_LESS_THAN_EQUAL, DFV_GREATER_THAN, DFV_NOT_EQUAL, DFV_GREATER_THAN_EQUAL, DFV_ALWAYS, DFV_SIZE }; // CULLING uint32_t EnableCullTest:1; //Enable or disable face culling. uint32_t CullMode:2; //Sets up front/back/both culling enum CullModeValue { CMV_FRONT, CMV_BACK, CMV_FRONT_AND_BACK, CMV_SIZE }; uint32_t CullWinding:1; //Sets winding for culling enum CullWindingValue { CWV_CW, CWV_CCW, CWV_SIZE }; // STENCIL uint32_t EnableStencilTest:1; //Bit Enables Stencil Testing uint32_t StencilTestFuncFront:4; //Specifies the stencil comparisons uint32_t StencilTestMaskFront:8; //Mask for front facing stencil post-op uint32_t StencilTestReferenceFront:8; //Reference value for front facing stencil post-op uint32_t StencilTestFuncBack:4; //Specifies the stencil comparisons uint32_t StencilTestMaskBack:8; //Mask for back facing stencil post-op uint32_t StencilTestReferenceBack:8; //Reference value for back facing stencil post-op enum StencilComparisonsValue //Values for the stencil comparisons { SCV_NEVER, SCV_ALWAYS, SCV_LESS, SCV_LEQUAL, SCV_EQUAL, SCV_GEQUAL, SCV_GREATER, SCV_NOTEQUAL, SCV_SIZE }; uint32_t StencilOpStencilFailFront:3; //Specifies the stencil operation when stencil test fails for front-facing polys uint32_t StencilOpStencilPassDepthFailFront:3; //Specifies the stencil operation when stencil test succeeds and depth test fails fails for front-facing polys uint32_t StencilOpStencilPassDepthPassFront:3; //Specifies the stencil operation when stencil and depth tests pass fails for front-facing polys uint32_t StencilOpStencilFailBack:3; //Specifies the stencil operation when stencil test fails for back-facing polys uint32_t StencilOpStencilPassDepthFailBack:3; //Specifies the stencil operation when stencil test succeeds and depth test fails for back-facing polys uint32_t StencilOpStencilPassDepthPassBack:3; //Specifies the stencil operation when stencil and depth tests pass for back-facing polys enum StencilOperationValue //Values for the stencil operations { SOV_KEEP, SOV_ZERO, SOV_REPLACE, SOV_INCR, SOV_INCR_WRAP, SOV_DECR, SOV_DECR_WRAP, SOV_INVERT, SOV_SIZE }; }; class ZRenderer : public ZThread { protected: //Default Constructor ZRenderer() : ZThread("ZRenderer Thread") { } public: //Virtual Destructor virtual ~ZRenderer() { } ////////////////////////// /* Lifecycle Operations */ ////////////////////////// /* virtual public ZRenderer::Init Initializes the Renderer for use as a long running subsystem. After this call, the render thread will be running. @return (bool) @context (all) */ virtual bool Init() = 0; /* virtual public ZRenderer::Shutdown Shuts down the system and stops the render thread. @return (void) @context (all) */ virtual void Shutdown() = 0; /////////////////////////// /* Renderer Data Getters */ /////////////////////////// /* virtual public ZRenderer::GetCapabilities Returns a map describing the capabilities and configuration of this renderer. All renderer implementations must map the following keys: gl { directx, opengl } gl.version { 9.0c, 10.0, 10.1, 11.0, 11.1, 2.1, 3.1, 3.2, 3.3 ... } : version number should always have major.minor format and should be the highest version required gl.shaderlang { hlsl_40, hlsl_30, hlsl, glsl_14, glsl_13, glsl_12, glsl_11, glsl, ... } : shading languages accepted should be listed in a comma separated list in order of preference data_buffer.block_alignment { integer } : alignment requirement for buffer blocks frame_buffer_render_target.max_color_attachments { integer } : maximum number of color buffer attachments Other keys may be supported depending upon the implementation. @return (const ZHashMap&) - map of capabilities @context (all) */ virtual const ZHashMap& GetCapabilities() = 0; /* virtual public ZRenderer::GetRenderPhase Gets the current rendering phase. @return (ZRenderPhase) - current rendering phase @context (all) */ virtual ZRenderPhase GetRenderPhase() = 0; ////////////////////////// /* Logistics Operations */ ////////////////////////// /* virtual public ZRenderer::CreateDataBuffer Creates a data buffer which contains data stored in graphics memory. The data buffer is created but not initialized with values (use FillBuffer or MapBuffer). Keep in mind when allocating a buffer that defines block data that determining the required size to fit all blocks includes taking into account alignment requirements. The alignment requirement for block data for this renderer can be determined through the capabilities map with key 'buffer.block_alignment'. @param _type - the type of buffer to allocate @param _usage - the usage pattern the buffer will follow @param _size - the size (in bytes) to allocate @return (ZDataBuffer) - new data buffer object, NULL if not successful @context (all) */ virtual ZPtr CreateDataBuffer(ZDataBufferType _type, ZDataBufferUsage _usage, size_t _size ) = 0; /* virtual public ZRenderer::CreateDrawParams Creates a draw parameters binding class, which is provided to the draw calls and is used to bind data to shader variables. @param _type - the type of draw parameters binding @return (ZPtr) - new draw parameters object, NULL if not successful @context (all) */ virtual ZPtr CreateDrawParams(ZDrawParamsType _type) = 0; /* virtual public ZRenderer::CreateFrameBufferRenderTarget Function to create a framebuffer-backed render target. @param _width - number of pixels wide to make the frame buffer @param _height - number of pixels tall to make the frame buffer @return (ZPtr) - new frame buffer render target, NULL if not successful @context (all) */ virtual ZPtr CreateFrameBufferRenderTarget(size_t _width, size_t _height) = 0; /* virtual public ZRenderer::CreateRenderBuffer Function to create a render buffer for use in a frame buffer render target. @param _type - the type of render buffer this will be @param _width - number of pixels wide to make the render buffer @param _height - number of pixels tall to make the render buffer @return (ZPtr) - new render buffer, NULL if not successful @context (all) */ virtual ZPtr CreateRenderBuffer(ZRenderBufferType _type, size_t _width, size_t _height) = 0; /* virtual public ZRenderer::CreateSampler Creates a sampler object to use as a view onto a texture. @return (ZPtr) - new sampler object, NULL if unsuccessful @context (all) */ virtual ZPtr CreateSampler() = 0; /* virtual public ZRenderer::CreateShader Function to create a shader object for the renderer. @param _type - type of shader to create: ZST_SOFT : Soft shaders ZST_VERTEX : Vertex shaders ZST_HULL : Hull shaders ZST_DOMAIN : Domain shaders ZST_GEOMETRY: Geometry shaders ZST_FRAGMENT: Fragment (pixel) shaders @return (ZPtr) - the created shader, NULL if not successful @context (all) */ virtual ZPtr CreateShader(ZShaderType _type) = 0; /* virtual public ZRenderer::CreateShaderProgram Function to create a shader program. @return (ZPtr) - new shader program, NULL if not successful @context (all) */ virtual ZPtr CreateShaderProgram() = 0; /* virtual public ZRenderer::CreateTexture Creates a texture object. In the case of cube map textures, the bitmap format describes a single 'side' of the cube map texture. If the bitmap provided has NULL for data, then the texture storage is initialized but no data is copied. @param _type - the type of texture @param _format - the texture internal storage format @param _usage - the usage type of the texture @param _bitmap - bitmap structure containing image format and size, as well as data (can be NULL) @param _generateMipmaps - indicating whether or not we should generate mipmaps @return (ZPtr) - new texture object, NULL if not successful @context (all) */ virtual ZPtr CreateTexture(ZTextureType _type, ZTextureFormat _format, ZTextureUsage _usage, const ZBitmap& _bitmap, bool _generateMipmaps) = 0; /* virtual public ZRenderer::CreateWindowRenderTarget Creates a window render target. @param _window - the window handle (created using libsst-wm) @param _screenIndex - the screen index bound to the window @return (ZPtr) - new window render target, NULL if not successful @context (all) */ virtual ZPtr CreateWindowRenderTarget(SST_Window _window, size_t _screenIndex ) = 0; //////////////////////// /* Frame Data Getters */ //////////////////////// /* virtual public ZRenderer::GetFrameRenderTarget Gets the render target set for the given frame context. @param _frameContext - frame context @return (ZRenderTarget*) - the render target for the given context @context (all) */ virtual ZRenderTarget* GetFrameRenderTarget(ZFrameContext _frameContext) = 0; ////////////////////////// /* Rendering Operations */ ////////////////////////// /* The renderer can maintain a few different states, each of which is described by an enumeration. The various rendering operations affect this state, and thread synchronization calls such as WaitFrameStart and WaitFrameEnd will wait until events are triggered after state changes, as follows. BeginFrame() | SubmitDrawData() | | RenderFrame() | +-------+-------+ | | | | | | ---------------+---+-------+-------+---+-----------------------+--------------- ===============|///////////////////////|///////////////////////|=============== ZRP_IDLE ... =|/ ZRP_FRAME_ACCEPTING /|/ ZRP_FRAME_RENDERING /|= ZRP_IDLE ... ===============|///////////////////////|///////////////////////|=============== | | +-> WaitFrameStart() +-> WaitFrameEnd() ^ | | Frame to Render? | +<----------------------+ Because of the multi threaded nature of ZRenderer, multiple threads can call SubmitDrawData to populate the render lists full of buffered data to draw. A single call should be placed to BeginFrame for each frame context that is desired, and a single call to RenderFrame should occur for each frame context that has been created. It is guaranteed that order will be maintained between calls to RenderFrame, meaning if RenderFrame is called for frame context 0, and then afterwards RenderFrame is called for frame context 1, frame context 0 is guaranteed to render in its entirety before frame context 0 is rendered. */ /* virtual public ZRenderer::BeginFrame Tells the renderer that threads will begin providing draw data for a frame of rendering. The value returned is later used as a frame context for render calls. BeginFrame can be called multiple times, each time returning a new frame context that can be provided for draw calls. BeginFrame should be called once for as many frame contexts there will be before beginning render calls for any of them. Calling BeginFrame after other frames have begun rendering results in undefined behavior. Frame contexts should never be re-used across multiple render cycles - always ask for a new one. @param _canvas - the canvas to render to @return (ZFrameContext) - the frame context that has been created @context (all) */ virtual ZFrameContext BeginFrame(ZPtr _canvas) = 0; /* virtual public ZRenderer::EndFrame TODO @param _frameContext - the frame context we are done submitting draw data to @return (void) @context (all) */ virtual void EndFrame(ZFrameContext _frameContext) = 0; /* virtual public ZRenderer::SubmitDrawData Draws geometry defined in a DataBuffer (Queues them up for rendering). @param _frameContext - the frame context to provide data for @param _shaderProgram - the shader program to draw with @param _shaderParams - the shader parameters binding @param _vertexParams - the vertex parameters binding @param _indexParams - the index parameters binding @param _renderState - the render state to render the geometry with @param _drawGroup - the draw group to render this call with; objects with lower draw group are rendered before objects with higher draw group @return (void) @context (all) */ virtual void SubmitDrawData(ZFrameContext _frameContext, ZPtr _shaderProgram, ZPtr _shaderParams, ZPtr _vertexParams, ZPtr _indexParams, const ZRenderState& _renderState, int _drawGroup = 0 ) = 0; /* virtual public ZRenderer::RenderFrame Renders the frame context. @param _frameContext - the frame context to render @return (void) @context (all) */ virtual void RenderFrame(ZFrameContext _frameContext) = 0; /* virtual public ZRenderer::WaitFrameStart Calling thread waits until RenderFrame is called for the given frame context. @param _frameContext - the frame context to wait for @return (void) @context (all) */ virtual void WaitFrameStart(ZFrameContext _frameContext) = 0; /* virtual public ZRenderer::WaitFrameEnd Calling thread waits until after the render thread has finished rendering a frame. @param _frameContext - the frame context to wait for @return (void) @context (all) */ virtual void WaitFrameEnd(ZFrameContext _frameContext) = 0; }; #endif