TDME2  1.9.200
ShadowMapping.cpp
Go to the documentation of this file.
2 
3 #include <memory>
4 #include <string>
5 #include <vector>
6 
7 #include <tdme/tdme.h>
14 #include <tdme/engine/Engine.h>
15 #include <tdme/engine/Light.h>
16 #include <tdme/math/Matrix4x4.h>
17 #include <tdme/math/Vector3.h>
18 #include <tdme/math/Vector4.h>
19 #include <tdme/utilities/Console.h>
20 
21 using std::make_unique;
22 using std::string;
23 using std::to_string;
24 using std::unique_ptr;
25 using std::vector;
26 
31 using tdme::engine::subsystems::shadowmapping::ShadowMapping_RunState;
40 
41 ShadowMapping::ShadowMapping(Engine* engine, Renderer* renderer, EntityRenderer* entityRenderer)
42 {
43  this->engine = engine;
44  this->renderer = renderer;
45  this->entityRenderer = entityRenderer;
46  shadowMaps.resize(engine->getLightCount());
48  runState = ShadowMapping_RunState::NONE;
49 }
50 
52 }
53 
54 void ShadowMapping::reshape(int32_t width, int32_t height)
55 {
56 }
57 
59 {
60  runState = ShadowMapping_RunState::CREATE;
61  // disable color rendering, we only want to write to the Z-Buffer
62  renderer->setColorMask(false, false, false, false);
63  // render backfaces only, avoid self-shadowing
65  // render to shadow maps
66  for (auto i = 0; i < engine->getLightCount(); i++) {
67  auto light = engine->getLightAt(i);
68  if (light->isEnabled() == true &&
69  light->getSpotDirection().computeLengthSquared() > Math::square(Math::EPSILON)) {
70  // create shadow map for light, if required
71  if (shadowMaps[i] == nullptr) {
72  shadowMaps[i] = make_unique<ShadowMap>(this, Engine::getShadowMapWidth(), Engine::getShadowMapHeight());
73  shadowMaps[i]->initialize();
74  }
75  // render
77  shadowMaps[i]->createShadowMap(light);
79  } else {
80  if (shadowMaps[i] != nullptr) {
81  // dispose shadow map
82  shadowMaps[i]->dispose();
83  shadowMaps[i] = nullptr;
84  }
85  }
86  }
87  // restore disable color rendering
88  renderer->setColorMask(true, true, true, true);
89  // restore render backfaces only
91  //
92  runState = ShadowMapping_RunState::NONE;
93 }
94 
95 void ShadowMapping::renderShadowMaps(const vector<Object*>& visibleObjects)
96 {
97  // only render for objects that receives shadows
98  for (auto object: visibleObjects) {
99  if (object->isReceivesShadows() == false) continue;
100  visibleObjectsReceivingShadows.push_back(object);
101  }
102 
103  //
104  auto contextCount = renderer->isSupportingMultithreadedRendering() == true?Engine::getThreadCount():1;
105  //
106  runState = ShadowMapping_RunState::RENDER;
107  // render using shadow mapping program
108  auto shader = Engine::getShadowMapRenderShader();
109  // do not allow writing to depth buffer
111  // user shader program
112  shader->useProgram(engine);
113  // render each shadow map
115 
116  for (auto i = 0; i < shadowMaps.size(); i++) {
117  // skip on unused shadow mapping
118  if (shadowMaps[i] == nullptr) continue;
119 
120  //
121  auto shadowMap = shadowMaps[i].get();
122  // set light to render
123  shader->setRenderLightId(i);
124 
125  // setup depth textures to contexts
126  for (auto j = 0; j < contextCount; j++) {
127  // use default context
128  auto contextIdx = j;
129  // set up light shader uniforms
130  shadowMap->updateDepthBiasMVPMatrix(contextIdx);
131  //
132  // bind shadow map texture on shadow map texture unit
133  auto textureUnit = renderer->getTextureUnit(contextIdx);
135  shadowMap->bindDepthBufferTexture(contextIdx);
136  // switch back to texture last unit
137  renderer->setTextureUnit(contextIdx, textureUnit);
138  }
139 
140  // only opaque face entities as shadows will not be produced on transparent faces
141  for (auto i = 0; i < Entity::RENDERPASS_MAX; i++) {
142  auto renderPass = static_cast<Entity::RenderPass>(Math::pow(2, i));
144  renderPass,
146  false,
147  EntityRenderer::RENDERTYPE_NORMALS |
148  EntityRenderer::RENDERTYPE_TEXTUREARRAYS_DIFFUSEMASKEDTRANSPARENCY |
149  EntityRenderer::RENDERTYPE_TEXTURES_DIFFUSEMASKEDTRANSPARENCY |
150  EntityRenderer::RENDERTYPE_SHADOWMAPPING
151  );
152  }
153  }
154 
155  //
157 
158  // unuse shader program
159  shader->unUseProgram();
160 
161  // restore depth textures of contexts
162  for (auto j = 0; j < contextCount; j++) {
163  // use default context
164  auto contextIdx = j;
165  auto textureUnit = renderer->getTextureUnit(contextIdx);
167  renderer->bindTexture(contextIdx, renderer->ID_NONE);
168  renderer->setTextureUnit(contextIdx, textureUnit);
169  }
170 
171  // restore render defaults
174 
175  //
177 
178  //
179  runState = ShadowMapping_RunState::NONE;
180 }
181 
183 {
184  // dispose shadow mappings
185  for (auto i = 0; i < shadowMaps.size(); i++) {
186  if (shadowMaps[i] != nullptr) {
187  shadowMaps[i]->dispose();
188  shadowMaps[i] = nullptr;
189  }
190  }
191 }
192 
193 void ShadowMapping::startObjectTransform(int contextIdx, Matrix4x4& transformMatrix)
194 {
195  if (runState != ShadowMapping_RunState::RENDER)
196  return;
197 
198  // retrieve current model view matrix and put it on stack
199  Matrix4x4 tmpMatrix;
201  // set up new model view matrix
202  tmpMatrix.set(depthBiasMVPMatrix);
203  depthBiasMVPMatrix.set(transformMatrix).multiply(tmpMatrix);
204 
205  //
206  updateDepthBiasMVPMatrix(contextIdx);
207 }
208 
210 {
211  if (runState != ShadowMapping_RunState::RENDER)
212  return;
213  // set up new model view matrix
215 }
216 
218 {
219  if (runState == ShadowMapping_RunState::NONE) return;
220 
221  //
222  switch(runState) {
223  case ShadowMapping_RunState::CREATE:
225  break;
226  case ShadowMapping_RunState::RENDER:
228  break;
229  default:
230  Console::println(string("ShadowMapping::updateTextureMatrix(): unsupported run state '" + to_string(runState)));
231  }
232 }
233 
234 void ShadowMapping::updateMatrices(int contextIdx)
235 {
236  if (runState == ShadowMapping_RunState::NONE) return;
237 
238  //
239  switch(runState) {
240  case ShadowMapping_RunState::CREATE:
242  break;
243  case ShadowMapping_RunState::RENDER:
245  break;
246  default:
247  Console::println(string("ShadowMapping::updateMatrices(): unsupported run state '" + to_string(runState)));
248  }
249 }
250 
251 void ShadowMapping::updateMaterial(int contextIdx) {
252  if (runState == ShadowMapping_RunState::NONE)
253  return;
254 
255  //
256  switch(runState) {
257  case ShadowMapping_RunState::CREATE:
259  break;
260  case ShadowMapping_RunState::RENDER:
262  break;
263  default:
264  Console::println(string("ShadowMapping::updateMaterial(): unsupported run state '" + to_string(runState)));
265  }
266 }
267 
268 void ShadowMapping::updateLight(int contextIdx, int32_t lightId) {
269  if (runState == ShadowMapping_RunState::RENDER) {
270  Engine::getShadowMapRenderShader()->updateLight(contextIdx, lightId);
271  }
272 }
273 
274 void ShadowMapping::bindTexture(int contextIdx, int32_t textureId) {
275  if (runState == ShadowMapping_RunState::NONE)
276  return;
277 
278  //
279  switch(runState) {
280  case ShadowMapping_RunState::CREATE:
281  Engine::getShadowMapCreationShader()->bindTexture(contextIdx, textureId);
282  break;
283  case ShadowMapping_RunState::RENDER:
284  Engine::getShadowMapRenderShader()->bindTexture(contextIdx, textureId);
285  break;
286  default:
287  Console::println(string("ShadowMapping::bindTexture(): unsupported run state '" + to_string(runState)));
288  }
289 }
290 
291 void ShadowMapping::updateDepthBiasMVPMatrix(int contextIdx, Matrix4x4& depthBiasMVPMatrix)
292 {
293  if (runState != ShadowMapping_RunState::RENDER)
294  return;
295 
296  // copy matrix
297  this->depthBiasMVPMatrix.set(depthBiasMVPMatrix);
298  // upload
300 }
301 
303 {
304  if (runState != ShadowMapping_RunState::RENDER)
305  return;
306 
307  // upload
309 }
310 
311 void ShadowMapping::setShader(int contextIdx, const string& id) {
312  if (runState == ShadowMapping_RunState::NONE)
313  return;
314 
315  //
316  switch(runState) {
317  case ShadowMapping_RunState::CREATE:
319  break;
320  case ShadowMapping_RunState::RENDER:
321  Engine::getShadowMapRenderShader()->setShader(contextIdx, id);
322  break;
323  default:
324  Console::println(string("ShadowMapping::setShader(): unsupported run state '" + to_string(runState)));
325  }
326 }
327 
329  if (runState == ShadowMapping_RunState::NONE)
330  return;
331 
332  //
333  switch(runState) {
334  case ShadowMapping_RunState::CREATE:
336  break;
337  case ShadowMapping_RunState::RENDER:
339  break;
340  default:
341  Console::println(string("ShadowMapping::updateShaderParameters(): unsupported run state '" + to_string(runState)));
342  }
343 }
344 
Engine main class.
Definition: Engine.h:131
Light * getLightAt(int32_t idx)
Returns light at idx (0 <= idx < 8)
Definition: Engine.h:1143
int32_t getLightCount()
Definition: Engine.h:1134
static ShadowMapRenderShader * getShadowMapRenderShader()
Definition: Engine.h:663
static int32_t getShadowMapWidth()
Definition: Engine.h:730
static int32_t getShadowMapHeight()
Definition: Engine.h:737
static int getThreadCount()
Definition: Engine.h:670
static ShadowMapCreationShader * getShadowMapCreationShader()
Definition: Engine.h:656
static constexpr int RENDERPASS_MAX
Definition: Entity.h:83
Light representation.
Definition: Light.h:33
virtual void setTextureUnit(int contextIdx, int32_t textureUnit)=0
Sets up texture unit.
virtual void enableDepthBufferWriting()=0
Enable depth buffer writing.
virtual void setCullFace(int32_t cullFace)=0
Sets up which face will be culled.
virtual int32_t getTextureUnit(int contextIdx)=0
Get texture unit.
virtual void enableBlending()=0
Enables blending.
virtual void disableBlending()=0
Disables blending.
virtual void setColorMask(bool red, bool green, bool blue, bool alpha)=0
Set up GL rendering colormask.
virtual void bindTexture(int contextIdx, int32_t textureId)=0
Binds a texture with given id or unbinds when using ID_NONE.
virtual void disableDepthBufferWriting()=0
Disable depth buffer writing.
void render(Entity::RenderPass renderPass, const vector< Object * > &objects, bool renderTransparentFaces, int32_t renderTypes)
Renders all given objects.
void useProgram(Engine *engine)
Use shadow map creation shader program.
void setShader(int contextIdx, const string &id)
Set shader.
void updateShaderParameters(int contextIdx)
Update shader parameters.
void bindTexture(int contextIdx, int32_t textureId)
Bind texture.
void unUseProgram()
Unuse shadow map creation shader program.
void updateLight(int contextIdx, int32_t lightId)
Update light.
void setDepthBiasMVPMatrix(int contextIdx, const Matrix4x4 &depthBiasMVPMatrix)
Set up program depth bias mvp matrix.
void setShader(int contextIdx, const string &id)
Set shader.
void updateTextureMatrix(int contextIdx)
Update up texture matrix.
void updateShaderParameters(int contextIdx)
Update shader parameters.
void bindTexture(int contextIdx, int32_t textureId)
Bind texture.
void updateDepthBiasMVPMatrix(int contextIdx, Matrix4x4 &depthBiasMVPMatrix)
Update depth bias mvp matrix with given matrix.
void reshape(int32_t width, int32_t height)
Reshape shadow maps.
void updateLight(int contextIdx, int32_t lightId)
Update light.
void updateMatrices(int contextIdx)
Update matrices.
void setShader(int contextIdx, const string &id)
Set shader.
void updateTextureMatrix(int contextIdx)
Update texture matrix.
void updateShaderParameters(int contextIdx)
Update shader parameters.
vector< unique_ptr< ShadowMap > > shadowMaps
Definition: ShadowMapping.h:46
void startObjectTransform(int contextIdx, Matrix4x4 &transformMatrix)
Start object transform.
void updateMaterial(int contextIdx)
Update material.
void renderShadowMaps(const vector< Object * > &visibleObjects)
Render shadow maps to world.
void bindTexture(int contextIdx, int32_t textureId)
Bind texture.
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Definition: Matrix4x4.h:23
Matrix4x4 & identity()
Creates identity matrix.
Definition: Matrix4x4.h:158
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Definition: Matrix4x4.h:225
Matrix4x4 & set(float r0c0, float r0c1, float r0c2, float r0c3, float r1c0, float r1c1, float r1c2, float r1c3, float r2c0, float r2c1, float r2c2, float r2c3, float r3c0, float r3c1, float r3c2, float r3c3)
Sets this matrix by its components.
Definition: Matrix4x4.h:108
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
Vector4 class representing vector4 mathematical structure and operations with x, y,...
Definition: Vector4.h:22
Console class.
Definition: Console.h:29