560 lines
17 KiB
C++
560 lines
17 KiB
C++
/*
|
|
ZRenderer.hpp
|
|
Authors: Patrick Baggett <ptbaggett@762studios.com>,
|
|
Chris Ertel <crertel@762studios.com>,
|
|
James Russell <jcrussell@762studios.com>
|
|
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 <ZRenderer/ZRendererBuild.hpp>
|
|
|
|
#include <SST/SST_WM.h>
|
|
|
|
#include <ZUtil/ZUtil.hpp>
|
|
|
|
#include <ZRenderer/ZDataBuffer.hpp>
|
|
#include <ZRenderer/ZRenderTarget.hpp>
|
|
#include <ZRenderer/ZFramebufferRenderTarget.hpp>
|
|
#include <ZRenderer/ZWindowRenderTarget.hpp>
|
|
#include <ZRenderer/ZTexture.hpp>
|
|
#include <ZRenderer/ZSampler.hpp>
|
|
#include <ZRenderer/ZShader.hpp>
|
|
#include <ZRenderer/ZShaderProgram.hpp>
|
|
#include <ZRenderer/ZShaderParams.hpp>
|
|
#include <ZRenderer/ZVertexParams.hpp>
|
|
#include <ZRenderer/ZIndexParams.hpp>
|
|
|
|
//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<ZString, ZString>&) - map of capabilities
|
|
@context (all)
|
|
*/
|
|
virtual const ZHashMap<ZString, ZString>& 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<ZDataBuffer> 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<ZDrawParams>) - new draw parameters object, NULL if not successful
|
|
@context (all)
|
|
*/
|
|
virtual ZPtr<ZDrawParams> 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<ZFramebufferRenderTarget>) - new frame buffer render target, NULL if not successful
|
|
@context (all)
|
|
*/
|
|
virtual ZPtr<ZFramebufferRenderTarget> 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<ZRenderBuffer>) - new render buffer, NULL if not successful
|
|
@context (all)
|
|
*/
|
|
virtual ZPtr<ZRenderBuffer> 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<ZSampler>) - new sampler object, NULL if unsuccessful
|
|
@context (all)
|
|
*/
|
|
virtual ZPtr<ZSampler> 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<ZShader>) - the created shader, NULL if not successful
|
|
@context (all)
|
|
*/
|
|
virtual ZPtr<ZShader> CreateShader(ZShaderType _type) = 0;
|
|
|
|
/*
|
|
virtual public ZRenderer::CreateShaderProgram
|
|
|
|
Function to create a shader program.
|
|
|
|
@return (ZPtr<ZShaderProgram>) - new shader program, NULL if not successful
|
|
@context (all)
|
|
*/
|
|
virtual ZPtr<ZShaderProgram> 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<ZTexture>) - new texture object, NULL if not successful
|
|
@context (all)
|
|
*/
|
|
virtual ZPtr<ZTexture> 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<ZRenderTarget>) - new window render target, NULL if not successful
|
|
@context (all)
|
|
*/
|
|
virtual ZPtr<ZRenderTarget> 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<ZRenderTarget> _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<ZShaderProgram> _shaderProgram,
|
|
ZPtr<ZShaderParams> _shaderParams,
|
|
ZPtr<ZVertexParams> _vertexParams,
|
|
ZPtr<ZIndexParams> _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
|