Pyrogenesis  trunk
ModelRenderer.h
Go to the documentation of this file.
1 /* Copyright (C) 2022 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 
18 /*
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.
22  */
23 
24 #ifndef INCLUDED_MODELRENDERER
25 #define INCLUDED_MODELRENDERER
26 
27 #include <memory>
28 
29 #include "graphics/MeshManager.h"
31 #include "graphics/SColor.h"
33 #include "renderer/VertexArray.h"
34 
36 typedef std::shared_ptr<RenderModifier> RenderModifierPtr;
37 
39 typedef std::shared_ptr<LitRenderModifier> LitRenderModifierPtr;
40 
42 typedef std::shared_ptr<ModelVertexRenderer> ModelVertexRendererPtr;
43 
45 typedef std::shared_ptr<ModelRenderer> ModelRendererPtr;
46 
47 class CModel;
48 class CShaderDefines;
49 
50 /**
51  * Class CModelRData: Render data that is maintained per CModel.
52  * ModelRenderer implementations may derive from this class to store
53  * per-CModel data.
54  *
55  * The main purpose of this class over CRenderData is to track which
56  * ModelRenderer the render data belongs to (via the key that is passed
57  * to the constructor). When a model changes the renderer it uses
58  * (e.g. via run-time modification of the renderpath configuration),
59  * the old ModelRenderer's render data is supposed to be replaced by
60  * the new data.
61  */
62 class CModelRData : public CRenderData
63 {
64 public:
65  CModelRData(const void* key) : m_Key(key) { }
66 
67  /**
68  * GetKey: Retrieve the key that can be used to identify the
69  * ModelRenderer that created this data.
70  *
71  * @return The opaque key that was passed to the constructor.
72  */
73  const void* GetKey() const { return m_Key; }
74 
75 private:
76  /// The key for model renderer identification
77  const void* m_Key;
78 };
79 
80 
81 /**
82  * Class ModelRenderer: Abstract base class for all model renders.
83  *
84  * A ModelRenderer manages a per-frame list of models.
85  *
86  * It is supposed to be derived in order to create new ways in which
87  * the per-frame list of models can be managed (for batching, for
88  * transparent rendering, etc.) or potentially for rarely used special
89  * effects.
90  *
91  * A typical ModelRenderer will delegate vertex transformation/setup
92  * to a ModelVertexRenderer.
93  * It will delegate fragment stage setup to a RenderModifier.
94  *
95  * For most purposes, you should use a BatchModelRenderer with
96  * specialized ModelVertexRenderer and RenderModifier implementations.
97  *
98  * It is suggested that a derived class implement the provided generic
99  * Render function, however in some cases it may be necessary to supply
100  * a Render function with a different prototype.
101  *
102  * ModelRenderer also contains a number of static helper functions
103  * for building vertex arrays.
104  */
106 {
107 public:
109  virtual ~ModelRenderer() { }
110 
111  /**
112  * Initialise global settings.
113  * Should be called before using the class.
114  */
115  static void Init();
116 
117  /**
118  * Submit: Submit a model for rendering this frame.
119  *
120  * preconditions : The model must not have been submitted to any
121  * ModelRenderer in this frame. Submit may only be called
122  * after EndFrame and before PrepareModels.
123  *
124  * @param model The model that will be added to the list of models
125  * submitted this frame.
126  */
127  virtual void Submit(int cullGroup, CModel* model) = 0;
128 
129  /**
130  * PrepareModels: Calculate renderer data for all previously
131  * submitted models.
132  *
133  * Must be called before any rendering calls and after all models
134  * for this frame have been submitted.
135  */
136  virtual void PrepareModels() = 0;
137 
138  /**
139  * Upload renderer data for all previously submitted models to backend.
140  *
141  * Must be called before any rendering calls and after all models
142  * for this frame have been prepared.
143  */
144  virtual void UploadModels(
145  Renderer::Backend::IDeviceCommandContext* deviceCommandContext) = 0;
146 
147  /**
148  * EndFrame: Remove all models from the list of submitted
149  * models.
150  */
151  virtual void EndFrame() = 0;
152 
153  /**
154  * Render: Render submitted models, using the given RenderModifier to setup
155  * the fragment stage.
156  *
157  * @note It is suggested that derived model renderers implement and use
158  * this Render functions. However, a highly specialized model renderer
159  * may need to "disable" this function and provide its own Render function
160  * with a different prototype.
161  *
162  * preconditions : PrepareModels must be called after all models have been
163  * submitted and before calling Render.
164  *
165  * @param modifier The RenderModifier that specifies the fragment stage.
166  * @param flags If flags is 0, all submitted models are rendered.
167  * If flags is non-zero, only models that contain flags in their
168  * CModel::GetFlags() are rendered.
169  */
170  virtual void Render(
171  Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
172  const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags) = 0;
173 
174  /**
175  * CopyPositionAndNormals: Copy unanimated object-space vertices and
176  * normals into the given vertex array.
177  *
178  * @param mdef The underlying CModelDef that contains mesh data.
179  * @param Position Points to the array that will receive
180  * position vectors. The array behind the iterator
181  * must be large enough to hold model->GetModelDef()->GetNumVertices()
182  * vertices.
183  * @param Normal Points to the array that will receive normal vectors.
184  * The array behind the iterator must be as large as the Position array.
185  */
186  static void CopyPositionAndNormals(
187  const CModelDefPtr& mdef,
188  const VertexArrayIterator<CVector3D>& Position,
190 
191  /**
192  * BuildPositionAndNormals: Build animated vertices and normals,
193  * transformed into world space.
194  *
195  * @param model The model that is to be transformed.
196  * @param Position Points to the array that will receive
197  * transformed position vectors. The array behind the iterator
198  * must be large enough to hold model->GetModelDef()->GetNumVertices()
199  * vertices. It must allow 16 bytes to be written to each element
200  * (i.e. provide 4 bytes of padding after each CVector3D).
201  * @param Normal Points to the array that will receive transformed
202  * normal vectors. The array behind the iterator must be as large as
203  * the Position array.
204  */
205  static void BuildPositionAndNormals(
206  CModel* model,
207  const VertexArrayIterator<CVector3D>& Position,
208  const VertexArrayIterator<CVector3D>& Normal);
209 
210  /**
211  * BuildColor4ub: Build lighting colors for the given model,
212  * based on previously calculated world space normals.
213  *
214  * @param model The model that is to be lit.
215  * @param Normal Array of the model's normal vectors, animated and
216  * transformed into world space.
217  * @param Color Points to the array that will receive the lit vertex color.
218  * The array behind the iterator must large enough to hold
219  * model->GetModelDef()->GetNumVertices() vertices.
220  */
221  static void BuildColor4ub(
222  CModel* model,
223  const VertexArrayIterator<CVector3D>& Normal,
224  const VertexArrayIterator<SColor4ub>& Color);
225 
226  /**
227  * BuildUV: Copy UV coordinates into the given vertex array.
228  *
229  * @param mdef The model def.
230  * @param UV Points to the array that will receive UV coordinates.
231  * The array behind the iterator must large enough to hold
232  * mdef->GetNumVertices() vertices.
233  */
234  static void BuildUV(
235  const CModelDefPtr& mdef,
236  const VertexArrayIterator<float[2]>& UV,
237  int UVset);
238 
239  /**
240  * BuildIndices: Create the indices array for the given CModelDef.
241  *
242  * @param mdef The model definition object.
243  * @param Indices The index array, must be able to hold
244  * mdef->GetNumFaces()*3 elements.
245  */
246  static void BuildIndices(
247  const CModelDefPtr& mdef,
248  const VertexArrayIterator<u16>& Indices);
249 
250  /**
251  * GenTangents: Generate tangents for the given CModelDef.
252  *
253  * @param mdef The model definition object.
254  * @param newVertices An out vector of the unindexed vertices with tangents added.
255  * The new vertices cannot be used with existing face index and must be welded/reindexed.
256  */
257  static void GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices, bool gpuSkinning);
258 };
259 
260 /**
261  * Implementation of ModelRenderer that loads the appropriate shaders for
262  * rendering each model, and that batches by shader technique (and by mesh and texture).
263  */
265 {
267 
268 public:
270  ~ShaderModelRenderer() override;
271 
272  // Batching implementations
273  void Submit(int cullGroup, CModel* model) override;
274  void PrepareModels() override;
275  void UploadModels(
276  Renderer::Backend::IDeviceCommandContext* deviceCommandContext) override;
277  void EndFrame() override;
278  void Render(
279  Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
280  const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags) override;
281 
282 private:
285 };
286 
287 #endif // INCLUDED_MODELRENDERER
std::shared_ptr< CModelDef > CModelDefPtr
Definition: MeshManager.h:27
ShaderModelRendererInternals * m
Definition: ModelRenderer.h:283
const void * GetKey() const
GetKey: Retrieve the key that can be used to identify the ModelRenderer that created this data...
Definition: ModelRenderer.h:73
std::shared_ptr< ModelRenderer > ModelRendererPtr
Definition: ModelRenderer.h:44
Implementation of ModelRenderer that loads the appropriate shaders for rendering each model...
Definition: ModelRenderer.h:264
std::shared_ptr< ModelVertexRenderer > ModelVertexRendererPtr
Definition: ModelRenderer.h:41
Definition: RenderableObject.h:40
Definition: CCmpRangeManager.cpp:211
CModelRData(const void *key)
Definition: ModelRenderer.h:65
Class ModelRenderer: Abstract base class for all model renders.
Definition: ModelRenderer.h:105
pthread_key_t key
Definition: wpthread.cpp:140
virtual ~ModelRenderer()
Definition: ModelRenderer.h:109
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
Definition: ShaderDefines.h:146
const void * m_Key
The key for model renderer identification.
Definition: ModelRenderer.h:77
std::shared_ptr< RenderModifier > RenderModifierPtr
Definition: ModelRenderer.h:35
Class RenderModifier: Some ModelRenderer implementations provide vertex management behaviour but allo...
Definition: RenderModifiers.h:48
ModelRenderer()
Definition: ModelRenderer.h:108
Class CModelRData: Render data that is maintained per CModel.
Definition: ModelRenderer.h:62
Internal data of the ShaderModelRenderer.
Definition: ModelRenderer.cpp:185
std::shared_ptr< LitRenderModifier > LitRenderModifierPtr
Definition: ModelRenderer.h:38
Definition: VertexArray.h:30
Class ModelVertexRenderer: Normal ModelRenderer implementations delegate vertex array management and ...
Definition: ModelVertexRenderer.h:43
Definition: Model.h:46
Definition: IDeviceCommandContext.h:40
bool Init(const CmdLineArgs &args, int flags)
Returns true if successful, false if mods changed and restart_engine was called.
Definition: GameSetup.cpp:525
Class LitRenderModifier: Abstract base class for RenderModifiers that apply a shadow map...
Definition: RenderModifiers.h:81