2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
11 #ifndef CAFU_MATSYS_RENDERER_HPP_INCLUDED
12 #define CAFU_MATSYS_RENDERER_HPP_INCLUDED
16 template<class T
> class ArrayT
;
18 template<class T
> class Matrix4x4T
;
19 typedef Matrix4x4T
<float> Matrix4x4fT
;
25 class RenderMaterialT
;
29 /// This class provides an interface to a renderer.
30 /// The interface is specified as ABC in order to share the renderer across exe/dll boundaries.
35 enum RenderActionT
{ AMBIENT
, STENCILSHADOW
, LIGHTING
};
38 /// Returns true if this renderer is supported on this system (e.g. required OpenGL extensions are present,
39 /// version of DirectX matches, ...), and returns false otherwise.
40 /// This function must not be called before the underlying video environment (i.e. the OpenGL rendering context) has been initialized.
41 /// No preceeding call to Initialize() is required, and the environment is left as clean as it was found,
42 /// such that no subsequent actions (i.e. calls to this function of *other* renderers) get into trouble.
43 virtual bool IsSupported() const=0;
45 /// Returns true if this renderer supports SHL rendering with compressed (indexed) SHLMaps, false otherwise.
46 virtual bool DoesSupportCompressedSHL() const=0;
48 /// Returns true if this renderer supports SHL rendering with uncompressed SHLMaps (four coefficients per SHLMap), false otherwise.
49 virtual bool DoesSupportUncompressedSHL() const=0;
51 /// Returns a "global" preference number for this renderer.
52 /// This helps the caller code the select the "best" or "most preferred" renderer among many.
53 virtual int GetPreferenceNr() const=0;
55 /// Call this after a successful call to IsSupported() in order to prepare the renderer for use.
56 virtual void Initialize()=0;
58 /// Call this in order to release this renderer.
59 virtual void Release()=0;
61 /// Returns a description of this renderer, e.g. for informing the users about the
62 /// underlying technique (OpenGL, DirectX, ...), the capabilities, or details about the implementation.
63 virtual const char* GetDescription() const=0;
65 // Tells the renderer where the base directory is.
66 // The texture file names of the materials are specified relative to this base dir.
67 // OBSOLETE virtual void SetBaseDir(const std::string& BaseDir_)=0;
69 // This simply returns the previously set base directory name.
70 // OBSOLETE virtual const std::string& GetBaseDir()=0;
72 /// Registers the Material with the renderer, and returns a handle for future reference.
73 /// NULL can be passed for Material, in which case a "null" handle will be returned, which is nonetheless valid
74 /// (but just won't cause any rendering output later).
75 virtual MatSys::RenderMaterialT
* RegisterMaterial(const MaterialT
* Material
) const=0;
77 /// Returns the MaterialT object that was used in RegisterMaterial() to create the RenderMaterial.
78 virtual const MaterialT
* GetMaterialFromRM(MatSys::RenderMaterialT
* RenderMaterial
) const=0;
80 /// Returns the ID of the ambient shader of the RenderMaterial.
81 /// This number can be used by the calling code in order to adjust the draw order (for the AMBIENT render action).
82 /// It is guaranteed that the returned value is reasonably small, that is, not greater than the number of shaders that are employed in this renderer.
83 virtual unsigned long GetAmbientShaderIDFromRM(MatSys::RenderMaterialT
* RenderMaterial
) const=0;
85 /// Returns the ID of the light shader of the RenderMaterial.
86 /// This number can be used by the calling code in order to adjust the draw order (for the LIGHTING render action).
87 /// It is guaranteed that the returned value is reasonably small, that is, not greater than the number of shaders that are employed in this renderer.
88 virtual unsigned long GetLightShaderIDFromRM(MatSys::RenderMaterialT
* RenderMaterial
) const=0;
90 /// Used to free the previously registered (render-)material.
91 /// If RenderMaterial happens to be the currently used material, SetCurrentMaterial(NULL) is automatically called before RenderMaterial is deleted.
92 virtual void FreeMaterial(MatSys::RenderMaterialT
* RenderMaterial
)=0;
94 /// Call this to begin rendering a new frame. This function typically clears the screen and calls other
95 /// implementation specific functions to start a new frame.
96 /// Time is the global time in seconds at which this frame starts.
97 virtual void BeginFrame(double Time
)=0;
99 /// Call this to end the current frame. This function typically calls functions like SwapBuffers() and other
100 /// implementation specific functions to end a frame.
101 virtual void EndFrame()=0;
103 /// This function pre-caches all textures of all materials that have been registered with RegisterMaterial() so far.
104 /// As a result, the delay that otherwise occurs when new textures are first used for rendering is minimized.
105 virtual void PreCache()=0;
107 /// This activates a specific render action, as is required for multi-pass rendering with dynamic lights and stencil shadows.
108 /// Rendering geometry will only consider those parts of the materials that are relevant for their currently set action.
109 virtual void SetCurrentRenderAction(RenderActionT RA
)=0;
111 /// Returns the currently set render action.
112 virtual RenderActionT
GetCurrentRenderAction() const=0;
114 // These methods set/get general-purpose rendering parameters.
116 // The Set... methods are normally called from entity code, before the entity draws itself.
117 // The entity in turn may have the values from its map file description, i.e. from CaWE, where the user set them.
118 // Or an entity script may set them, or of course the engine or MOD (entity) C++ code.
119 // For example, a weapon could set the percentage of its remaining ammo, or anything else that reflects its current state.
121 // These parameters are then available in the cmat material script files, where they can be used in expressions.
122 // This means that the cmat script can for example specify how the color of a material changes depending on some weapons remaining ammo level!
123 // Another example are toggle-switches that can change their color (e.g. red/green) depending on their state.
125 // How does the writer of the cmap script know the meaning of a rendering parameter? Answer: By agreement/arrangement (Vereinbarung/Absprache)!
126 // He knows that he's writing a script for a material that is supposed to be on a certain entity, e.g. a weapon.
127 // The weapon coder then tells him that rendering parameter 7 is set to the remaining relative ammo level, and the cmap writer can then use it.
129 // The cmap script in turn may hand over these *rendering* parameters as *shader* parameters to the shader by using the "shaderExprParam" keyword.
130 // The meaning of the *shader* parameters does ALSO rely on a previous agreement/arrangement, but this time with the shader coder!
131 // That in turn means that the full control over a shader (== ShaderT, e.g. a vertex+fragment program) can be *anywhere* between those who
132 // provide the rendering parameter values and those who write the cmap script! E.g. for a shader parameter ("shaderExprParam ..."),
133 // you can pass-in a constant value, a rendering parameter, or any combination between them that can be expressed by an expression.
135 // Index can currently be between 0 and 31 (inclusive).
136 virtual void SetGenPurposeRenderingParam (unsigned long Index
, float Value
)=0;
137 virtual void SetGenPurposeRenderingParam (unsigned long Index
, int Value
)=0;
138 virtual float GetGenPurposeRenderingParamF(unsigned long Index
) const=0;
139 virtual int GetGenPurposeRenderingParamI(unsigned long Index
) const=0;
141 // Sets/gets the ambient light color that is used from material script rgb expressions.
142 virtual void SetCurrentAmbientLightColor(float r
, float g
, float b
)=0;
143 virtual float* GetCurrentAmbientLightColor()=0; // Can also be used for writing.
144 virtual const float* GetCurrentAmbientLightColor() const=0;
146 // This sets the current light source that is to be used with RenderActions STENCILSHADOW and LIGHTING.
147 // Please note that the Position and Radius must be given in MODEL space!
148 virtual void SetCurrentLightSourcePosition(float x
, float y
, float z
)=0;
149 virtual float* GetCurrentLightSourcePosition()=0; // Can also be used for writing.
150 virtual const float* GetCurrentLightSourcePosition() const=0;
151 virtual void SetCurrentLightSourceRadius(float r
)=0;
152 virtual float& GetCurrentLightSourceRadius()=0; // Can also be used for writing.
153 virtual const float& GetCurrentLightSourceRadius() const=0;
154 virtual void SetCurrentLightSourceDiffuseColor (float r
, float g
, float b
)=0;
155 virtual float* GetCurrentLightSourceDiffuseColor()=0; // Can also be used for writing.
156 virtual const float* GetCurrentLightSourceDiffuseColor() const=0;
157 virtual void SetCurrentLightSourceSpecularColor(float r
, float g
, float b
)=0;
158 virtual float* GetCurrentLightSourceSpecularColor()=0; // Can also be used for writing.
159 virtual const float* GetCurrentLightSourceSpecularColor() const=0;
161 // This sets the current eye position in MODEL space(!) that is used in some lighting shaders (e.g. for specular highlights).
162 virtual void SetCurrentEyePosition(float x
, float y
, float z
)=0;
163 virtual float* GetCurrentEyePosition()=0; // Can also be used for writing.
164 virtual const float* GetCurrentEyePosition() const=0;
166 /// Pushes all lighting parameters onto a stack. The depth of the stack is only limited by available memory.
167 /// The following parameters are covered:
168 /// Light source position and radius, light source diffuse and specular color, and the eye position.
169 /// The ambient light color is currently NOT covered.
170 virtual void PushLightingParameters()=0;
172 /// Pops (restores) the lighting parameters that have previously been pushed onto the stack.
173 /// Nothing happens if the stack is empty.
174 virtual void PopLightingParameters()=0;
177 /******************************************/
178 /*** Interface for output window issues ***/
179 /******************************************/
181 virtual void ClearColor(float r
, float g
, float b
, float a
)=0;
182 virtual void Flush()=0;
185 /***********************************************/
186 /*** Interface for dealing with the matrices ***/
187 /***********************************************/
189 enum MatrixNameT
{ MODEL_TO_WORLD
, WORLD_TO_VIEW
, PROJECTION
/*VIEW_TO_CLIP*/ /*, TEXTURE*/, END_MARKER
};
191 // Methods for getting the native and dependent matrices.
192 virtual const Matrix4x4fT
& GetMatrix(MatrixNameT MN
) const=0;
193 virtual const Matrix4x4fT
& GetMatrixInv(MatrixNameT MN
) const=0;
194 virtual const Matrix4x4fT
& GetMatrixModelView() const=0;
196 // Methods for modifying the matrices.
197 virtual void SetMatrix(MatrixNameT MN
, const Matrix4x4fT
& Matrix
)=0;
198 virtual void Translate(MatrixNameT MN
, float x
, float y
, float z
)=0; // Convenience method, equivalent to SetMatrix(GetMatrix()*T);
199 virtual void Scale (MatrixNameT MN
, float scale
)=0;
200 virtual void RotateX (MatrixNameT MN
, float angle
)=0;
201 virtual void RotateY (MatrixNameT MN
, float angle
)=0;
202 virtual void RotateZ (MatrixNameT MN
, float angle
)=0;
204 // Methods for pushing the matrices on and popping them off a stack.
205 virtual void PushMatrix(MatrixNameT MN
)=0;
206 virtual void PopMatrix (MatrixNameT MN
)=0;
209 // Viewport functions.
210 virtual void SetViewport(int x
, int y
, int width
, int height
)=0;
211 virtual void GetViewport(int viewport
[4])=0;
213 // Selection, Picking, and Feedback.
214 enum PickingRenderModeT
{ RENDER
, SELECT
, FEEDBACK
};
216 virtual void SetSelectionBuffer(unsigned long Size
, unsigned int* Buffer
)=0;
217 virtual unsigned long SetPickingRenderMode(PickingRenderModeT PRM
)=0;
218 virtual void InitNameStack()=0;
219 virtual void LoadName(unsigned long Name
)=0;
220 virtual void PushName(unsigned long Name
)=0;
221 virtual void PopName()=0;
224 /**************************************************************/
225 /*** 1st interface for handing in geometry (immediate mode) ***/
226 /**************************************************************/
228 virtual void SetCurrentMaterial(MatSys::RenderMaterialT
* RenderMaterial
)=0;
229 virtual MatSys::RenderMaterialT
* GetCurrentMaterial() const=0;
230 virtual void LockCurrentMaterial(bool LockCM_
)=0;
232 virtual void SetCurrentLightMap(TextureMapI
* LightMap
)=0;
233 virtual void SetCurrentLightDirMap(TextureMapI
* LightDirMap
)=0;
235 virtual void SetCurrentSHLMaps(const ArrayT
<TextureMapI
*>& SHLMaps
)=0; // Each SHLMap stores 4 coefficients (uncompressed SHL) or there is one index map (compressed SHL).
236 virtual void SetCurrentSHLLookupMap(TextureMapI
* SHLLookupMap
)=0;
238 /* virtual void BeginGeom(type)=0;
239 virtual void VertexAttrib1(...)=0; // e.g. TexCoord
240 virtual void VertexAttrib2(...)=0; // e.g. LMCoord
241 virtual void Vertex(...)=0;
242 virtual void EndGeom()=0; */
244 /* // SOME OLD STUFF - REMOVE!
246 // ?????????????????????????????????????
247 virtual void BeginShadowSilhouetteGeom()=0;
248 virtual void Vertex(...)=0;
249 virtual void EndShadowSilhouetteGeom()=0; */
251 virtual void RenderMesh(const MatSys::MeshT
& Mesh
)=0;
253 /// This ABC does neither have nor need a destructor, because no implementation will ever be deleted via a pointer to a RendererI.
254 /// (The implementations are singletons after all.) See the Singleton pattern and the C++ FAQ 21.05 (the "precise rule") for more information.
255 /// g++ however issues a warning with no such destructor, so I provide one anyway and am safe.
256 virtual ~RendererI() { }
260 /// A global pointer to the current renderer, for common access by all modules that use the MatSys.
261 /// Just set this after you loaded the desired renderer DLL to the pointer returned by the DLLs GetRenderer() function.
262 /// (And NULL it on unloading the DLL.)
263 /// An analogous object exists for the TextureMapManager interface, see TextureMap.hpp.
264 extern RendererI
* Renderer
;