TDME2  1.9.200
EntityRenderer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <string>
5 #include <tuple>
6 #include <unordered_map>
7 #include <variant>
8 #include <vector>
9 
10 #include <tdme/tdme.h>
11 #include <tdme/engine/fwd-tdme.h>
13 #include <tdme/engine/Color4.h>
19 #include <tdme/engine/Entity.h>
20 #include <tdme/engine/Object.h>
21 #include <tdme/math/fwd-tdme.h>
22 #include <tdme/math/Math.h>
23 #include <tdme/math/Matrix3x3.h>
24 #include <tdme/math/Matrix4x4.h>
25 #include <tdme/math/Vector2.h>
26 #include <tdme/math/Vector3.h>
29 #include <tdme/utilities/Pool.h>
30 
31 using std::get;
32 using std::string;
33 using std::to_string;
34 using std::tuple;
35 using std::unique_ptr;
36 using std::unordered_map;
37 using std::vector;
38 
54 using tdme::math::Math;
61 
62 /**
63  * Rendering class
64  * @author Andreas Drewke
65  */
67  friend class ObjectNodeRenderer;
69  friend class tdme::engine::Engine;
70 
71 private:
72  static constexpr int32_t BATCHRENDERER_MAX { 256 };
73  static constexpr int32_t INSTANCEDRENDERING_OBJECTS_MAX { 16384 };
74 
75  /**
76  * Simple class to determine if a transform matrix is right handed
77  * @author Andreas Drewke
78  */
80  {
81  private:
85 
86  public:
87  /**
88  * Public constructor
89  */
91  }
92 
93  /**
94  * Check if matrix is right handed
95  * @param matrix matrix
96  * @return right handed
97  */
98  inline bool isRightHanded(Matrix4x4& matrix) {
99  // copy into x,y,z axes
100  xAxis.set(matrix[0], matrix[1], matrix[2]);
101  yAxis.set(matrix[4], matrix[5], matrix[6]);
102  zAxis.set(matrix[8], matrix[9], matrix[10]);
103  // check if right handed
104  return Vector3::computeDotProduct(Vector3::computeCrossProduct(xAxis, yAxis), zAxis) < 0.0f;
105  }
106  };
107 
109  vector<int32_t>* vboInstancedRenderingIds;
110  unique_ptr<ByteBuffer> bbEffectColorMuls;
111  unique_ptr<ByteBuffer> bbEffectColorAdds;
112  unique_ptr<ByteBuffer> bbMvMatrices;
114  vector<Object*> objectsToRender;
115  vector<Object*> objectsNotRendered;
116  vector<Object*> objectsByModelToRender;
117  vector<Object*> objectsByModelNotRendered;
118  };
119 
120  Engine* engine { nullptr };
121  Renderer* renderer { nullptr };
122 
123  vector<unique_ptr<BatchRendererTriangles>> trianglesBatchRenderers;
125  vector<TransparentRenderFace*> nodeTransparentRenderFaces;
126  unique_ptr<EntityRenderer_TransparentRenderFacesGroupPool> transparentRenderFacesGroupPool;
127  unique_ptr<TransparentRenderFacesPool> transparentRenderFacesPool;
128 
130  std::size_t operator()(const tuple<Model*, ObjectNode*, int32_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int32_t, const Material*, bool, uint8_t>& k) const {
131  std::hash<uint64_t> hashVal;
132  return hashVal(
133  reinterpret_cast<uint64_t>(get<0>(k)) ^
134  reinterpret_cast<uint64_t>(get<1>(k)) ^
135  static_cast<uint64_t>(get<2>(k)) ^
136  static_cast<uint64_t>(get<3>(k)) ^
137  static_cast<uint64_t>(get<4>(k)) ^
138  static_cast<uint64_t>(get<5>(k)) ^
139  static_cast<uint64_t>(get<6>(k)) ^
140  static_cast<uint64_t>(get<7>(k)) ^
141  static_cast<uint64_t>(get<8>(k)) ^
142  static_cast<uint64_t>(get<9>(k)) ^
143  static_cast<uint64_t>(get<10>(k)) ^
144  reinterpret_cast<uint64_t>(get<11>(k)) ^
145  static_cast<uint64_t>(get<12>(k)) ^
146  static_cast<uint64_t>(get<13>(k))
147  );
148  }
149  };
150  unordered_map<tuple<Model*, ObjectNode*, int32_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int32_t, const Material*, bool, uint8_t>, TransparentRenderFacesGroup*, TransparentRenderFacesGroup_Hash> transparentRenderFacesGroups;
151 
152  unique_ptr<RenderTransparentRenderPointsPool> renderTransparentRenderPointsPool;
153  unique_ptr<BatchRendererPoints> psePointBatchRenderer;
155  vector<ObjectRenderContext> contexts;
156 
157  /**
158  * Renders transparent faces
159  * TODO: guess this should be optimized regarding GL commands
160  * skinned mesh is not supported when using GPU
161  * @param transparentRenderFaces transparent render faces
162  */
163  void prepareTransparentFaces(const vector<TransparentRenderFace*>& transparentRenderFaces);
164 
165  /**
166  * Render transparent faces groups
167  * @param contextIdx context index
168  */
169  void renderTransparentFacesGroups(int contextIdx);
170 
171  /**
172  * Release transparent faces groups
173  */
175 
176  /**
177  * Renders multiple objects of same type(with same model)
178  * @param threadIdx thread idx
179  * @param objects objects of same type/ with same models
180  * @param collectTransparentFaces collect render faces
181  * @param renderTypes render types
182  * @param transparentRenderFacesPool transparent render faces pool
183  */
184  inline void renderObjectsOfSameType(int threadIdx, const vector<Object*>& objects, bool collectTransparentFaces, int32_t renderTypes, TransparentRenderFacesPool* transparentRenderFacesPool) {
185  if (renderer->isInstancedRenderingAvailable() == true) {
186  renderObjectsOfSameTypeInstanced(threadIdx, objects, collectTransparentFaces, renderTypes, transparentRenderFacesPool);
187  } else {
188  renderObjectsOfSameTypeNonInstanced(objects, collectTransparentFaces, renderTypes);
189  }
190  }
191 
192  /**
193  * Renders multiple objects of same type(with same model) not using instancing
194  * @param objects objects of same type/ with same models
195  * @param collectTransparentFaces collect render faces
196  * @param renderTypes render types
197  */
198  void renderObjectsOfSameTypeNonInstanced(const vector<Object*>& objects, bool collectTransparentFaces, int32_t renderTypes);
199 
200  /**
201  * Renders multiple objects of same type(with same model) using instancing
202  * @param threadIdx thread idx
203  * @param objects objects of same type/ with same models
204  * @param collectTransparentFaces collect render faces
205  * @param renderTypes render types
206  */
207  void renderObjectsOfSameTypeInstanced(int threadIdx, const vector<Object*>& objects, bool collectTransparentFaces, int32_t renderTypes, TransparentRenderFacesPool* transparentRenderFacesPool);
208 
209  /**
210  * Checks if a material could change when having multiple objects but same model
211  * @param objectNode object node
212  * @param facesEntityIdx faces entity idx
213  * @param renderTypes render types
214  */
215  inline bool checkMaterialChangable(ObjectNode* objectNode, int32_t facesEntityIdx, int32_t renderTypes) {
217  }
218 
219  /**
220  * Set ups a material for rendering
221  * @param contextIdx context index
222  * @param objectNode object node
223  * @param facesEntityIdx faces entity idx
224  * @param renderTypes render types
225  * @param updateOnly update only, means material has been set up already, only do changes
226  * @param materialKey material key
227  * @param currentMaterialKey current material key or empty
228  */
229  void setupMaterial(int contextIdx, ObjectNode* objectNode, int32_t facesEntityIdx, int32_t renderTypes, bool updateOnly, string& materialKey, const string& currentMaterialKey = string());
230 
231  /**
232  * Clear material for rendering
233  * @param contextIdx context index
234  */
235  void clearMaterial(int contextIdx);
236 
237  /**
238  * Render function
239  * @param threadIdx thread index
240  * @param objects objects
241  * @param visibleObjectsByModels objects by models storage
242  * @param renderTransparentFaces render transparent faces
243  * @param renderTypes render types
244  */
245  inline void renderFunction(
246  int threadIdx,
247  Entity::RenderPass renderPass,
248  const vector<Object*>& objects,
249  array<vector<Object*>, Engine::UNIQUEMODELID_MAX>& objectsByModels,
251  int renderTypes,
253  //
254  if (objects.empty() == true) return;
255  // reset shader
256  renderer->setShader(threadIdx, string());
257  auto effectPass = renderer->getEffectPass();
258  // sort objects by model
259  Vector3 objectCamFromAxis;
260  auto camera = engine->getCamera();
261  auto minObjectUniqueId = Engine::UNIQUEMODELID_MAX;
262  auto maxObjectUniqueId = -1;
263  for (auto objectIdx = 0; objectIdx < objects.size(); objectIdx++) {
264  auto object = objects[objectIdx];
265  if (object->enabledInstances == 0) continue;
266  if (effectPass != 0 && object->excludeFromEffectPass == effectPass) continue;
267  if (object->renderPass != renderPass) continue;
268  auto uniqueModelId = object->getUniqueModelId();
269  if (uniqueModelId != Engine::UNIQUEMODELID_NONE) {
270  auto& objectsByModel = objectsByModels[uniqueModelId];
271  if (objectsByModel.empty() == true) {
272  minObjectUniqueId = Math::min(uniqueModelId, minObjectUniqueId);
273  maxObjectUniqueId = Math::max(uniqueModelId, maxObjectUniqueId);
274  }
275  objectsByModel.push_back(object);
276  }
277  }
278  maxObjectUniqueId++;
279 
280  // render objects
281  auto& context = contexts[threadIdx];
282  for (auto i = minObjectUniqueId; i < maxObjectUniqueId; i++) {
283  auto& objectsByModel = objectsByModels[i];
284  if (objectsByModel.size() == 0) {
285  continue;
286  } else
287  if (objectsByModel.size() > 0) {
288  do {
289  for (auto object: objectsByModel) {
290  if (context.objectsByModelToRender.size() == 0 ||
291  (object->instances == context.objectsByModelToRender[0]->instances &&
292  object->enabledInstances == context.objectsByModelToRender[0]->enabledInstances)) {
293  context.objectsByModelToRender.push_back(object);
294  } else {
295  context.objectsByModelNotRendered.push_back(object);
296  }
297  }
298  renderObjectsOfSameType(threadIdx, context.objectsByModelToRender, renderTransparentFaces, renderTypes, transparentRenderFacesPool);
299  objectsByModel = context.objectsByModelNotRendered;
300  context.objectsByModelToRender.clear();
301  context.objectsByModelNotRendered.clear();
302  } while (objectsByModel.size() > 0);
303  }
304  objectsByModel.clear();
305  }
306  }
307 
308 public:
309  static constexpr int32_t RENDERTYPE_NORMALS { 1 };
310  static constexpr int32_t RENDERTYPE_TEXTUREARRAYS { 2 };
312  static constexpr int32_t RENDERTYPE_EFFECTCOLORS { 8 };
313  static constexpr int32_t RENDERTYPE_MATERIALS { 16 };
314  static constexpr int32_t RENDERTYPE_MATERIALS_DIFFUSEMASKEDTRANSPARENCY { 32 };
315  static constexpr int32_t RENDERTYPE_TEXTURES { 64 };
316  static constexpr int32_t RENDERTYPE_TEXTURES_DIFFUSEMASKEDTRANSPARENCY { 128 };
317  static constexpr int32_t RENDERTYPE_LIGHTS { 256 };
318  static constexpr int32_t RENDERTYPE_SHADOWMAPPING { 512 };
319  static constexpr int32_t RENDERTYPE_RENDERGROUP_OBJECTORIGIN { 1024 };
320  static constexpr int32_t RENDERTYPE_ALL { 2047 };
321 
322  // forbid class copy
324 
325  /**
326  * Public constructor
327  * @param engine engine
328  * @param renderer renderer
329  */
331 
332  /**
333  * Destructor
334  */
335  ~EntityRenderer();
336 
337  /**
338  * Init
339  */
340  void initialize();
341 
342  /**
343  * Dispose
344  */
345  void dispose();
346 
347  /**
348  * @return batch renderer for triangles
349  */
351 
352  /**
353  * Resets the object renderer
354  */
355  void reset();
356 
357  /**
358  * Renders all given objects
359  * @param renderPass render pass
360  * @param objects objects
361  * @param renderTransparentFaces render transparent faces
362  * @param renderTypes render types
363  */
364  void render(Entity::RenderPass renderPass, const vector<Object*>& objects, bool renderTransparentFaces, int32_t renderTypes);
365 
366  /**
367  * Renders collected transparent faces
368  */
369  void renderTransparentFaces();
370 
371  /**
372  * Render points particle system entities
373  * @param renderPass render pass
374  * @param pses points particle system entities
375  */
376  void render(Entity::RenderPass renderPass, const vector<Entity*>& pses);
377 
378  /**
379  * Renders all given lines entities
380  * @param renderPass render pass
381  * @param linesEntities lines entities
382  */
383  void render(Entity::RenderPass renderPass, const vector<Lines*>& linesEntities);
384 
385 };
Color 4 definition class.
Definition: Color4.h:18
Engine main class.
Definition: Engine.h:131
Camera * getCamera()
Definition: Engine.h:1071
static constexpr int UNIQUEMODELID_NONE
Definition: Engine.h:335
static constexpr int UNIQUEMODELID_MAX
Definition: Engine.h:334
Engine entity.
Definition: Entity.h:30
Fog particle system entity to be used with engine class.
Lines entity to be used with engine class.
Definition: Lines.h:38
Object to be used with engine class.
Definition: Object.h:60
Point particle system entity to be used with engine class.
Represents a material.
Definition: Material.h:23
Representation of a 3D model.
Definition: Model.h:35
int32_t getEffectPass()
Get effect pass.
Definition: Renderer.h:461
virtual bool isInstancedRenderingAvailable()=0
Checks if instanced rendering is available.
void setShader(int contextIdx, const string &id)
Set shader.
Definition: Renderer.h:1193
Simple class to determine if a transform matrix is right handed.
bool isRightHanded(Matrix4x4 &matrix)
Check if matrix is right handed.
EntityRenderer(Engine *engine, Renderer *renderer)
Public constructor.
static constexpr int32_t RENDERTYPE_TEXTUREARRAYS_DIFFUSEMASKEDTRANSPARENCY
void prepareTransparentFaces(const vector< TransparentRenderFace * > &transparentRenderFaces)
Renders transparent faces TODO: guess this should be optimized regarding GL commands skinned mesh is ...
bool checkMaterialChangable(ObjectNode *objectNode, int32_t facesEntityIdx, int32_t renderTypes)
Checks if a material could change when having multiple objects but same model.
void render(Entity::RenderPass renderPass, const vector< Object * > &objects, bool renderTransparentFaces, int32_t renderTypes)
Renders all given objects.
unique_ptr< RenderTransparentRenderPointsPool > renderTransparentRenderPointsPool
void renderFunction(int threadIdx, Entity::RenderPass renderPass, const vector< Object * > &objects, array< vector< Object * >, Engine::UNIQUEMODELID_MAX > &objectsByModels, bool renderTransparentFaces, int renderTypes, TransparentRenderFacesPool *transparentRenderFacesPool)
Render function.
unique_ptr< EntityRenderer_TransparentRenderFacesGroupPool > transparentRenderFacesGroupPool
array< vector< Object * >, Engine::UNIQUEMODELID_MAX > objectsByModels
static constexpr int32_t RENDERTYPE_TEXTURES_DIFFUSEMASKEDTRANSPARENCY
void renderObjectsOfSameType(int threadIdx, const vector< Object * > &objects, bool collectTransparentFaces, int32_t renderTypes, TransparentRenderFacesPool *transparentRenderFacesPool)
Renders multiple objects of same type(with same model)
static constexpr int32_t RENDERTYPE_MATERIALS_DIFFUSEMASKEDTRANSPARENCY
unique_ptr< TransparentRenderFacesPool > transparentRenderFacesPool
void setupMaterial(int contextIdx, ObjectNode *objectNode, int32_t facesEntityIdx, int32_t renderTypes, bool updateOnly, string &materialKey, const string &currentMaterialKey=string())
Set ups a material for rendering.
void renderObjectsOfSameTypeInstanced(int threadIdx, const vector< Object * > &objects, bool collectTransparentFaces, int32_t renderTypes, TransparentRenderFacesPool *transparentRenderFacesPool)
Renders multiple objects of same type(with same model) using instancing.
void releaseTransparentFacesGroups()
Release transparent faces groups.
static constexpr int32_t RENDERTYPE_RENDERGROUP_OBJECTORIGIN
unordered_map< tuple< Model *, ObjectNode *, int32_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int32_t, const Material *, bool, uint8_t >, TransparentRenderFacesGroup *, TransparentRenderFacesGroup_Hash > transparentRenderFacesGroups
vector< unique_ptr< BatchRendererTriangles > > trianglesBatchRenderers
unique_ptr< BatchRendererPoints > psePointBatchRenderer
void renderTransparentFacesGroups(int contextIdx)
Render transparent faces groups.
vector< TransparentRenderFace * > nodeTransparentRenderFaces
void clearMaterial(int contextIdx)
Clear material for rendering.
void renderObjectsOfSameTypeNonInstanced(const vector< Object * > &objects, bool collectTransparentFaces, int32_t renderTypes)
Renders multiple objects of same type(with same model) not using instancing.
void renderTransparentFaces()
Renders collected transparent faces.
Object node specifically for rendering.
Definition: ObjectNode.h:41
vector< int32_t > specularMaterialDynamicDiffuseTextureIdsByEntities
Definition: ObjectNode.h:66
Standard math functions.
Definition: Math.h:19
Matrix3x3 class representing matrix3x3 mathematical structure and operations for 2d space.
Definition: Matrix3x3.h:20
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Definition: Matrix4x4.h:23
Vector2 class representing vector2 mathematical structure and operations with x, y components.
Definition: Vector2.h:20
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Definition: Vector3.h:70
Byte buffer class.
Definition: ByteBuffer.h:27
Pool template class.
Definition: Pool.h:20
std::size_t operator()(const tuple< Model *, ObjectNode *, int32_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int32_t, const Material *, bool, uint8_t > &k) const
#define FORBID_CLASS_COPY(CLASS)
Definition: tdme.h:6