Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
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
31#include "graphics/SColor.h"
34
35class RenderModifier;
36typedef std::shared_ptr<RenderModifier> RenderModifierPtr;
37
39typedef std::shared_ptr<LitRenderModifier> LitRenderModifierPtr;
40
42typedef std::shared_ptr<ModelVertexRenderer> ModelVertexRendererPtr;
43
44class ModelRenderer;
45typedef std::shared_ptr<ModelRenderer> ModelRendererPtr;
46
47class CModel;
48class 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 */
63{
64public:
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
75private:
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{
107public:
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,
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,
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
268public:
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
282private:
285};
286
287#endif // INCLUDED_MODELRENDERER
std::shared_ptr< CModelDef > CModelDefPtr
Definition: MeshManager.h:27
std::shared_ptr< RenderModifier > RenderModifierPtr
Definition: ModelRenderer.h:36
std::shared_ptr< LitRenderModifier > LitRenderModifierPtr
Definition: ModelRenderer.h:39
std::shared_ptr< ModelRenderer > ModelRendererPtr
Definition: ModelRenderer.h:45
std::shared_ptr< ModelVertexRenderer > ModelVertexRendererPtr
Definition: ModelRenderer.h:42
Class CModelRData: Render data that is maintained per CModel.
Definition: ModelRenderer.h:63
CModelRData(const void *key)
Definition: ModelRenderer.h:65
const void * GetKey() const
GetKey: Retrieve the key that can be used to identify the ModelRenderer that created this data.
Definition: ModelRenderer.h:73
const void * m_Key
The key for model renderer identification.
Definition: ModelRenderer.h:77
Definition: Model.h:39
Definition: RenderableObject.h:41
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
Definition: ShaderDefines.h:147
Class LitRenderModifier: Abstract base class for RenderModifiers that apply a shadow map.
Definition: RenderModifiers.h:82
Class ModelRenderer: Abstract base class for all model renders.
Definition: ModelRenderer.h:106
virtual void PrepareModels()=0
PrepareModels: Calculate renderer data for all previously submitted models.
static void GenTangents(const CModelDefPtr &mdef, std::vector< float > &newVertices, bool gpuSkinning)
GenTangents: Generate tangents for the given CModelDef.
Definition: ModelRenderer.cpp:132
static void Init()
Initialise global settings.
Definition: ModelRenderer.cpp:49
virtual void Submit(int cullGroup, CModel *model)=0
Submit: Submit a model for rendering this frame.
static void BuildColor4ub(CModel *model, const VertexArrayIterator< CVector3D > &Normal, const VertexArrayIterator< SColor4ub > &Color)
BuildColor4ub: Build lighting colors for the given model, based on previously calculated world space ...
Definition: ModelRenderer.cpp:109
static void BuildPositionAndNormals(CModel *model, const VertexArrayIterator< CVector3D > &Position, const VertexArrayIterator< CVector3D > &Normal)
BuildPositionAndNormals: Build animated vertices and normals, transformed into world space.
Definition: ModelRenderer.cpp:70
virtual void EndFrame()=0
EndFrame: Remove all models from the list of submitted models.
static void BuildUV(const CModelDefPtr &mdef, const VertexArrayIterator< float[2]> &UV, int UVset)
BuildUV: Copy UV coordinates into the given vertex array.
Definition: ModelRenderer.cpp:140
virtual ~ModelRenderer()
Definition: ModelRenderer.h:109
static void CopyPositionAndNormals(const CModelDefPtr &mdef, const VertexArrayIterator< CVector3D > &Position, const VertexArrayIterator< CVector3D > &Normal)
CopyPositionAndNormals: Copy unanimated object-space vertices and normals into the given vertex array...
Definition: ModelRenderer.cpp:54
virtual void UploadModels(Renderer::Backend::IDeviceCommandContext *deviceCommandContext)=0
Upload renderer data for all previously submitted models to backend.
static void BuildIndices(const CModelDefPtr &mdef, const VertexArrayIterator< u16 > &Indices)
BuildIndices: Create the indices array for the given CModelDef.
Definition: ModelRenderer.cpp:158
virtual void Render(Renderer::Backend::IDeviceCommandContext *deviceCommandContext, const RenderModifierPtr &modifier, const CShaderDefines &context, int cullGroup, int flags)=0
Render: Render submitted models, using the given RenderModifier to setup the fragment stage.
ModelRenderer()
Definition: ModelRenderer.h:108
Class ModelVertexRenderer: Normal ModelRenderer implementations delegate vertex array management and ...
Definition: ModelVertexRenderer.h:44
Class RenderModifier: Some ModelRenderer implementations provide vertex management behaviour but allo...
Definition: RenderModifiers.h:49
Definition: IDeviceCommandContext.h:42
Implementation of ModelRenderer that loads the appropriate shaders for rendering each model,...
Definition: ModelRenderer.h:265
ShaderModelRenderer(ModelVertexRendererPtr vertexrender)
Definition: ModelRenderer.cpp:202
~ShaderModelRenderer() override
Definition: ModelRenderer.cpp:208
void Submit(int cullGroup, CModel *model) override
Submit: Submit a model for rendering this frame.
Definition: ModelRenderer.cpp:214
void Render(Renderer::Backend::IDeviceCommandContext *deviceCommandContext, const RenderModifierPtr &modifier, const CShaderDefines &context, int cullGroup, int flags) override
Render: Render submitted models, using the given RenderModifier to setup the fragment stage.
Definition: ModelRenderer.cpp:359
ShaderModelRendererInternals * m
Definition: ModelRenderer.h:284
void UploadModels(Renderer::Backend::IDeviceCommandContext *deviceCommandContext) override
Upload renderer data for all previously submitted models to backend.
Definition: ModelRenderer.cpp:249
void EndFrame() override
EndFrame: Remove all models from the list of submitted models.
Definition: ModelRenderer.cpp:265
void PrepareModels() override
PrepareModels: Calculate renderer data for all previously submitted models.
Definition: ModelRenderer.cpp:232
Definition: VertexArray.h:31
@ Normal
Definition: CCmpRangeManager.cpp:211
Internal data of the ShaderModelRenderer.
Definition: ModelRenderer.cpp:187
pthread_key_t key
Definition: wpthread.cpp:140