Merge 'remotes/trunk'
[0ad.git] / source / renderer / ModelRenderer.h
blobeff1b63d8425a39d65b8679b7b7cd335035d447e
1 /* Copyright (C) 2015 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
19 * Home to the ModelRenderer class, an abstract base class that manages
20 * a per-frame list of submitted models, as well as simple helper
21 * classes.
24 #ifndef INCLUDED_MODELRENDERER
25 #define INCLUDED_MODELRENDERER
27 #include <memory>
29 #include "graphics/MeshManager.h"
30 #include "graphics/RenderableObject.h"
31 #include "graphics/SColor.h"
32 #include "renderer/VertexArray.h"
34 class RenderModifier;
35 typedef shared_ptr<RenderModifier> RenderModifierPtr;
37 class LitRenderModifier;
38 typedef shared_ptr<LitRenderModifier> LitRenderModifierPtr;
40 class ModelVertexRenderer;
41 typedef shared_ptr<ModelVertexRenderer> ModelVertexRendererPtr;
43 class ModelRenderer;
44 typedef shared_ptr<ModelRenderer> ModelRendererPtr;
46 class CModel;
47 class CShaderDefines;
49 /**
50 * Class CModelRData: Render data that is maintained per CModel.
51 * ModelRenderer implementations may derive from this class to store
52 * per-CModel data.
54 * The main purpose of this class over CRenderData is to track which
55 * ModelRenderer the render data belongs to (via the key that is passed
56 * to the constructor). When a model changes the renderer it uses
57 * (e.g. via run-time modification of the renderpath configuration),
58 * the old ModelRenderer's render data is supposed to be replaced by
59 * the new data.
61 class CModelRData : public CRenderData
63 public:
64 CModelRData(const void* key) : m_Key(key) { }
66 /**
67 * GetKey: Retrieve the key that can be used to identify the
68 * ModelRenderer that created this data.
70 * @return The opaque key that was passed to the constructor.
72 const void* GetKey() const { return m_Key; }
74 private:
75 /// The key for model renderer identification
76 const void* m_Key;
80 /**
81 * Class ModelRenderer: Abstract base class for all model renders.
83 * A ModelRenderer manages a per-frame list of models.
85 * It is supposed to be derived in order to create new ways in which
86 * the per-frame list of models can be managed (for batching, for
87 * transparent rendering, etc.) or potentially for rarely used special
88 * effects.
90 * A typical ModelRenderer will delegate vertex transformation/setup
91 * to a ModelVertexRenderer.
92 * It will delegate fragment stage setup to a RenderModifier.
94 * For most purposes, you should use a BatchModelRenderer with
95 * specialized ModelVertexRenderer and RenderModifier implementations.
97 * It is suggested that a derived class implement the provided generic
98 * Render function, however in some cases it may be necessary to supply
99 * a Render function with a different prototype.
101 * ModelRenderer also contains a number of static helper functions
102 * for building vertex arrays.
104 class ModelRenderer
106 public:
107 ModelRenderer() { }
108 virtual ~ModelRenderer() { }
111 * Initialise global settings.
112 * Should be called before using the class.
114 static void Init();
117 * Submit: Submit a model for rendering this frame.
119 * preconditions : The model must not have been submitted to any
120 * ModelRenderer in this frame. Submit may only be called
121 * after EndFrame and before PrepareModels.
123 * @param model The model that will be added to the list of models
124 * submitted this frame.
126 virtual void Submit(int cullGroup, CModel* model) = 0;
129 * PrepareModels: Calculate renderer data for all previously
130 * submitted models.
132 * Must be called before any rendering calls and after all models
133 * for this frame have been submitted.
135 virtual void PrepareModels() = 0;
138 * EndFrame: Remove all models from the list of submitted
139 * models.
141 virtual void EndFrame() = 0;
144 * Render: Render submitted models, using the given RenderModifier to setup
145 * the fragment stage.
147 * @note It is suggested that derived model renderers implement and use
148 * this Render functions. However, a highly specialized model renderer
149 * may need to "disable" this function and provide its own Render function
150 * with a different prototype.
152 * preconditions : PrepareModels must be called after all models have been
153 * submitted and before calling Render.
155 * @param modifier The RenderModifier that specifies the fragment stage.
156 * @param flags If flags is 0, all submitted models are rendered.
157 * If flags is non-zero, only models that contain flags in their
158 * CModel::GetFlags() are rendered.
160 virtual void Render(const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags) = 0;
163 * CopyPositionAndNormals: Copy unanimated object-space vertices and
164 * normals into the given vertex array.
166 * @param mdef The underlying CModelDef that contains mesh data.
167 * @param Position Points to the array that will receive
168 * position vectors. The array behind the iterator
169 * must be large enough to hold model->GetModelDef()->GetNumVertices()
170 * vertices.
171 * @param Normal Points to the array that will receive normal vectors.
172 * The array behind the iterator must be as large as the Position array.
174 static void CopyPositionAndNormals(
175 const CModelDefPtr& mdef,
176 const VertexArrayIterator<CVector3D>& Position,
177 const VertexArrayIterator<CVector3D>& Normal);
180 * BuildPositionAndNormals: Build animated vertices and normals,
181 * transformed into world space.
183 * @param model The model that is to be transformed.
184 * @param Position Points to the array that will receive
185 * transformed position vectors. The array behind the iterator
186 * must be large enough to hold model->GetModelDef()->GetNumVertices()
187 * vertices. It must allow 16 bytes to be written to each element
188 * (i.e. provide 4 bytes of padding after each CVector3D).
189 * @param Normal Points to the array that will receive transformed
190 * normal vectors. The array behind the iterator must be as large as
191 * the Position array.
193 static void BuildPositionAndNormals(
194 CModel* model,
195 const VertexArrayIterator<CVector3D>& Position,
196 const VertexArrayIterator<CVector3D>& Normal);
199 * BuildColor4ub: Build lighting colors for the given model,
200 * based on previously calculated world space normals.
202 * @param model The model that is to be lit.
203 * @param Normal Array of the model's normal vectors, animated and
204 * transformed into world space.
205 * @param Color Points to the array that will receive the lit vertex color.
206 * The array behind the iterator must large enough to hold
207 * model->GetModelDef()->GetNumVertices() vertices.
209 static void BuildColor4ub(
210 CModel* model,
211 const VertexArrayIterator<CVector3D>& Normal,
212 const VertexArrayIterator<SColor4ub>& Color);
215 * BuildUV: Copy UV coordinates into the given vertex array.
217 * @param mdef The model def.
218 * @param UV Points to the array that will receive UV coordinates.
219 * The array behind the iterator must large enough to hold
220 * mdef->GetNumVertices() vertices.
222 static void BuildUV(
223 const CModelDefPtr& mdef,
224 const VertexArrayIterator<float[2]>& UV,
225 int UVset);
228 * BuildIndices: Create the indices array for the given CModelDef.
230 * @param mdef The model definition object.
231 * @param Indices The index array, must be able to hold
232 * mdef->GetNumFaces()*3 elements.
234 static void BuildIndices(
235 const CModelDefPtr& mdef,
236 const VertexArrayIterator<u16>& Indices);
239 * GenTangents: Generate tangents for the given CModelDef.
241 * @param mdef The model definition object.
242 * @param newVertices An out vector of the unindexed vertices with tangents added.
243 * The new vertices cannot be used with existing face index and must be welded/reindexed.
245 static void GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices, bool gpuSkinning);
249 struct ShaderModelRendererInternals;
252 * Implementation of ModelRenderer that loads the appropriate shaders for
253 * rendering each model, and that batches by shader (and by mesh and texture).
255 * Note that the term "Shader" is somewhat misleading, as this handled
256 * fixed-function rendering using the same API as real GLSL/ARB shaders.
258 class ShaderModelRenderer : public ModelRenderer
260 friend struct ShaderModelRendererInternals;
262 public:
263 ShaderModelRenderer(ModelVertexRendererPtr vertexrender);
264 virtual ~ShaderModelRenderer();
266 // Batching implementations
267 virtual void Submit(int cullGroup, CModel* model);
268 virtual void PrepareModels();
269 virtual void EndFrame();
270 virtual void Render(const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags);
272 private:
273 ShaderModelRendererInternals* m;
276 #endif // INCLUDED_MODELRENDERER