SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLGLProgram.cpp
Go to the documentation of this file.
1 /**
2  * \file SLGLProgram.cpp
3  * \date July 2014
4  * \authors Marcus Hudritsch, Martin Christens. See http://www.clockworkcoders.com
5  * \copyright http://opensource.org/licenses/GPL-3.0
6  * \remarks Please use clangformat to format the code. See more code style on
7  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
8 */
9 
10 #include <SLAssetManager.h>
11 #include <SLGLDepthBuffer.h>
12 #include <SLGLProgram.h>
13 #include <SLGLShader.h>
14 #include <SLGLState.h>
15 #include <SLScene.h>
16 #include <SLSkybox.h>
17 
18 //-----------------------------------------------------------------------------
19 // Error Strings defined in SLGLShader.h
20 extern char* aGLSLErrorString[];
21 //-----------------------------------------------------------------------------
22 //! Ctor with a vertex and a fragment shader filename.
23 /*!
24  Constructor for shader programs. Shader programs can be used in multiple
25  materials and can belong therefore to the global assets such as meshes
26  (SLMesh), materials (SLMaterial), textures (SLGLTexture) and shader programs
27  (SLGLProgram).
28  @param am Pointer to a global asset manager. If passed the asset manager is
29  the owner of the instance and will do the deallocation. If a nullptr is passed
30  the creator is responsible for the deallocation.
31  @param vertShaderFile Name of the vertex shader file. If only a filename is
32  passed it will be search on the SLGLProgram::defaultPath.
33  @param fragShaderFile Name of the fragment shader file. If only a filename is
34  passed it will be search on the SLGLProgram::defaultPath.
35  @param geomShaderFile Name of the geometry shader file. If only a filename is
36  passed it will be search on the SLGLProgram::defaultPath.
37  @param programName existing program name to use
38  */
40  const string& vertShaderFile,
41  const string& fragShaderFile,
42  const string& geomShaderFile,
43  const string& programName) : SLObject(programName)
44 {
45  _isLinked = false;
46  _progID = 0;
47 
48  // optional load vertex and/or fragment shaders
49  addShader(new SLGLShader(vertShaderFile, ST_vertex));
50  addShader(new SLGLShader(fragShaderFile, ST_fragment));
51 
52  if (!geomShaderFile.empty())
53  addShader(new SLGLShader(geomShaderFile, ST_geometry));
54 
55  // Add pointer to the global resource vectors for deallocation
56  if (am)
57  am->programs().push_back(this);
58 }
59 //-----------------------------------------------------------------------------
60 /*!
61  * The destructor should be called by the owner of the shader program. If an
62  * asset manager was passed in the constructor it will do it after scene destruction.
63  * The destructor deletes all shader objects (SLGLShader) in the RAM as well
64  * as on the GPU.
65  */
67 {
68  // SL_LOG("~SLGLProgram");
69  for (auto shader : _shaders)
70  {
71  if (_isLinked)
72  {
73  glDetachShader(_progID, shader->_shaderID);
75  }
76 
77  // always delete shader objects before program object
78  delete shader;
79  }
80  _isLinked = false;
81 
82  if (_progID > 0)
83  {
84  glDeleteProgram(_progID);
86  }
87 
88  // delete uniform variables
89  for (auto uf : _uniforms1f)
90  delete uf;
91  for (auto ui : _uniforms1i)
92  delete ui;
93 }
94 //-----------------------------------------------------------------------------
95 //! Delete all Gpu data
97 {
98  if (_isLinked)
99  {
100  for (auto shader : _shaders)
101  {
102  glDetachShader(_progID, shader->_shaderID);
103  GET_GL_ERROR;
104  }
105  _isLinked = false;
106  }
107 
108  if (_progID > 0)
109  {
110  glDeleteProgram(_progID);
111  GET_GL_ERROR;
112  }
113 }
114 //-----------------------------------------------------------------------------
115 //! SLGLProgram::addShader adds a shader to the shader list
117 {
118  assert(shader);
119  _shaders.push_back(shader);
120 }
121 //-----------------------------------------------------------------------------
122 /*! SLGLProgram::initTF() initializes shader for transform feedback.
123  * Does not replace any code from the shader and assumes valid syntax for the
124  * shader used. Used for particle systems
125  */
126 void SLGLProgram::initTF(const char* writeBackAttrib[], int size)
127 {
128  // create program object if it doesn't exist
129  if (!_progID)
130  _progID = glCreateProgram();
131 
132  // if already linked, detach, recreate and compile shaders
133  if (_isLinked)
134  {
135  for (auto* shader : _shaders)
136  {
137  if (_isLinked)
138  {
139  glDetachShader(_progID, shader->_shaderID);
140  GET_GL_ERROR;
141  }
142  }
143  _isLinked = false;
144  }
145 
146  // compile all shader objects
147  SLbool allSuccuessfullyCompiled = true;
148  for (auto* shader : _shaders)
149  {
150  if (!shader->createAndCompile(nullptr))
151  {
152  allSuccuessfullyCompiled = false;
153  break;
154  }
155  GET_GL_ERROR;
156  }
157 
158  // try to compile alternative per vertex lighting shaders
159  if (!allSuccuessfullyCompiled)
160  {
161  // delete all shaders and uniforms that where attached
162  for (auto* sh : _shaders)
163  delete sh;
164  for (auto* uf : _uniforms1f)
165  delete uf;
166  for (auto* ui : _uniforms1i)
167  delete ui;
168 
169  _shaders.clear();
170  _uniforms1f.clear();
171  _uniforms1i.clear();
172  }
173 
174  // attach all shader objects
175  if (allSuccuessfullyCompiled)
176  {
177  for (auto* shader : _shaders)
178  {
179  glAttachShader(_progID, shader->_shaderID);
180  GET_GL_ERROR;
181  }
182  }
183  else
184  {
185  SL_EXIT_MSG("No successfully compiled shaders attached!");
186  }
187 
188  int linked = 0;
189  glTransformFeedbackVaryings(_progID,
190  size,
191  writeBackAttrib,
192  GL_INTERLEAVED_ATTRIBS);
193  glLinkProgram(_progID);
194  GET_GL_ERROR;
195  glGetProgramiv(_progID, GL_LINK_STATUS, &linked);
196  GET_GL_ERROR;
197 
198  if (linked)
199  {
200  _isLinked = true;
201 
202  // if name is empty concatenate shader names
203  if (_name.empty())
204  for (auto* shader : _shaders)
205  _name += shader->name() + ", ";
206  }
207  else
208  {
209  SLchar log[256];
210  glGetProgramInfoLog(_progID, sizeof(log), nullptr, &log[0]);
211  SL_LOG("*** LINKER ERROR ***");
212  SL_LOG("Source files: ");
213  for (auto* shader : _shaders)
214  SL_LOG("%s", shader->name().c_str());
215  SL_LOG("ProgramInfoLog: %s", log);
216  SL_EXIT_MSG("GLSL linker error");
217  }
218 }
219 //-----------------------------------------------------------------------------
220 /*! SLGLProgram::init creates the OpenGL shader program object, compiles all
221 shader objects and attaches them to the shader program. At the end all shaders
222 are linked. If a shader fails to compile a simple texture only shader is
223 compiled that shows an error message in the texture.
224 */
226 {
227  // create program object if it doesn't exist
228  if (!_progID)
229  _progID = glCreateProgram();
230 
231  // if already linked, detach, recreate and compile shaders
232  if (_isLinked)
233  {
234  for (auto* shader : _shaders)
235  {
236  if (_isLinked)
237  {
238  glDetachShader(_progID, shader->_shaderID);
239  GET_GL_ERROR;
240  }
241  }
242  _isLinked = false;
243  }
244 
245  // compile all shader objects
246  SLbool allSuccuessfullyCompiled = true;
247  for (auto* shader : _shaders)
248  {
249  if (!shader->createAndCompile(lights))
250  {
251  allSuccuessfullyCompiled = false;
252  break;
253  }
254  GET_GL_ERROR;
255  }
256 
257  // try to compile alternative per vertex lighting shaders
258  if (!allSuccuessfullyCompiled)
259  {
260  // delete all shaders and uniforms that where attached
261  for (auto* sh : _shaders)
262  delete sh;
263  for (auto* uf : _uniforms1f)
264  delete uf;
265  for (auto* ui : _uniforms1i)
266  delete ui;
267 
268  _shaders.clear();
269  _uniforms1f.clear();
270  _uniforms1i.clear();
271  }
272 
273  // attach all shader objects
274  if (allSuccuessfullyCompiled)
275  {
276  for (auto* shader : _shaders)
277  {
278  glAttachShader(_progID, shader->_shaderID);
279  GET_GL_ERROR;
280  }
281  }
282  else
283  {
284  SL_EXIT_MSG("No successfully compiled shaders attached!");
285  }
286 
287  int linked = 0;
288  glLinkProgram(_progID);
289  GET_GL_ERROR;
290  glGetProgramiv(_progID, GL_LINK_STATUS, &linked);
291  GET_GL_ERROR;
292 
293  if (linked)
294  {
295  _isLinked = true;
296 
297  // if name is empty concatenate shader names
298  if (_name.empty())
299  for (auto* shader : _shaders)
300  _name += shader->name() + ", ";
301  }
302  else
303  {
304  SLchar log[256];
305  glGetProgramInfoLog(_progID, sizeof(log), nullptr, &log[0]);
306  SL_LOG("*** LINKER ERROR ***");
307  SL_LOG("Source files: ");
308  for (auto* shader : _shaders)
309  SL_LOG("%s", shader->name().c_str());
310  SL_LOG("ProgramInfoLog: %s", log);
311  SL_EXIT_MSG("GLSL linker error");
312  }
313 }
314 //-----------------------------------------------------------------------------
315 /*! SLGLProgram::useProgram inits the first time the program and then uses it.
316 Call this initialization if you pass your own custom uniform variables.
317 */
319 {
320  if (_progID == 0 && !_shaders.empty())
321  init(nullptr);
322 
323  if (_isLinked)
324  {
326  GET_GL_ERROR;
327  }
328 }
329 //-----------------------------------------------------------------------------
330 /*! SLGLProgram::beginUse starts using the shader program and transfers the
331 the camera, lights and material parameter as uniform variables. It also passes
332 the custom uniform variables of the _uniform1fList as well as the texture names.
333 */
335  SLMaterial* mat,
336  SLVLight* lights)
337 {
338  if (_progID == 0 && !_shaders.empty())
339  init(lights);
340 
341  if (_isLinked)
342  {
343  SLGLState* stateGL = SLGLState::instance();
344 
345  stateGL->useProgram(_progID);
346 
347  SLint nextTexUnit = 0;
348  if (lights)
349  nextTexUnit = passLightsToUniforms(lights, nextTexUnit);
350 
351  if (mat)
352  mat->passToUniforms(this, nextTexUnit);
353 
354  if (cam)
355  cam->passToUniforms(this);
356 
357  for (auto* uf : _uniforms1f)
358  uniform1f(uf->name(), uf->value());
359 
360  for (auto* ui : _uniforms1i)
361  uniform1i(ui->name(), ui->value());
362 
363  GET_GL_ERROR;
364  }
365 }
366 //-----------------------------------------------------------------------------
368  SLuint nextTexUnit) const
369 {
370  SLGLState* stateGL = SLGLState::instance();
371 
372  // Pass global lighting value
373  uniform1f("u_oneOverGamma", SLLight::oneOverGamma());
374  uniform4fv("u_globalAmbi", 1, (const SLfloat*)&SLLight::globalAmbient);
375 
376  if (!lights->empty())
377  {
378  SLMat4f viewRotMat(stateGL->viewMatrix);
379  viewRotMat.translation(0, 0, 0); // delete translation part, only rotation needed
380 
381  // lighting parameter arrays
382  SLint lightIsOn[SL_MAX_LIGHTS]; //!< flag if light is on
383  SLVec4f lightPosWS[SL_MAX_LIGHTS]; //!< position of light in world space
384  SLVec4f lightPosVS[SL_MAX_LIGHTS]; //!< position of light in view space
385  SLVec4f lightAmbient[SL_MAX_LIGHTS]; //!< ambient light intensity (Ia)
386  SLVec4f lightDiffuse[SL_MAX_LIGHTS]; //!< diffuse light intensity (Id)
387  SLVec4f lightSpecular[SL_MAX_LIGHTS]; //!< specular light intensity (Is)
388  SLVec3f lightSpotDirWS[SL_MAX_LIGHTS]; //!< spot direction in world space
389  SLVec3f lightSpotDirVS[SL_MAX_LIGHTS]; //!< spot direction in view space
390  SLfloat lightSpotCutoff[SL_MAX_LIGHTS]; //!< spot cutoff angle 1-180 degrees
391  SLfloat lightSpotCosCut[SL_MAX_LIGHTS]; //!< cosine of spot cutoff angle
392  SLfloat lightSpotExp[SL_MAX_LIGHTS]; //!< spot exponent
393  SLVec3f lightAtt[SL_MAX_LIGHTS]; //!< att. factor (const,linear,quadratic)
394  SLint lightDoAtt[SL_MAX_LIGHTS]; //!< flag if att. must be calculated
395  SLint lightCreatesShadows[SL_MAX_LIGHTS]; //!< flag if light creates shadows
396  SLint lightDoSmoothShadows[SL_MAX_LIGHTS]; //!< flag if percentage-closer filtering is enabled
397  SLuint lightSmoothShadowLevel[SL_MAX_LIGHTS]; //!< radius of area to sample
398  SLfloat lightShadowMinBias[SL_MAX_LIGHTS]; //!< shadow mapping min. bias at 0 deg.
399  SLfloat lightShadowMaxBias[SL_MAX_LIGHTS]; //!< shadow mapping max. bias at 90 deg.
400  SLint lightUsesCubemap[SL_MAX_LIGHTS]; //!< flag if light has a cube shadow map
401  SLMat4f lightSpace[SL_MAX_LIGHTS * 6]; //!< projection matrix of the light
402  SLGLDepthBuffer* lightShadowMap[SL_MAX_LIGHTS * 6]; //!< pointers to depth-buffers for shadow mapping
403  SLint lightNumCascades[SL_MAX_LIGHTS]; //!< number of cascades for cascaded shadow mapping
404 
405  // Init to defaults
406  for (SLint i = 0; i < SL_MAX_LIGHTS; ++i)
407  {
408  lightIsOn[i] = 0;
409  lightPosWS[i] = SLVec4f(0, 0, 1, 1);
410  lightPosVS[i] = SLVec4f(0, 0, 1, 1);
411  lightAmbient[i] = SLCol4f::BLACK;
412  lightDiffuse[i] = SLCol4f::BLACK;
413  lightSpecular[i] = SLCol4f::BLACK;
414  lightSpotDirWS[i] = SLVec3f(0, 0, -1);
415  lightSpotDirVS[i] = SLVec3f(0, 0, -1);
416  lightSpotCutoff[i] = 180.0f;
417  lightSpotCosCut[i] = cos(Utils::DEG2RAD * lightSpotCutoff[i]);
418  lightSpotExp[i] = 1.0f;
419  lightAtt[i].set(1.0f, 0.0f, 0.0f);
420  lightDoAtt[i] = 0;
421  for (SLint ii = 0; ii < 6; ++ii)
422  {
423  lightSpace[i * 6 + ii] = SLMat4f();
424  lightShadowMap[i * 6 + ii] = nullptr;
425  }
426  lightCreatesShadows[i] = 0;
427  lightDoSmoothShadows[i] = 0;
428  lightSmoothShadowLevel[i] = 1;
429  lightShadowMinBias[i] = 0.001f;
430  lightShadowMaxBias[i] = 0.008f;
431  lightUsesCubemap[i] = 0;
432  lightNumCascades[i] = 0;
433  }
434 
435  // Fill up light property vectors
436  for (SLuint i = 0; i < lights->size(); ++i)
437  {
438  SLLight* light = lights->at(i);
439  SLShadowMap* shadowMap = light->shadowMap();
440 
441  lightIsOn[i] = light->isOn();
442  lightPosWS[i] = light->positionWS();
443  lightPosVS[i] = stateGL->viewMatrix * light->positionWS();
444  lightAmbient[i] = light->ambient();
445  lightDiffuse[i] = light->diffuse();
446  lightSpecular[i] = light->specular();
447  lightSpotDirWS[i] = light->spotDirWS();
448  lightSpotDirVS[i] = stateGL->viewMatrix.mat3() * light->spotDirWS();
449  lightSpotCutoff[i] = light->spotCutOffDEG();
450  lightSpotCosCut[i] = light->spotCosCut();
451  lightSpotExp[i] = light->spotExponent();
452  lightAtt[i] = SLVec3f(light->kc(), light->kl(), light->kq());
453  lightDoAtt[i] = light->isAttenuated();
454  lightCreatesShadows[i] = light->createsShadows();
455  lightDoSmoothShadows[i] = light->doSoftShadows();
456  lightSmoothShadowLevel[i] = light->softShadowLevel();
457  lightShadowMinBias[i] = light->shadowMinBias();
458  lightShadowMaxBias[i] = light->shadowMaxBias();
459  lightUsesCubemap[i] = shadowMap && shadowMap->useCubemap() ? 1 : 0;
460  lightNumCascades[i] = shadowMap ? shadowMap->numCascades() : 0;
461 
462  if (shadowMap)
463  {
464  int cascades = (int)shadowMap->depthBuffers().size();
465 
466  for (SLint ls = 0; ls < 6; ++ls)
467  {
468  lightShadowMap[i * 6 + ls] = cascades > ls ? shadowMap->depthBuffers()[ls] : nullptr;
469  lightSpace[i * 6 + ls] = shadowMap->lightSpace()[ls];
470  }
471  }
472  }
473 
474  // Pass vectors as uniform vectors
475  auto nL = (SLint)lights->size();
476  SLint loc;
477  loc = uniform1iv("u_lightIsOn", nL, (SLint*)&lightIsOn);
478  loc = uniform4fv("u_lightPosWS", nL, (SLfloat*)&lightPosWS);
479  loc = uniform4fv("u_lightPosVS", nL, (SLfloat*)&lightPosVS);
480  loc = uniform4fv("u_lightAmbi", nL, (SLfloat*)&lightAmbient);
481  loc = uniform4fv("u_lightDiff", nL, (SLfloat*)&lightDiffuse);
482  loc = uniform4fv("u_lightSpec", nL, (SLfloat*)&lightSpecular);
483  loc = uniform3fv("u_lightSpotDir", nL, (SLfloat*)&lightSpotDirVS);
484  loc = uniform1fv("u_lightSpotDeg", nL, (SLfloat*)&lightSpotCutoff);
485  loc = uniform1fv("u_lightSpotCos", nL, (SLfloat*)&lightSpotCosCut);
486  loc = uniform1fv("u_lightSpotExp", nL, (SLfloat*)&lightSpotExp);
487  loc = uniform3fv("u_lightAtt", nL, (SLfloat*)&lightAtt);
488  loc = uniform1iv("u_lightDoAtt", nL, (SLint*)&lightDoAtt);
489  loc = uniform1iv("u_lightCreatesShadows", nL, (SLint*)&lightCreatesShadows);
490  loc = uniform1iv("u_lightDoSmoothShadows", nL, (SLint*)&lightDoSmoothShadows);
491  loc = uniform1iv("u_lightSmoothShadowLevel", nL, (SLint*)&lightSmoothShadowLevel);
492  loc = uniform1iv("u_lightUsesCubemap", nL, (SLint*)&lightUsesCubemap);
493  loc = uniform1fv("u_lightShadowMinBias", nL, (SLfloat*)&lightShadowMinBias);
494  loc = uniform1fv("u_lightShadowMaxBias", nL, (SLfloat*)&lightShadowMaxBias);
495  loc = uniform1iv("u_lightNumCascades", nL, (SLint*)&lightNumCascades);
496 
497  for (int i = 0; i < SL_MAX_LIGHTS; ++i)
498  {
499  if (lightCreatesShadows[i])
500  {
501  if (lightNumCascades[i])
502  {
503  SLstring uniformSm;
504 
505  uniformSm = ("u_cascadesFactor_" + std::to_string(i));
506  loc = uniform1f(uniformSm.c_str(), lights->at(i)->shadowMap()->cascadesFactor());
507  uniformSm = ("u_lightSpace_" + std::to_string(i));
508  loc = uniformMatrix4fv(uniformSm.c_str(), lightNumCascades[i], (SLfloat*)(lightSpace + (i * 6)));
509  for (int j = 0; j < lightNumCascades[i]; j++)
510  {
511  uniformSm = "u_cascadedShadowMap_" + std::to_string(i) + "_" + std::to_string(j);
512  if ((loc = getUniformLocation(uniformSm.c_str())) >= 0)
513  {
514  lightShadowMap[i * 6 + j]->bindActive(nextTexUnit);
515  glUniform1i(loc, nextTexUnit);
516  nextTexUnit++;
517  }
518  }
519  }
520  else
521  {
522  SLstring uniformSm;
523 
524  if (lightUsesCubemap[i])
525  {
526  uniformSm = ("u_lightSpace_" + std::to_string(i));
527  loc = uniformMatrix4fv(uniformSm.c_str(), 6, (SLfloat*)(lightSpace + (i * 6)));
528  uniformSm = "u_shadowMapCube_" + std::to_string(i);
529  }
530  else
531  {
532  uniformSm = ("u_lightSpace_" + std::to_string(i));
533  loc = uniformMatrix4fv(uniformSm.c_str(), 1, (SLfloat*)(lightSpace + (i * 6)));
534  uniformSm = "u_shadowMap_" + std::to_string(i);
535  }
536 
537  if ((loc = getUniformLocation(uniformSm.c_str())) >= 0)
538  {
539  lightShadowMap[i * 6]->bindActive(nextTexUnit);
540  glUniform1i(loc, nextTexUnit);
541  nextTexUnit++;
542  }
543  }
544  }
545  }
546 
547  loc = uniform1i("u_lightsDoColoredShadows", (SLint)SLLight::doColoredShadows);
548  }
549  return nextTexUnit;
550 }
551 //-----------------------------------------------------------------------------
552 //! SLGLProgram::endUse stops the shader program
554 {
555  SLGLState* stateGL = SLGLState::instance();
556 
557  // In core profile you must have an active program
558  if (stateGL->glVersionNOf() > 3.0f) return;
559 
560  stateGL->useProgram(0);
561 }
562 //-----------------------------------------------------------------------------
563 //! SLGLProgram::addUniform1f add a uniform variable to the list
565 {
566  _uniforms1f.push_back(u);
567 }
568 //-----------------------------------------------------------------------------
569 //! SLGLProgram::addUniform1f add a uniform variable to the list
571 {
572  _uniforms1i.push_back(u);
573 }
574 //-----------------------------------------------------------------------------
576 {
577  SLint loc = glGetUniformLocation(_progID, name);
578  GET_GL_ERROR;
579  return loc;
580 }
581 //-----------------------------------------------------------------------------
582 //! Passes the float value v0 to the uniform variable "name"
584 {
586  if (loc >= 0) glUniform1f(loc, v0);
587  return loc;
588 }
589 //-----------------------------------------------------------------------------
590 //! Passes the float values v0 & v1 to the uniform variable "name"
592  SLfloat v0,
593  SLfloat v1) const
594 {
596  if (loc >= 0) glUniform2f(loc, v0, v1);
597  return loc;
598 }
599 //-----------------------------------------------------------------------------
600 //! Passes the float values v0, v1 & v2 to the uniform variable "name"
602  SLfloat v0,
603  SLfloat v1,
604  SLfloat v2) const
605 {
607  if (loc >= 0) glUniform3f(loc, v0, v1, v2);
608  return loc;
609 }
610 //-----------------------------------------------------------------------------
611 //! Passes the float values v0,v1,v2 & v3 to the uniform variable "name"
613  SLfloat v0,
614  SLfloat v1,
615  SLfloat v2,
616  SLfloat v3) const
617 {
619  if (loc >= 0) glUniform4f(loc, v0, v1, v2, v3);
620  return loc;
621 }
622 //-----------------------------------------------------------------------------
623 //! Passes the int values v0 to the uniform variable "name"
624 SLint SLGLProgram::uniform1i(const SLchar* name, SLint v0) const
625 {
627  if (loc >= 0) glUniform1i(loc, v0);
628  return loc;
629 }
630 //-----------------------------------------------------------------------------
631 //! Passes the int values v0 & v1 to the uniform variable "name"
633  SLint v0,
634  SLint v1) const
635 {
637  if (loc >= 0) glUniform2i(loc, v0, v1);
638  return loc;
639 }
640 //-----------------------------------------------------------------------------
641 //! Passes the int values v0, v1 & v2 to the uniform variable "name"
643  SLint v0,
644  SLint v1,
645  SLint v2) const
646 {
648  if (loc >= 0) glUniform3i(loc, v0, v1, v2);
649  return loc;
650 }
651 //-----------------------------------------------------------------------------
652 //! Passes the int values v0, v1, v2 & v3 to the uniform variable "name"
654  SLint v0,
655  SLint v1,
656  SLint v2,
657  SLint v3) const
658 {
660  if (loc == -1) return false;
661  glUniform4i(loc, v0, v1, v2, v3);
662  return loc;
663 }
664 //-----------------------------------------------------------------------------
665 //! Passes 1 float value py pointer to the uniform variable "name"
667  SLsizei count,
668  const SLfloat* value) const
669 {
671  if (loc >= 0) glUniform1fv(loc, count, value);
672  return loc;
673 }
674 //-----------------------------------------------------------------------------
675 //! Passes 2 float values py pointer to the uniform variable "name"
677  SLsizei count,
678  const SLfloat* value) const
679 {
681  if (loc >= 0) glUniform2fv(loc, count, value);
682  return loc;
683 }
684 //-----------------------------------------------------------------------------
685 //! Passes 3 float values py pointer to the uniform variable "name"
687  SLsizei count,
688  const SLfloat* value) const
689 {
691  if (loc == -1) return false;
692  glUniform3fv(loc, count, value);
693  return loc;
694 }
695 //-----------------------------------------------------------------------------
696 //! Passes 4 float values py pointer to the uniform variable "name"
698  SLsizei count,
699  const SLfloat* value) const
700 {
702  if (loc >= 0) glUniform4fv(loc, count, value);
703  return loc;
704 }
705 //-----------------------------------------------------------------------------
706 //! Passes 1 int value py pointer to the uniform variable "name"
708  SLsizei count,
709  const SLint* value) const
710 {
712  if (loc >= 0) glUniform1iv(loc, count, value);
713  return loc;
714 }
715 //-----------------------------------------------------------------------------
716 //! Passes 2 int values py pointer to the uniform variable "name"
718  SLsizei count,
719  const SLint* value) const
720 {
722  if (loc >= 0) glUniform2iv(loc, count, value);
723  return loc;
724 }
725 //-----------------------------------------------------------------------------
726 //! Passes 3 int values py pointer to the uniform variable "name"
728  SLsizei count,
729  const SLint* value) const
730 {
732  if (loc >= 0) glUniform3iv(loc, count, value);
733  return loc;
734 }
735 //-----------------------------------------------------------------------------
736 //! Passes 4 int values py pointer to the uniform variable "name"
738  SLsizei count,
739  const SLint* value) const
740 {
742  if (loc >= 0) glUniform4iv(loc, count, value);
743  return loc;
744 }
745 //-----------------------------------------------------------------------------
746 //! Passes a 2x2 float matrix values py pointer to the uniform variable "name"
748  SLsizei count,
749  const SLfloat* value,
750  GLboolean transpose) const
751 {
753  if (loc >= 0) glUniformMatrix2fv(loc, count, transpose, value);
754  return loc;
755 }
756 //-----------------------------------------------------------------------------
757 //! Passes a 2x2 float matrix values py pointer to the uniform at location loc
759  SLsizei count,
760  const SLfloat* value,
761  GLboolean transpose) const
762 {
763  glUniformMatrix2fv(loc, count, transpose, value);
764 }
765 //-----------------------------------------------------------------------------
766 //! Passes a 3x3 float matrix values py pointer to the uniform variable "name"
768  SLsizei count,
769  const SLfloat* value,
770  GLboolean transpose) const
771 {
773  if (loc >= 0) glUniformMatrix3fv(loc, count, transpose, value);
774  return loc;
775 }
776 //-----------------------------------------------------------------------------
777 //! Passes a 3x3 float matrix values py pointer to the uniform at location loc
779  SLsizei count,
780  const SLfloat* value,
781  GLboolean transpose) const
782 {
783  glUniformMatrix3fv(loc, count, transpose, value);
784 }
785 //-----------------------------------------------------------------------------
786 //! Passes a 4x4 float matrix values py pointer to the uniform variable "name"
788  SLsizei count,
789  const SLfloat* value,
790  GLboolean transpose) const
791 {
793  if (loc >= 0) glUniformMatrix4fv(loc, count, transpose, value);
794  return loc;
795 }
796 //-----------------------------------------------------------------------------
797 //! Passes a 4x4 float matrix values py pointer to the uniform at location loc
799  SLsizei count,
800  const SLfloat* value,
801  GLboolean transpose) const
802 {
803  glUniformMatrix4fv(loc, count, transpose, value);
804 }
805 //-----------------------------------------------------------------------------
float SLfloat
Definition: SL.h:173
#define SL_LOG(...)
Definition: SL.h:233
unsigned int SLuint
Definition: SL.h:171
char SLchar
Definition: SL.h:162
bool SLbool
Definition: SL.h:175
#define SL_EXIT_MSG(message)
Definition: SL.h:240
int SLsizei
Definition: SL.h:172
string SLstring
Definition: SL.h:158
int SLint
Definition: SL.h:170
@ ST_vertex
Definition: SLEnums.h:224
@ ST_geometry
Definition: SLEnums.h:226
@ ST_fragment
Definition: SLEnums.h:225
Uses an OpenGL framebuffer object as a depth-buffer.
char * aGLSLErrorString[]
Definition: SLGLShader.cpp:18
Singleton class for global render state.
static const SLint SL_MAX_LIGHTS
max. number of used lights
Definition: SLGLState.h:49
#define GET_GL_ERROR
Definition: SLGLState.h:56
vector< SLLight * > SLVLight
STL vector of light pointers.
Definition: SLLight.h:232
SLMat4< SLfloat > SLMat4f
Definition: SLMat4.h:1581
SLVec3< SLfloat > SLVec3f
Definition: SLVec3.h:318
SLVec4< SLfloat > SLVec4f
Definition: SLVec4.h:235
Toplevel holder of the assets meshes, materials, textures and shaders.
SLVGLProgram & programs()
Active or visible camera node class.
Definition: SLCamera.h:54
void passToUniforms(SLGLProgram *program)
Pass camera parameters to the uniform variables.
Definition: SLCamera.cpp:1688
void bindActive(SLuint texUnit) const
Sets the active texture unit within the shader and binds the texture.
SLint uniformMatrix4fv(const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
Passes a 4x4 float matrix values py pointer to the uniform variable "name".
SLint uniform4fv(const SLchar *name, SLsizei count, const SLfloat *value) const
Passes 4 float values py pointer to the uniform variable "name".
void deleteDataGpu()
Delete all Gpu data.
Definition: SLGLProgram.cpp:96
SLint uniform4f(const SLchar *name, SLfloat v0, SLfloat v1, SLfloat v2, SLfloat v3) const
Passes the float values v0,v1,v2 & v3 to the uniform variable "name".
SLint uniform3fv(const SLchar *name, SLsizei count, const SLfloat *value) const
Passes 3 float values py pointer to the uniform variable "name".
~SLGLProgram() override
Definition: SLGLProgram.cpp:66
SLint uniform3i(const SLchar *name, SLint v0, SLint v1, SLint v2) const
Passes the int values v0, v1 & v2 to the uniform variable "name".
SLint uniform2iv(const SLchar *name, SLsizei count, const SLint *value) const
Passes 2 int values py pointer to the uniform variable "name".
SLint uniform3iv(const SLchar *name, SLsizei count, const SLint *value) const
Passes 3 int values py pointer to the uniform variable "name".
SLint uniformMatrix3fv(const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
Passes a 3x3 float matrix values py pointer to the uniform variable "name".
SLint uniform2fv(const SLchar *name, SLsizei count, const SLfloat *value) const
Passes 2 float values py pointer to the uniform variable "name".
SLint uniform1f(const SLchar *name, SLfloat v0) const
Passes the float value v0 to the uniform variable "name".
void initTF(const char *writeBackAttrib[], int size)
void beginUse(SLCamera *cam, SLMaterial *mat, SLVLight *lights)
void addShader(SLGLShader *shader)
SLGLProgram::addShader adds a shader to the shader list.
SLint uniform2f(const SLchar *name, SLfloat v0, SLfloat v1) const
Passes the float values v0 & v1 to the uniform variable "name".
void addUniform1i(SLGLUniform1i *u)
add int uniform
SLuint _progID
OpenGL shader program object ID.
Definition: SLGLProgram.h:141
SLint uniform1fv(const SLchar *name, SLsizei count, const SLfloat *value) const
Passes 1 float value py pointer to the uniform variable "name".
SLint getUniformLocation(const SLchar *name) const
SLVUniform1f _uniforms1f
Vector of uniform1f variables.
Definition: SLGLProgram.h:144
void addUniform1f(SLGLUniform1f *u)
add float uniform
SLint uniform3f(const SLchar *name, SLfloat v0, SLfloat v1, SLfloat v2) const
Passes the float values v0, v1 & v2 to the uniform variable "name".
SLint uniformMatrix2fv(const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
Passes a 2x2 float matrix values py pointer to the uniform variable "name".
void useProgram()
SLVGLShader _shaders
Vector of all shader objects.
Definition: SLGLProgram.h:143
void init(SLVLight *lights)
SLint passLightsToUniforms(SLVLight *lights, SLuint nextTexUnit) const
SLint uniform1iv(const SLchar *name, SLsizei count, const SLint *value) const
Passes 1 int value py pointer to the uniform variable "name".
SLVUniform1i _uniforms1i
Vector of uniform1i variables.
Definition: SLGLProgram.h:145
SLint uniform1i(const SLchar *name, SLint v0) const
Passes the int values v0 to the uniform variable "name".
SLint uniform2i(const SLchar *name, SLint v0, SLint v1) const
Passes the int values v0 & v1 to the uniform variable "name".
SLint uniform4iv(const SLchar *name, GLsizei count, const SLint *value) const
Passes 4 int values py pointer to the uniform variable "name".
SLbool _isLinked
Flag if program is linked.
Definition: SLGLProgram.h:142
SLGLProgram(SLAssetManager *am, const string &vertShaderFile, const string &fragShaderFile, const string &geomShaderFile="", const string &programName="")
Ctor with a vertex and a fragment shader filename.
Definition: SLGLProgram.cpp:39
void endUse()
SLGLProgram::endUse stops the shader program.
SLint uniform4i(const SLchar *name, SLint v0, SLint v1, SLint v2, SLint v3) const
Passes the int values v0, v1, v2 & v3 to the uniform variable "name".
Encapsulation of an OpenGL shader object.
Definition: SLGLShader.h:25
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
SLMat4f viewMatrix
matrix for the active cameras view transform
Definition: SLGLState.h:91
SLfloat glVersionNOf() const
Definition: SLGLState.h:129
void useProgram(SLuint progID)
Definition: SLGLState.cpp:410
Template for a single GLSL uniform variable.
Definition: SLGLUniform.h:24
Abstract Light class for OpenGL light sources.
Definition: SLLight.h:61
virtual SLVec3f spotDirWS()=0
void createsShadows(SLbool createsShadows)
Definition: SLLight.cpp:98
void shadowMaxBias(SLfloat maxBias)
Definition: SLLight.h:129
SLbool doSoftShadows() const
Definition: SLLight.h:150
void shadowMap(SLShadowMap *shadowMap)
Definition: SLLight.h:125
virtual SLCol4f specular()=0
Returns normally _specularColor * _specularPower.
SLbool isAttenuated() const
Definition: SLLight.h:146
virtual SLVec4f positionWS() const =0
static SLbool doColoredShadows
flag if shadows should be displayed with colors for debugging
Definition: SLLight.h:205
static SLCol4f globalAmbient
static global ambient light intensity
Definition: SLLight.h:202
void kl(SLfloat kl)
Definition: SLLight.cpp:80
SLfloat spotCosCut() const
Definition: SLLight.h:141
static SLfloat oneOverGamma()
Definition: SLLight.h:203
void isOn(const SLbool on)
Definition: SLLight.h:71
SLuint softShadowLevel() const
Definition: SLLight.h:151
void spotCutOffDEG(SLfloat cutOffAngleDEG)
Definition: SLLight.cpp:92
virtual SLCol4f diffuse()=0
Returns normally _diffuseColor * _diffusePower.
virtual SLCol4f ambient()=0
Return normally _ambientColor * _ambientPower.
void kc(SLfloat kc)
Definition: SLLight.cpp:74
void kq(SLfloat kq)
Definition: SLLight.cpp:86
void shadowMinBias(SLfloat minBias)
Definition: SLLight.h:128
void spotExponent(const SLfloat exp)
Definition: SLLight.h:111
SLVec3< T > translation() const
Definition: SLMat4.h:184
SLMat3< T > mat3() const
Definition: SLMat4.h:98
Defines a standard CG material with textures and a shader program.
Definition: SLMaterial.h:56
SLint passToUniforms(SLGLProgram *program, SLint nextTexUnit)
Passes all material parameters as uniforms to the passed shader program.
Definition: SLMaterial.cpp:560
Base class for all other classes.
Definition: SLObject.h:23
SLstring _name
name of an object
Definition: SLObject.h:42
const SLstring & name() const
Definition: SLObject.h:38
Class for standard and cascaded shadow mapping.
Definition: SLShadowMap.h:39
void numCascades(int numCascades)
Definition: SLShadowMap.h:72
SLGLVDepthBuffer depthBuffers()
Definition: SLShadowMap.h:81
void useCubemap(SLbool useCubemap)
Definition: SLShadowMap.h:62
SLMat4f * lightSpace()
Definition: SLShadowMap.h:79
void set(const T X, const T Y, const T Z)
Definition: SLVec3.h:59
static SLVec4 BLACK
Definition: SLVec4.h:213
static const float DEG2RAD
Definition: Utils.h:239
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1103
V3 v3(float x, float y, float z)
Definition: WAIMath.h:38