TDME2  1.9.200
LightingShader.cpp
Go to the documentation of this file.
2 
3 #include <string>
4 #include <unordered_map>
5 #include <vector>
6 
7 #include <tdme/tdme.h>
31 #include <tdme/utilities/Console.h>
33 
34 using std::string;
35 using std::unordered_map;
36 using std::vector;
37 
62 
63 LightingShader::LightingShader(Renderer* renderer): renderer(renderer)
64 {
65  // light scattering
66  if (LightingShaderLightScatteringDefaultImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderLightScatteringDefaultImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
67  if (LightingShaderLightScatteringFoliageImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderLightScatteringFoliageImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
68  if (LightingShaderLightScatteringTreeImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderLightScatteringTreeImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
69  // spec
70  if (LightingShaderDefaultImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderDefaultImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
71  if (LightingShaderFoliageImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderFoliageImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
72  if (LightingShaderSolidImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderSolidImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
73  if (LightingShaderTerrainEditorImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderTerrainEditorImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
74  if (LightingShaderTerrainImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderTerrainImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
75  if (LightingShaderTreeImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderTreeImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
76  if (LightingShaderWaterImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderWaterImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
77  // spec + deferred
78  if (DeferredLightingShaderDefaultImplementation::isSupported(renderer) == true) { auto shaderProgram = new DeferredLightingShaderDefaultImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
79  if (DeferredLightingShaderFoliageImplementation::isSupported(renderer) == true) { auto shaderProgram = new DeferredLightingShaderFoliageImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
80  if (DeferredLightingShaderSolidImplementation::isSupported(renderer) == true) { auto shaderProgram = new DeferredLightingShaderSolidImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
81  if (DeferredLightingShaderTerrainImplementation::isSupported(renderer) == true) { auto shaderProgram = new DeferredLightingShaderTerrainImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
82  if (DeferredLightingShaderTreeImplementation::isSupported(renderer) == true) { auto shaderProgram = new DeferredLightingShaderTreeImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
83  // pbr
84  if (LightingShaderPBRDefaultImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderPBRDefaultImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
85  if (LightingShaderPBRFoliageImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderPBRFoliageImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
86  if (LightingShaderPBRTreeImplementation::isSupported(renderer) == true) { auto shaderProgram = new LightingShaderPBRTreeImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
87  if (DeferredLightingShaderPBRDefaultImplementation::isSupported(renderer) == true) { auto shaderProgram = new DeferredLightingShaderPBRDefaultImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
88  if (DeferredLightingShaderPBRFoliageImplementation::isSupported(renderer) == true) { auto shaderProgram = new DeferredLightingShaderPBRFoliageImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
89  if (DeferredLightingShaderPBRTreeImplementation::isSupported(renderer) == true) { auto shaderProgram = new DeferredLightingShaderPBRTreeImplementation(renderer); shaders[shaderProgram->getId()] = shaderProgram; }
90  auto threadCount = renderer->isSupportingMultithreadedRendering() == true?Engine::getThreadCount():1;
91  contexts.resize(threadCount);
92 }
93 
95  for (const auto& [shaderId, shader]: shaders) {
96  delete shader;
97  }
98 }
99 
101 {
102  bool initialized = true;
103  for (const auto& [shaderId, shader]: shaders) {
104  if (shader->isInitialized() == false) {
105  Console::println("LightingShader::isInitialized(): " + shaderId + ": not initialized!");
106  } else {
107  shader->registerShader();
108  }
109  initialized&= shader->isInitialized();
110  }
111  return initialized;
112 }
113 
115 {
116  for (const auto& [shaderId, shader]: shaders) {
117  shader->initialize();
118  }
119 }
120 
122 {
123  for (const auto& [shaderId, shader]: shaders) {
124  shader->unloadTextures();
125  }
126 }
127 
129 {
130  running = true;
131  this->engine = engine;
132 }
133 
135 {
136  running = false;
137  auto i = 0;
138  for (auto& lightingShaderContext: contexts) {
139  if (lightingShaderContext.implementation != nullptr) lightingShaderContext.implementation->unUseProgram(i);
140  lightingShaderContext.implementation = nullptr;
141  i++;
142  }
143  engine = nullptr;
144 }
145 
146 void LightingShader::updateEffect(int contextIdx)
147 {
148  auto& lightingShaderContext = contexts[contextIdx];
149  if (lightingShaderContext.implementation == nullptr) return;
150  lightingShaderContext.implementation->updateEffect(renderer, contextIdx);
151 }
152 
153 void LightingShader::updateMaterial(int contextIdx)
154 {
155  auto& lightingShaderContext = contexts[contextIdx];
156  if (lightingShaderContext.implementation == nullptr) return;
157  lightingShaderContext.implementation->updateMaterial(renderer, contextIdx);
158 }
159 
160 void LightingShader::updateLight(int contextIdx, int32_t lightId)
161 {
162  auto& lightingShaderContext = contexts[contextIdx];
163  if (lightingShaderContext.implementation == nullptr) return;
164  lightingShaderContext.implementation->updateLight(renderer, contextIdx, lightId);
165 }
166 
167 void LightingShader::updateMatrices(int contextIdx)
168 {
169  auto& lightingShaderContext = contexts[contextIdx];
170  if (lightingShaderContext.implementation == nullptr) return;
171  lightingShaderContext.implementation->updateMatrices(renderer, contextIdx);
172 }
173 
175  auto& lightingShaderContext = contexts[contextIdx];
176  if (lightingShaderContext.implementation == nullptr) return;
177  lightingShaderContext.implementation->updateTextureMatrix(renderer, contextIdx);
178 }
179 
180 void LightingShader::setShader(int contextIdx, const string& id) {
181  if (running == false) return;
182  auto shaderId = id;
183  // TODO: find a better solution to remove pbr from lightscattering pass
184  if ((renderer->isPBRAvailable() == false || renderer->getShaderPrefix() == "ls_") &&
185  StringTools::startsWith(id, "pbr-") == true) {
186  shaderId = StringTools::substring(id, 4, id.size());
187  }
188  auto& lightingShaderContext = contexts[contextIdx];
189  auto currentImplementation = lightingShaderContext.implementation;
190  auto shaderIt = shaders.find(renderer->getShaderPrefix() + shaderId);
191  if (shaderIt == shaders.end()) shaderIt = shaders.find(renderer->getShaderPrefix() + "default");
192  if (shaderIt == shaders.end()) shaderIt = shaders.find("default");
193  auto nextImplementation = shaderIt->second;
194  if (currentImplementation != nextImplementation) {
195  if (currentImplementation != nullptr) currentImplementation->unUseProgram(contextIdx);
196  lightingShaderContext.implementation = nextImplementation;
197  lightingShaderContext.implementation->useProgram(engine, contextIdx);
198  }
199 }
200 
202  auto& lightingShaderContext = contexts[contextIdx];
203  if (lightingShaderContext.implementation == nullptr) return;
204  lightingShaderContext.implementation->updateShaderParameters(renderer, contextIdx);
205 }
206 
207 void LightingShader::bindTexture(int contextIdx, int32_t textureId)
208 {
209  auto& lightingShaderContext = contexts[contextIdx];
210  if (lightingShaderContext.implementation == nullptr) return;
211  lightingShaderContext.implementation->bindTexture(renderer, contextIdx, textureId);
212 }
213 
214 
215 void LightingShader::loadTextures(const string& pathName) {
216  for (const auto& [shaderId, shader]: shaders) {
217  shader->unloadTextures();
218  shader->loadTextures(pathName);
219  }
220 }
Engine main class.
Definition: Engine.h:131
static int getThreadCount()
Definition: Engine.h:670
Interface to lighting shader program.
void updateLight(int contextIdx, int32_t lightId)
Update light to program.
void updateMatrices(int contextIdx)
Update matrices to program.
void updateEffect(int contextIdx)
Update effect to program.
void useProgram(Engine *engine)
Use lighting program.
void setShader(int contextIdx, const string &id)
Set shader.
void updateTextureMatrix(int contextIdx)
Update texture matrix to program.
void updateShaderParameters(int contextIdx)
Update shader parameters.
void updateMaterial(int contextIdx)
Update material to program.
void bindTexture(int contextIdx, int32_t textureId)
Bind texture.
void loadTextures(const string &pathName)
Load textures.
unordered_map< string, LightingShaderImplementation * > shaders
const string & getShaderPrefix()
Get shader prefix.
Definition: Renderer.h:477
Console class.
Definition: Console.h:29
String tools class.
Definition: StringTools.h:22