TDME2  1.9.200
LightingShaderBaseImplementation.cpp
Go to the documentation of this file.
2 
3 #include <string>
4 
5 #include <tdme/tdme.h>
8 #include <tdme/engine/Camera.h>
9 #include <tdme/engine/Engine.h>
10 #include <tdme/engine/Timing.h>
11 #include <tdme/math/Matrix4x4.h>
12 #include <tdme/utilities/Console.h>
13 
14 using std::string;
15 using std::to_string;
16 
25 
26 LightingShaderBaseImplementation::LightingShaderBaseImplementation(Renderer* renderer)
27 {
28  this->renderer = renderer;
29  initialized = false;
30 }
31 
33 {
34  return initialized;
35 }
36 
38 {
39  // map inputs to attributes
45  }
46 
47  // link program
48  if (renderer->linkProgram(programId) == false) return;
49 
50  // get uniforms
51  // globals
58 
59  // additional mapping
60  if (renderer->isSpecularMappingAvailable() == true) {
63 
64  }
65  if (renderer->isNormalMappingAvailable() == true) {
68  }
69 
70  // environment mapping
74 
75  // texture matrix
77 
78  // matrices as uniform only if not using instanced rendering
79  if (renderer->isInstancedRenderingAvailable() == false) {
81  if (uniformNormalMatrix == -1) return;
82 
84  if (uniformModelMatrix == -1) return;
85 
88  }
89 
90  // camera, projection matrix
92  if (uniformCameraMatrix == -1) return;
94  if (uniformProjectionMatrix == -1) return;
96 
97  // material
100  uniformMaterialSpecular = renderer->getProgramUniformLocation(programId, "specularMaterial.specular");
101  uniformMaterialEmission = renderer->getProgramUniformLocation(programId, "specularMaterial.emission");
102  uniformMaterialShininess = renderer->getProgramUniformLocation(programId, "specularMaterial.shininess");
103  uniformMaterialReflection = renderer->getProgramUniformLocation(programId, "specularMaterial.reflection");
104 
105  // lights
106  for (auto i = 0; i < Engine::LIGHTS_MAX; i++) {
107  uniformLightEnabled[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) +"].enabled");
108  uniformLightAmbient[i] = renderer->getProgramUniformLocation(programId,"specularLights[" + to_string(i) + "].ambient");
109  uniformLightDiffuse[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].diffuse");
110  uniformLightSpecular[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].specular");
111  uniformLightPosition[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].position");
112  uniformLightSpotDirection[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].spotDirection");
113  uniformLightSpotExponent[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].spotExponent");
114  uniformLightSpotCosCutoff[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].spotCosCutoff");
115  uniformLightConstantAttenuation[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].constantAttenuation");
116  uniformLightLinearAttenuation[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].linearAttenuation");
117  uniformLightQuadraticAttenuation[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].quadraticAttenuation");
118  uniformLightRadius[i] = renderer->getProgramUniformLocation(programId, "specularLights[" + to_string(i) + "].radius");
119  }
120 
122 
123  // use foliage animation
125 
126  //
127  initialized = true;
128 }
129 
131 {
132  renderer->useProgram(contextIdx, programId);
134  // initialize static uniforms
135  if (renderer->isInstancedRenderingAvailable() == true) {
138  }
139  if (uniformDiffuseTextureUnit != -1) {
141  }
144  }
147  }
148 
149  // initialize dynamic uniforms
150  updateEffect(renderer, contextIdx);
151  updateMaterial(renderer, contextIdx);
152  for (auto i = 0; i < Engine::LIGHTS_MAX; i++) {
153  updateLight(renderer, contextIdx, i);
154  }
155 
156  // environment mapping texture unit
159  }
160 
161  // time
162  if (uniformTime != -1) renderer->setProgramUniformFloat(contextIdx, uniformTime, static_cast<float>(engine->getTiming()->getTotalTime()) / 1000.0f);
163 }
164 
166 {
168  renderer->bindTexture(contextIdx, renderer->ID_NONE);
170  renderer->bindTexture(contextIdx, renderer->ID_NONE);
172  renderer->bindTexture(contextIdx, renderer->ID_NONE);
173  renderer->setTextureUnit(contextIdx, 0);
174 }
175 
177 {
178  // skip if using instanced rendering
179  if (renderer->isInstancedRenderingAvailable() == false) {
180  //
183  }
184 }
185 
187 {
188  //
189  array<float, 4> tmpColor4 {{ 0.0f, 0.0f, 0.0f, 0.0f }};
190 
191  auto material = renderer->getSpecularMaterial(contextIdx);
192 
193  // ambient without alpha, as we only use alpha from diffuse color
194  tmpColor4 = material.ambient;
195  tmpColor4[3] = 0.0f;
197  // diffuse
198  if (uniformMaterialDiffuse != -1) renderer->setProgramUniformFloatVec4(contextIdx, uniformMaterialDiffuse, material.diffuse);
199  // specular without alpha, as we only use alpha from diffuse color
200  tmpColor4 = material.specular;
201  tmpColor4[3] = 0.0f;
203  // emission without alpha, as we only use alpha from diffuse color
204  tmpColor4 = material.emission;
205  tmpColor4[3] = 0.0f;
207  // shininess
208  if (uniformMaterialShininess != -1) renderer->setProgramUniformFloat(contextIdx, uniformMaterialShininess, material.shininess);
209  // reflection
210  if (uniformMaterialReflection != -1) renderer->setProgramUniformFloat(contextIdx, uniformMaterialReflection, material.reflection);
212  // diffuse texture masked transparency
214  renderer->setProgramUniformInteger(contextIdx, uniformDiffuseTextureMaskedTransparency, material.diffuseTextureMaskedTransparency);
215  }
216  // diffuse texture masked transparency threshold
218  renderer->setProgramUniformFloat(contextIdx, uniformDiffuseTextureMaskedTransparencyThreshold, material.diffuseTextureMaskedTransparencyThreshold);
219  }
220  // texture atlas size
221  if (uniformTextureAtlasSize != -1) {
222  renderer->setProgramUniformInteger(contextIdx, uniformTextureAtlasSize, material.textureAtlasSize);
223  }
224  // texture atlas pixel dimension
226  renderer->setProgramUniformFloatVec2(contextIdx, uniformTextureAtlasPixelDimension, material.textureAtlasPixelDimension);
227  }
228 }
229 
230 void LightingShaderBaseImplementation::updateLight(Renderer* renderer, int contextIdx, int32_t lightId)
231 {
232  // lights
233  const auto& light = renderer->getLight(contextIdx, lightId);
234  if (uniformLightEnabled[lightId] != -1) renderer->setProgramUniformInteger(contextIdx, uniformLightEnabled[lightId], light.enabled);
235  if (light.enabled == 0) return;
236  if (uniformLightAmbient[lightId] != -1) renderer->setProgramUniformFloatVec4(contextIdx, uniformLightAmbient[lightId], light.ambient);
237  if (uniformLightDiffuse[lightId] != -1) renderer->setProgramUniformFloatVec4(contextIdx, uniformLightDiffuse[lightId], light.diffuse);
238  if (uniformLightSpecular[lightId] != -1) renderer->setProgramUniformFloatVec4(contextIdx, uniformLightSpecular[lightId], light.specular);
239  if (uniformLightPosition[lightId] != -1) renderer->setProgramUniformFloatVec4(contextIdx, uniformLightPosition[lightId], light.position);
240  if (uniformLightSpotDirection[lightId] != -1) renderer->setProgramUniformFloatVec3(contextIdx, uniformLightSpotDirection[lightId], light.spotDirection);
241  if (uniformLightSpotExponent[lightId] != -1) renderer->setProgramUniformFloat(contextIdx, uniformLightSpotExponent[lightId], light.spotExponent);
242  if (uniformLightSpotCosCutoff[lightId] != -1) renderer->setProgramUniformFloat(contextIdx, uniformLightSpotCosCutoff[lightId], light.spotCosCutoff);
243  if (uniformLightConstantAttenuation[lightId] != -1) renderer->setProgramUniformFloat(contextIdx, uniformLightConstantAttenuation[lightId], light.constantAttenuation);
244  if (uniformLightLinearAttenuation[lightId] != -1) renderer->setProgramUniformFloat(contextIdx, uniformLightLinearAttenuation[lightId], light.linearAttenuation);
245  if (uniformLightQuadraticAttenuation[lightId] != -1) renderer->setProgramUniformFloat(contextIdx, uniformLightQuadraticAttenuation[lightId], light.quadraticAttenuation);
246  if (uniformLightRadius[lightId] != -1) renderer->setProgramUniformFloat(contextIdx, uniformLightQuadraticAttenuation[lightId], light.radius);
247 }
248 
250 {
251  // set up camera and projection matrices if using instanced rendering
254  // camera position
255  if (uniformCameraPosition != -1) {
257  }
258  //
259  if (renderer->isInstancedRenderingAvailable() == false) {
260  // matrices
261  Matrix4x4 normalMatrix;
262  // normal matrix
263  normalMatrix.set(renderer->getModelViewMatrix()).invert().transpose();
264  // upload matrices
267  }
268 }
269 
270 // TODO: shader parameters
271 
273  //
275 }
276 
278 }
279 
280 void LightingShaderBaseImplementation::bindTexture(Renderer* renderer, int contextIdx, int32_t textureId)
281 {
282  switch (renderer->getTextureUnit(contextIdx)) {
284  if (uniformDiffuseTextureAvailable != -1) {
285  renderer->setProgramUniformInteger(contextIdx, uniformDiffuseTextureAvailable, textureId == 0 ? 0 : 1);
286  }
287  break;
289  if (renderer->isSpecularMappingAvailable() == false)
290  break;
291 
293  break;
295  if (renderer->isNormalMappingAvailable() == false)
296  break;
297 
298  if (uniformNormalTextureAvailable != -1) renderer->setProgramUniformInteger(contextIdx, uniformNormalTextureAvailable, textureId == 0 ? 0 : 1);
299  break;
301  if (uniformEnvironmentMappingTextureUnit != -1 && textureId != 0) {
304  }
307  }
308  } else {
310  }
311  }
312 }
313 
315 }
316 
318 }
Engine main class.
Definition: Engine.h:131
Timing * getTiming()
Definition: Engine.h:1064
Timing class.
Definition: Timing.h:16
int64_t getTotalTime()
Definition: Timing.h:63
virtual void loadTextures(const string &pathName) override
Load textures.
virtual void updateLight(Renderer *renderer, int contextIdx, int32_t lightId) override
Update light to program.
virtual void updateTextureMatrix(Renderer *renderer, int contextIdx) override
Update texture matrix to program.
virtual void updateMaterial(Renderer *renderer, int contextIdx) override
Update material to program.
virtual void updateMatrices(Renderer *renderer, int contextIdx) override
Update matrices to program.
virtual void bindTexture(Renderer *renderer, int contextIdx, int32_t textureId) override
Bind texture.
virtual void updateEffect(Renderer *renderer, int contextIdx) override
Update effect to program.
virtual void unUseProgram(int contextIdx) override
Unuse lighting program.
virtual void useProgram(Engine *engine, int contextIdx) override
Use lighting program.
virtual void updateShaderParameters(Renderer *renderer, int contextIdx) override=0
Update shader parameters.
virtual void setTextureUnit(int contextIdx, int32_t textureUnit)=0
Sets up texture unit.
array< float, 4 > & getEffectColorAdd(int contextIdx)
Get effect color add.
Definition: Renderer.h:1141
array< float, 3 > & getEnvironmentMappingCubeMapPosition(int contextIdx)
Get environment mapping cube map position.
Definition: Renderer.h:1360
Matrix3x3 & getTextureMatrix(int contextIdx)
Get texture matrix.
Definition: Renderer.h:579
virtual void setProgramUniformFloatVec4(int contextIdx, int32_t uniformId, const array< float, 4 > &data)=0
Set up a float vec4 uniform value.
array< float, 4 > & getEffectColorMul(int contextIdx)
Get effect color mul.
Definition: Renderer.h:1131
virtual void setProgramUniformFloatVec2(int contextIdx, int32_t uniformId, const array< float, 2 > &data)=0
Set up a float vec2 uniform value.
virtual int32_t getTextureUnit(int contextIdx)=0
Get texture unit.
virtual void setProgramAttributeLocation(int32_t programId, int32_t location, const string &name)=0
Bind attribute to a input location.
virtual void setProgramUniformInteger(int contextIdx, int32_t uniformId, int32_t value)=0
Set up a integer uniform value.
virtual bool linkProgram(int32_t programId)=0
Links attached shaders to a program.
virtual void bindTexture(int contextIdx, int32_t textureId)=0
Binds a texture with given id or unbinds when using ID_NONE.
virtual void setProgramUniformFloatMatrix3x3(int contextIdx, int32_t uniformId, const array< float, 9 > &value)=0
Set up a float matrix 3x3 uniform value.
Renderer_SpecularMaterial & getSpecularMaterial(int contextIdx)
Get specular material.
Definition: Renderer.h:1157
void setLighting(int contextIdx, int32_t lighting)
Set current lighting model.
Definition: Renderer.h:504
virtual bool isInstancedRenderingAvailable()=0
Checks if instanced rendering is available.
virtual void setProgramUniformFloatMatrix4x4(int contextIdx, int32_t uniformId, const array< float, 16 > &value)=0
Set up a float matrix 4x4 uniform value.
virtual int32_t getProgramUniformLocation(int32_t programId, const string &name)=0
Returns location of given uniform variable.
virtual void useProgram(int contextIdx, int32_t programId)=0
Use shader program.
virtual void setProgramUniformFloatVec3(int contextIdx, int32_t uniformId, const array< float, 3 > &data)=0
Set up a float vec3 uniform value.
virtual void setProgramUniformFloat(int contextIdx, int32_t uniformId, float value)=0
Set up a float uniform value.
Renderer_Light & getLight(int contextIdx, int32_t lightIdx)
Get light.
Definition: Renderer.h:1114
const array< float, 9 > & getArray() const
Definition: Matrix3x3.h:369
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Definition: Matrix4x4.h:23
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
Matrix4x4 & invert()
Inverts this matrix.
Definition: Matrix4x4.h:479
Matrix4x4 & transpose()
Transposes this matrix.
Definition: Matrix4x4.h:453
const array< float, 16 > & getArray() const
Definition: Matrix4x4.h:611
const array< float, 3 > & getArray() const
Definition: Vector3.h:366
Console class.
Definition: Console.h:29