NGL  6.5
The NCCA Graphics Library
ShaderLib.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 Jon Macey
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include <cstdlib>
18 #include <fstream>
19 #include <memory>
20 #include <algorithm>
21 #include "ShaderLib.h"
22 #include "TextShaders.h"
23 #include "ColourShaders.h"
24 #include "DiffuseShaders.h"
25 #include "ToonShaders.h"
26 #include "rapidjson/document.h"
27 
28 
29 //----------------------------------------------------------------------------------------------------------------------
32 //----------------------------------------------------------------------------------------------------------------------
33 
34 namespace ngl
35 {
36 
37 
38 //----------------------------------------------------------------------------------------------------------------------
39 void ShaderLib::setShaderParamFromMat4(const std::string &_paramName, Mat4 _p1 ) noexcept
40 {
41  (*this)[m_currentShader]->setUniformMatrix4fv(_paramName.c_str(),1,GL_FALSE,_p1.openGL());
42 }
43 
44 //----------------------------------------------------------------------------------------------------------------------
45 void ShaderLib::setRegisteredUniformFromMat4(const std::string &_registeredUniformName, Mat4 _p1 ) noexcept
46 {
47  (*this)[m_currentShader]->setRegisteredUniformMatrix4fv(_registeredUniformName,1,GL_FALSE,_p1.openGL());
48 }
49 
50 //----------------------------------------------------------------------------------------------------------------------
51 void ShaderLib::setShaderParamFromMat3(const std::string &_paramName, Mat3 _p1 ) noexcept
52 {
53  (*this)[m_currentShader]->setUniformMatrix3fv(_paramName.c_str(),1,GL_FALSE,_p1.openGL());
54 }
55 
56 //----------------------------------------------------------------------------------------------------------------------
57 void ShaderLib::setRegisteredUniformFromMat3( const std::string &_paramName, Mat3 _p1 ) noexcept
58 {
59  (*this)[m_currentShader]->setRegisteredUniformMatrix3fv(_paramName,1,GL_FALSE,_p1.openGL());
60 }
61 //----------------------------------------------------------------------------------------------------------------------
62 void ShaderLib::setShaderParamFromVec4(const std::string &_paramName, Vec4 _p1 ) noexcept
63 {
64 
65  (*this)[m_currentShader]->setUniform4fv(_paramName.c_str(),1,_p1.openGL());
66 
67 }
68 //----------------------------------------------------------------------------------------------------------------------
69 void ShaderLib::setRegisteredUniformVec4( const std::string &_paramName, Vec4 _p1 ) noexcept
70 {
71  (*this)[m_currentShader]->setRegisteredUniform4f(_paramName,_p1.m_x,_p1.m_y,_p1.m_z,_p1.m_w);
72 }
73 
74 //----------------------------------------------------------------------------------------------------------------------
75 void ShaderLib::setShaderParamFromColour( const std::string &_paramName,Colour _p1 ) noexcept
76 {
77 
78  (*this)[m_currentShader]->setUniform4fv(_paramName.c_str(),1,_p1.openGL());
79 
80 }
81 //----------------------------------------------------------------------------------------------------------------------
82 void ShaderLib::setRegisteredUniformFromColour(const std::string &_paramName, Colour _p1 ) noexcept
83 {
84  (*this)[m_currentShader]->setRegisteredUniform4f(_paramName,_p1.m_r,_p1.m_g,_p1.m_b,_p1.m_a);
85 }
86 //----------------------------------------------------------------------------------------------------------------------
87 void ShaderLib::setRegisteredUniformVec3(const std::string &_paramName,Vec3 _p1 ) noexcept
88 {
89  (*this)[m_currentShader]->setRegisteredUniform3f(_paramName,_p1.m_x,_p1.m_y,_p1.m_z);
90 }
91 
92 //----------------------------------------------------------------------------------------------------------------------
93 void ShaderLib::setRegisteredUniformVec2( const std::string &_paramName, Vec2 _p1 ) noexcept
94 {
95  (*this)[m_currentShader]->setRegisteredUniform2f(_paramName,_p1.m_x,_p1.m_y);
96 }
97 
98 
99 
100 
101 //----------------------------------------------------------------------------------------------------------------------
102 void ShaderLib::setShaderParam4f(const std::string &_paramName, float _p1,float _p2, float _p3, float _p4 ) noexcept
103 {
104  (*this)[m_currentShader]->setUniform4f(_paramName.c_str(),_p1,_p2,_p3,_p4);
105 }
106 
107 //----------------------------------------------------------------------------------------------------------------------
108 void ShaderLib::setRegisteredUniform4f(const std::string &_paramName,float _p1,float _p2, float _p3, float _p4 ) noexcept
109 {
110  (*this)[m_currentShader]->setRegisteredUniform4f(_paramName,_p1,_p2,_p3,_p4);
111 }
112 
113 //----------------------------------------------------------------------------------------------------------------------
114 void ShaderLib::setShaderParam3f(const std::string &_paramName, float _p1, float _p2, float _p3 ) noexcept
115 {
116  (*this)[m_currentShader]->setUniform3f(_paramName.c_str(),_p1,_p2,_p3);
117 }
118 
119 //----------------------------------------------------------------------------------------------------------------------
120 void ShaderLib::setRegisteredUniform3f( const std::string &_paramName, float _p1, float _p2, float _p3 ) noexcept
121 {
122  (*this)[m_currentShader]->setRegisteredUniform3f(_paramName,_p1,_p2,_p3);
123 }
124 
125 //----------------------------------------------------------------------------------------------------------------------
126 void ShaderLib::setShaderParam2f( const std::string &_paramName,float _p1, float _p2 ) noexcept
127 {
128  (*this)[m_currentShader]->setUniform2f(_paramName.c_str(),_p1,_p2);
129 
130 }
131 
132 //----------------------------------------------------------------------------------------------------------------------
133 void ShaderLib::setRegisteredUniform2f( const std::string &_paramName, float _p1, float _p2 ) noexcept
134 {
135  (*this)[m_currentShader]->setRegisteredUniform2f(_paramName,_p1,_p2);
136 }
137 //----------------------------------------------------------------------------------------------------------------------
138 void ShaderLib::setShaderParam1i(const std::string &_paramName, int _p1 ) noexcept
139 {
140  (*this)[m_currentShader]->setUniform1i(_paramName.c_str(),_p1);
141 
142 }
143 
144 //----------------------------------------------------------------------------------------------------------------------
145 void ShaderLib::setRegisteredUniform1i(const std::string &_paramName, int _p1 ) noexcept
146 {
147  (*this)[m_currentShader]->setRegisteredUniform1i(_paramName,_p1);
148 }
149 
150 
151 
152 //----------------------------------------------------------------------------------------------------------------------
153 void ShaderLib::setShaderParam1f( const std::string &_paramName, float _p1 ) noexcept
154 {
155  (*this)[m_currentShader]->setUniform1f(_paramName.c_str(),_p1);
156 
157 }
158 
159 //----------------------------------------------------------------------------------------------------------------------
160 void ShaderLib::setRegisteredUniform1f(const std::string &_paramName, float _p1 ) noexcept
161 {
162  (*this)[m_currentShader]->setRegisteredUniform1f(_paramName,_p1);
163 }
164 
165 
166 //----------------------------------------------------------------------------------------------------------------------
167 void ShaderLib::loadShader( const std::string &_shaderName,const std::string &_vert, const std::string &_frag,const std::string &_geo, const bool _exitOnError ) noexcept
168 {
169  // must add code to do this next version
170  NGL_UNUSED(_exitOnError);
171  createShaderProgram(_shaderName);
172 
173  attachShader(_shaderName+"Vertex",ShaderType::VERTEX);
174  attachShader(_shaderName+"Fragment",ShaderType::FRAGMENT);
175  loadShaderSource(_shaderName+"Vertex",_vert);
176  loadShaderSource(_shaderName+"Fragment",_frag);
177 
178  compileShader(_shaderName+"Vertex");
179  compileShader(_shaderName+"Fragment");
180  attachShaderToProgram(_shaderName,_shaderName+"Vertex");
181  attachShaderToProgram(_shaderName,_shaderName+"Fragment");
182  if( _geo !="")
183  {
184  attachShader(_shaderName+"Geo",ShaderType::GEOMETRY);
185  loadShaderSource(_shaderName+"Geo",_vert);
186  compileShader(_shaderName+"Geo");
187  attachShaderToProgram(_shaderName,_shaderName+"Geo");
188  }
189 
190  linkProgramObject(_shaderName);
191 }
192 
193 
194 //----------------------------------------------------------------------------------------------------------------------
195 void ShaderLib::reset() noexcept
196 {
197  std::cerr<<"Closing down shader manager\n";
198  for(auto programs : m_shaderPrograms)
199  delete programs.second;
200  for(auto shader : m_shaders)
201  delete shader.second;
202 }
203 
204 
205 //----------------------------------------------------------------------------------------------------------------------
206 GLint ShaderLib::getAttribLocation( const std::string &_shaderName, const std::string &_paramName ) noexcept
207 {
208 
209  GLint attrib=0;
210 
211  // get an iterator to the shaders
212  auto shader=m_shaderPrograms.find(_shaderName);
213  // make sure we have a valid shader
214  if(shader!=m_shaderPrograms.end())
215  {
216  // grab the pointer to the shader and call compile
217  attrib=glGetAttribLocation(shader->second->getID(),_paramName.c_str());
218  }
219  else
220  {
221  std::cerr <<"Warning trying to get attrib "<<_paramName<<" from "<<_shaderName<<" but not found\n";
222  }
223 
224  return attrib;
225 
226 }
227 
228 
229 
230 //----------------------------------------------------------------------------------------------------------------------
232 {
233 //std::cout<<"Shader Manager ctor\n";
234  m_debugState=false;
235  m_numShaders=0;
236  m_nullProgram = new ShaderProgram("NULL");
237  m_currentShader="NULL";
239  loadTextShaders();
242  loadToonShaders();
243  m_debugState=true;
244 }
245 //----------------------------------------------------------------------------------------------------------------------
246 GLuint ShaderLib::getShaderID(const std::string &_shaderName) noexcept
247 {
248  GLuint value = 0;
249  auto shader=m_shaders.find(_shaderName);
250  // make sure we have a valid shader and program
251  if(shader!=m_shaders.end() )
252  {
253  value = shader->second->getShaderHandle();
254  }
255  else
256  {
257  std::cout<<"Warning: No shader named "<< _shaderName << " in " << m_currentShader <<" shader program \n";
258  }
259  return value;
260 }
261 
262 ngl::Shader* ShaderLib::getShader(const std::string &_shaderName) noexcept
263 {
264  ngl::Shader* shaderPointer;
265  auto shader=m_shaders.find(_shaderName);
266  // make sure we have a valid shader and program
267  if(shader!=m_shaders.end() )
268  {
269  shaderPointer = shader->second;
270  }
271  else
272  {
273  shaderPointer = nullptr;
274  std::cout<<"Warning: No shader named "<< _shaderName << " in " << m_currentShader <<" shader program \n";
275  }
276  return shaderPointer;
277 }
278 //----------------------------------------------------------------------------------------------------------------------
279 void ShaderLib::attachShader(const std::string &_name, ShaderType _type ) noexcept
280 {
281  m_shaders[_name]= new Shader(_name,_type);
282  if(m_debugState==true)
283  std::cout<<"just attached "<<_name<<" "<<m_shaders[_name]->getShaderHandle()<<"\n";
284 }
285 
286 //----------------------------------------------------------------------------------------------------------------------
287 void ShaderLib::compileShader( const std::string &_name ) noexcept
288 {
289  // get an iterator to the shaders
290  auto shader=m_shaders.find(_name);
291  // make sure we have a valid shader
292  if(shader!=m_shaders.end())
293  {
294  // grab the pointer to the shader and call compile
295  shader->second->compile();
296  }
297  else {std::cerr<<"Warning shader not know in compile "<<_name.c_str();}
298 
299 }
300 //----------------------------------------------------------------------------------------------------------------------
301 void ShaderLib::createShaderProgram(const std::string &_name ) noexcept
302 {
303  if(m_debugState)
304  std::cerr<<"creating empty ShaderProgram "<<_name.c_str()<<"\n";
305  m_shaderPrograms[_name]= new ShaderProgram(_name);
306 }
307 //----------------------------------------------------------------------------------------------------------------------
308 void ShaderLib::attachShaderToProgram( const std::string &_program, const std::string &_shader ) noexcept
309 {
310 
311  // get an iterator to the shader and program
312  auto shader=m_shaders.find(_shader);
313  auto program=m_shaderPrograms.find(_program);
314 
315  // make sure we have a valid shader and program
316  if(shader!=m_shaders.end() && program !=m_shaderPrograms.end())
317  {
318  // now attach the shader to the program
319  program->second->attachShader(shader->second);
320  // now increment the shader ref count so we know if how many references
321  shader->second->incrementRefCount();
322 
323  if (m_debugState == true)
324  {
325  std::cerr<<_shader.c_str()<<" attached to program "<<_program.c_str()<<"\n";
326  }
327  }
328  else {std::cerr<<"Warning cant attach "<<_shader.c_str() <<" to "<<_program.c_str()<<"\n";}
329 }
330 
331 //----------------------------------------------------------------------------------------------------------------------
332 void ShaderLib::loadShaderSource(std::string _shaderName, std::string _sourceFile ) noexcept
333 {
334  auto shader=m_shaders.find(_shaderName);
335  // make sure we have a valid shader and program
336  if(shader!=m_shaders.end() )
337  {
338  shader->second->load(_sourceFile);
339  }
340  else {std::cerr<<"Warning shader not know in loadShaderSource "<<_shaderName.c_str();}
341 
342 }
343 
344 
346 {
347  // convert to low for test
348  std::string tlower=type;
349  std::transform(type.begin(), type.end(), tlower.begin(), ::tolower);
350  const static std::unordered_map<std::string,ShaderType> stype=
351  {
352  {"vertex",ShaderType::VERTEX},
353  {"fragment",ShaderType::FRAGMENT},
354  {"geometry",ShaderType::GEOMETRY},
355  {"tesscontrol",ShaderType::TESSCONTROL},
356  {"tesseval",ShaderType::TESSEVAL},
357  {"compute",ShaderType::COMPUTE}
358  };
359 
360  auto value=stype.find(tlower);
361  if(value !=stype.end())
362  {
363  return value->second;
364  }
365  else
366  {
367  return ShaderType::NONE;
368  }
369 }
370 
371 
372 bool ShaderLib::loadFromJson(const std::string &_fname) noexcept
373 {
374  namespace rj=rapidjson;
375  std::ifstream file;
376  file.open(_fname.c_str(), std::ios::in);
377  if (file.fail())
378  {
379  std::cerr<<"error opening json file\n";
380  exit(EXIT_FAILURE);
381  }
382  std::unique_ptr<std::string> source( new std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()) );
383  file.close();
384  // we need a mutable string for parsing so copy to a char * buffer
385 
386  std::unique_ptr<char []> buffer(new char[source->size()]);
387  memcpy(buffer.get(), source->c_str(), source->size());
388  // null terminate the string!
389  buffer[source->size()]='\0';
390 
391  rj::Document doc;
392 
393  if (doc.ParseInsitu<0>(buffer.get()).HasParseError())
394  {
395  std::cerr<<"Parse Error for file "<<_fname<<"\n";
396  return false;
397 
398  }
399 
400  if(!doc.HasMember("ShaderProgram"))
401  {
402  std::cerr<<"This does not seem to be a valid shader json file"<<std::endl;
403  return false;
404  }
405  std::cout<<"***************Loading Shaders from JSON*****************\n";
406 
407  bool debug=false;
408  // Now we iterate through the json and gather our data.
409  for (rj::Value::ConstMemberIterator itr = doc.MemberBegin(); itr != doc.MemberEnd(); ++itr)
410  {
411  if(itr->value.HasMember("debug"))
412  {
413  debug=itr->value["debug"].GetBool();
414  }
415  const rj::Value::Ch* progName=itr->value["name"].GetString();
416  if(progName ==NULL || strlen(progName)==0 )
417  {
418  std::cerr<<"ShaderProgram must have a name (or could be 0 length) \n";
419  return false;
420  }
421  createShaderProgram(progName);
422  const rj::Value& shaders = itr->value["Shaders"];
423  for (rj::SizeType i = 0; i < shaders.Size(); i++)
424  {
425  const rj::Value &currentShader = shaders[i];
426  const rj::Value::Ch *name=currentShader["name"].GetString();
427  ShaderType shadertype=getShaderType(currentShader["type"].GetString());
428 
429  attachShader(name,shadertype);
430  const rj::Value& paths = currentShader["path"];
431  std::string shaderSource;
432  for (rj::SizeType p = 0; p < paths.Size(); p++)
433  {
434  // load the shader sources in order.
435  std::ifstream source;
436  source.open(paths[p].GetString(), std::ios::in);
437  if(debug)
438  {
439  std::cout<<"attempting to load "<<paths[p].GetString()<<"\n";
440  }
441  if (source.fail())
442  {
443  std::cerr<<"error opening shader file\n";
444  exit(EXIT_FAILURE);
445  }
446  std::unique_ptr<std::string> f( new std::string((std::istreambuf_iterator<char>(source)), std::istreambuf_iterator<char>()));
447  if(debug)
448  {
449  std::cout<<"loaded data string \n"<< const_cast<char *>(f->c_str())<<"\n";
450  }
451  source.close();
452  shaderSource+=*f;
453  shaderSource+="\n";
454  }
455  loadShaderSourceFromString(name,shaderSource);
456  if(debug)
457  {
458  std::cout<<"********* Final Shader String ***************\n";
459  std::cout<<shaderSource<<"\n";
460  }
461  compileShader(name);
462  attachShaderToProgram(progName,name);
463  } // end parse shader loop
464  if(debug)
465  {
466  std::cout<<"Linking and registering Uniforms to ShaderLib\n";
467  }
468  linkProgramObject(progName);
469  //autoRegisterUniforms(progName);
470  std::cout<<"**********************DONE********************\n";
471  }
472  return true;
473 }
474 
475 
476 //----------------------------------------------------------------------------------------------------------------------
477 void ShaderLib::loadShaderSourceFromString(const std::string &_shaderName, const std::string &_string ) noexcept
478 {
479  auto shader=m_shaders.find(_shaderName);
480  // make sure we have a valid shader and program
481  if(shader!=m_shaders.end() )
482  {
483  shader->second->loadFromString(_string);
484  //std::cout<<*_string<<"\n";
485  }
486  else {std::cerr<<"Warning shader not know in loadShaderSource "<<_shaderName.c_str();}
487 
488 }
489 
490 
491 //----------------------------------------------------------------------------------------------------------------------
492 void ShaderLib::linkProgramObject(const std::string &_name ) noexcept
493 {
494 
495  auto program=m_shaderPrograms.find(_name);
496  // make sure we have a valid program
497  if(program!=m_shaderPrograms.end() )
498  {
499  std::cerr<<"Linking "<<_name.c_str()<<"\n";
500  program->second->link();
501  }
502  else {std::cerr<<"Warning Program not known in link "<<_name.c_str();}
503 
504 }
505 
506 //----------------------------------------------------------------------------------------------------------------------
507 void ShaderLib::use( const std::string &_name ) noexcept
508 {
509  auto program=m_shaderPrograms.find(_name);
510  // make sure we have a valid program
511  if(program!=m_shaderPrograms.end() )
512  {
513  //std::cerr<<"Shader manager Use\n";
514  m_currentShader=_name;
515  program->second->use();
516  }
517  else
518  {
519  std::cerr<<"Warning Program not know in use "<<_name.c_str()<<"\n";
520  m_currentShader="NULL";
521  glUseProgram(0);
522  }
523 
524 }
525 
526 
527 //----------------------------------------------------------------------------------------------------------------------
529 {
530  auto program=m_shaderPrograms.find(_name);
531  // make sure we have a valid program
532  if(program!=m_shaderPrograms.end() )
533  {
534  return program->second->getID();
535  }
536  else
537  {
538  std::cerr<<"Warning Program not know in use "<<_name.c_str();
539  return 0;
540  }
541 }
542 
543 //----------------------------------------------------------------------------------------------------------------------
544 void ShaderLib::autoRegisterUniforms(const std::string &_shaderName ) noexcept
545 {
546  auto program=m_shaderPrograms.find(_shaderName);
547  // make sure we have a valid program
548  if(program!=m_shaderPrograms.end() )
549  {
550  program->second->autoRegisterUniforms();
551  }
552  else
553  {
554  std::cerr<<"Warning Program not know in registerUniform "<<_shaderName<<"\n";
555  }
556 }
557 
558 //----------------------------------------------------------------------------------------------------------------------
559 void ShaderLib::bindAttribute(const std::string &_programName, GLuint _index, const std::string &_attribName ) noexcept
560 {
561  auto program=m_shaderPrograms.find(_programName);
562  // make sure we have a valid program
563  if(program!=m_shaderPrograms.end() )
564  {
565  program->second->bindAttribute(_index,_attribName);
566  }
567  else {std::cerr<<"Warning Program not know in bindAttribute "<<_programName.c_str();}
568 }
569 
570 
571 //----------------------------------------------------------------------------------------------------------------------
572 void ShaderLib::bindFragDataLocation( const std::string &_programName, GLuint _index, const std::string &_attribName ) noexcept
573 {
574  auto program=m_shaderPrograms.find(_programName);
575  // make sure we have a valid program
576  if(program!=m_shaderPrograms.end() )
577  {
578  program->second->bindFragDataLocation(_index,_attribName);
579  }
580  else {std::cerr<<"Warning Program not know in bindAttribute "<<_programName.c_str();}
581 }
582 
583 
584 //----------------------------------------------------------------------------------------------------------------------
585 void ceckGLError( const std::string &_file, const int _line ) noexcept
586 {
587 
588  NGLCheckGLError(_file,_line);
589 
590 }
591 
592 
593 //----------------------------------------------------------------------------------------------------------------------
595 {
596  auto program=m_shaderPrograms.find(_name);
597  // make sure we have a valid program
598  if(program!=m_shaderPrograms.end() )
599  {
600  m_currentShader=_name;
601  return program->second;
602  }
603  else
604  {
605  std::cerr<<"Warning Program not know in [] "<<_name.c_str();
606  std::cerr<<"returning a null program and hoping for the best\n";
607  return m_nullProgram;
608  }
609 }
610 
611 
612 //----------------------------------------------------------------------------------------------------------------------
613 ShaderProgram * ShaderLib::operator[]( const char *_name ) noexcept
614 {
615  auto program=m_shaderPrograms.find(_name);
616  // make sure we have a valid program
617  if(program!=m_shaderPrograms.end() )
618  {
619  m_currentShader=_name;
620 
621  return program->second;
622  }
623  else
624  {
625  std::cerr<<"Warning Program not know in [] "<<_name;
626  std::cerr<<"returning a null program and hoping for the best\n";
627  return m_nullProgram;
628  }
629 }
630 
631 
633 {
634  m_currentShader="NULL";
635  m_nullProgram->use();
636 }
637 
638 
639 GLuint ShaderLib::getUniformBlockIndex( const std::string &_uniformBlockName ) const noexcept
640 {
641 
642  GLuint id=0;
643 
644  // get an iterator to the shaders
646  // make sure we have a valid shader
647  if(shader!=m_shaderPrograms.end())
648  {
649  // grab the pointer to the shader and call compile
650  id=shader->second->getUniformBlockIndex(_uniformBlockName);
651  }
652  else
653  {
654  std::cerr <<"Can't find id for uniform block " << _uniformBlockName <<"\n";
655  }
656 
657  return id;
658 }
659 
661 {
662 
663  createShaderProgram("nglTextShader");
664 
665  attachShader("nglTextVertex",ShaderType::VERTEX);
666  attachShader("nglTextFragment",ShaderType::FRAGMENT);
667 
670 
671  compileShader("nglTextVertex");
672  compileShader("nglTextFragment");
673 
674 
675  attachShaderToProgram("nglTextShader","nglTextVertex");
676  attachShaderToProgram("nglTextShader","nglTextFragment");
677 
678  bindAttribute("nglTextShader",0,"inVert");
679  bindAttribute("nglTextShader",1,"inUV");
680 
681  linkProgramObject("nglTextShader");
682  use("nglTextShader");
683  autoRegisterUniforms("nglTextShader");
684 
685  use("NULL");
686 }
687 
688 
690 {
691 
692  createShaderProgram("nglColourShader");
693 
694  attachShader("nglColourVertex",ShaderType::VERTEX);
695  attachShader("nglColourFragment",ShaderType::FRAGMENT);
696 
699 
700  compileShader("nglColourVertex");
701  compileShader("nglColourFragment");
702 
703 
704  attachShaderToProgram("nglColourShader","nglColourVertex");
705  attachShaderToProgram("nglColourShader","nglColourFragment");
706 
707  bindAttribute("nglColourShader",0,"inVert");
708 
709  linkProgramObject("nglColourShader");
710  use("nglColourShader");
711  autoRegisterUniforms("nglColourShader");
712  use("NULL");
713 }
714 
716 {
717 
718  createShaderProgram("nglDiffuseShader");
719 
720  attachShader("nglDiffuseVertex",ShaderType::VERTEX);
721  attachShader("nglDiffuseFragment",ShaderType::FRAGMENT);
722 
725 
726  compileShader("nglDiffuseVertex");
727  compileShader("nglDiffuseFragment");
728 
729 
730  attachShaderToProgram("nglDiffuseShader","nglDiffuseVertex");
731  attachShaderToProgram("nglDiffuseShader","nglDiffuseFragment");
732 
733  bindAttribute("nglDiffuseShader",0,"inVert");
734  bindAttribute("nglDiffuseShader",2,"inNormal");
735 
736  linkProgramObject("nglDiffuseShader");
737  use("nglDiffuseShader");
738  autoRegisterUniforms("nglDiffuseShader");
739  use("NULL");
740 }
741 
742 
744 {
745 
746  createShaderProgram("nglToonShader");
747 
748  attachShader("nglToonVertex",ShaderType::VERTEX);
749  attachShader("nglToonFragment",ShaderType::FRAGMENT);
750 
753 
754  compileShader("nglToonVertex");
755  compileShader("nglToonFragment");
756 
757 
758  attachShaderToProgram("nglToonShader","nglToonVertex");
759  attachShaderToProgram("nglToonShader","nglToonFragment");
760 
761  bindAttribute("nglToonShader",0,"inVert");
762  bindAttribute("nglToonShader",2,"inNormal");
763 
764  linkProgramObject("nglToonShader");
765  use("nglToonShader");
766  autoRegisterUniforms("nglToonShader");
767  use("NULL");
768 }
769 
770 
771 void ShaderLib::printRegisteredUniforms(const std::string &_shader) const noexcept
772 {
773  auto program=m_shaderPrograms.find(_shader);
774  // make sure we have a valid program
775  if(program!=m_shaderPrograms.end() )
776  {
777  program->second->printRegisteredUniforms();
778  }
779 }
780 
781 void ShaderLib::printProperties() const noexcept
782 {
783 
785  // make sure we have a valid program
786  if(program!=m_shaderPrograms.end() )
787  {
788  std::cerr<<"_______________________________________________________________________________________________________________________\n";
789  std::cerr<<"Printing Properties for ShaderProgram "<<m_currentShader<<"\n";
790  std::cerr<<"_______________________________________________________________________________________________________________________\n";
791  program->second->printProperties();
792  std::cerr<<"_______________________________________________________________________________________________________________________\n";
793  }
794  else {std::cerr<<"Warning no currently active shader to print properties for "<<m_currentShader<<"\n";}
795 
796 
797 
798 
799 }
800 
801 
802 void ShaderLib::setUniform(const std::string &_paramName,Real _v0) noexcept
803 {
804  (*this)[m_currentShader]->setUniform1f(_paramName.c_str(),_v0);
805 }
806 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Real _v0) noexcept
807 {
808  (*this)[m_currentShader]->setRegisteredUniform1f(_paramName.c_str(),_v0);
809 
810 }
811 
812 void ShaderLib::setUniform(const std::string &_paramName,Real _v0,Real _v1) noexcept
813 {
814  (*this)[m_currentShader]->setUniform2f(_paramName.c_str(),_v0,_v1);
815 }
816 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Real _v0,Real _v1) noexcept
817 {
818  (*this)[m_currentShader]->setRegisteredUniform2f(_paramName.c_str(),_v0,_v1);
819 
820 }
821 
822 void ShaderLib::setUniform(const std::string &_paramName,Real _v0,Real _v1,Real _v2) noexcept
823 {
824  (*this)[m_currentShader]->setUniform3f(_paramName.c_str(),_v0,_v1,_v2);
825 
826 }
827 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Real _v0,Real _v1,Real _v2) noexcept
828 {
829  (*this)[m_currentShader]->setRegisteredUniform3f(_paramName.c_str(),_v0,_v1,_v2);
830 }
831 
832 void ShaderLib::setUniform(const std::string &_paramName,Real _v0,Real _v1,Real _v2,Real _v3) noexcept
833 {
834  (*this)[m_currentShader]->setUniform4f(_paramName.c_str(),_v0,_v1,_v2,_v3);
835 }
836 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Real _v0,Real _v1,Real _v2,Real _v3) noexcept
837 {
838  (*this)[m_currentShader]->setRegisteredUniform4f(_paramName.c_str(),_v0,_v1,_v2,_v3);
839 }
840 
841 void ShaderLib::setUniform(const std::string &_paramName,GLint _v0) noexcept
842 {
843  (*this)[m_currentShader]->setUniform1i(_paramName.c_str(),_v0);
844 }
845 void ShaderLib::setRegisteredUniform(const std::string &_paramName,GLint _v0) noexcept
846 {
847  (*this)[m_currentShader]->setRegisteredUniform1i(_paramName.c_str(),_v0);
848 }
849 
850 void ShaderLib::setUniform(const std::string &_paramName,GLint _v0,GLint _v1) noexcept
851 {
852  (*this)[m_currentShader]->setUniform2i(_paramName.c_str(),_v0,_v1);
853 }
854 void ShaderLib::setRegisteredUniform(const std::string &_paramName,GLint _v0,GLint _v1) noexcept
855 {
856  (*this)[m_currentShader]->setRegisteredUniform2i(_paramName.c_str(),_v0,_v1);
857 }
858 
859 void ShaderLib::setUniform(const std::string &_paramName,GLint _v0,GLint _v1,GLint _v2) noexcept
860 {
861  (*this)[m_currentShader]->setUniform3i(_paramName.c_str(),_v0,_v1,_v2);
862 }
863 void ShaderLib::setRegisteredUniform(const std::string &_paramName,GLint _v0,GLint _v1,GLint _v2) noexcept
864 {
865  (*this)[m_currentShader]->setRegisteredUniform3i(_paramName.c_str(),_v0,_v1,_v2);
866 }
867 
868 void ShaderLib::setUniform(const std::string &_paramName,GLint _v0,GLint _v1,GLint _v2,GLint _v3) noexcept
869 {
870  (*this)[m_currentShader]->setUniform4i(_paramName.c_str(),_v0,_v1,_v2,_v3);
871 }
872 void ShaderLib::setRegisteredUniform(const std::string &_paramName,GLint _v0,GLint _v1,GLint _v2,GLint _v3) noexcept
873 {
874  (*this)[m_currentShader]->setRegisteredUniform4f(_paramName.c_str(),_v0,_v1,_v2,_v3);
875 }
876 
877 void ShaderLib::setUniform(const std::string &_paramName,Colour _v0) noexcept
878 {
879  (*this)[m_currentShader]->setUniform4f(_paramName.c_str(),_v0.m_r,_v0.m_g,_v0.m_b,_v0.m_a);
880 }
881 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Colour _v0) noexcept
882 {
883  (*this)[m_currentShader]->setRegisteredUniform4f(_paramName.c_str(),_v0.m_r,_v0.m_g,_v0.m_b,_v0.m_a);
884 }
885 void ShaderLib::setUniform(const std::string &_paramName,Vec2 _v0) noexcept
886 {
887  (*this)[m_currentShader]->setUniform2f(_paramName.c_str(),_v0.m_x,_v0.m_y);
888 }
889 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Vec2 _v0) noexcept
890 {
891  (*this)[m_currentShader]->setRegisteredUniform2f(_paramName.c_str(),_v0.m_x,_v0.m_y);
892 }
893 void ShaderLib::setUniform(const std::string &_paramName,Vec3 _v0) noexcept
894 {
895  (*this)[m_currentShader]->setUniform3f(_paramName.c_str(),_v0.m_x,_v0.m_y,_v0.m_z);
896 }
897 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Vec3 _v0) noexcept
898 {
899  (*this)[m_currentShader]->setRegisteredUniform3f(_paramName.c_str(),_v0.m_x,_v0.m_y,_v0.m_z);
900 }
901 void ShaderLib::setUniform(const std::string &_paramName,Vec4 _v0) noexcept
902 {
903  (*this)[m_currentShader]->setUniform4f(_paramName.c_str(),_v0.m_x,_v0.m_y,_v0.m_z,_v0.m_w);
904 }
905 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Vec4 _v0) noexcept
906 {
907  (*this)[m_currentShader]->setRegisteredUniform4f(_paramName.c_str(),_v0.m_x,_v0.m_y,_v0.m_z,_v0.m_w);
908 }
909 
910 void ShaderLib::setUniform(const std::string &_paramName,Mat3 _v0) noexcept
911 {
912  (*this)[m_currentShader]->setUniformMatrix3fv(_paramName.c_str(),1,GL_FALSE,_v0.openGL());
913 
914 }
915 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Mat3 _v0) noexcept
916 {
917  (*this)[m_currentShader]->setRegisteredUniformMatrix3fv(_paramName,1,GL_FALSE,_v0.openGL());
918 
919 }
920 
921 void ShaderLib::setUniform(const std::string &_paramName,Mat4 _v0) noexcept
922 {
923  (*this)[m_currentShader]->setUniformMatrix4fv(_paramName.c_str(),1,GL_FALSE,_v0.openGL());
924 }
925 void ShaderLib::setRegisteredUniform(const std::string &_paramName,Mat4 _v0) noexcept
926 {
927  (*this)[m_currentShader]->setRegisteredUniformMatrix4fv(_paramName,1,GL_FALSE,_v0.openGL());
928 }
929 
930 
931 
932 
933 
934 } // end ngl namespace
935 
936 
937 
938 //----------------------------------------------------------------------------------------------------------------------
939 
void printRegisteredUniforms(const std::string &_shader) const noexcept
debug print any registered uniforms
Definition: ShaderLib.cpp:771
#define NGL_UNUSED(arg)
define unused to quiet Warnings
Definition: Types.h:143
unsigned int GLuint
Definition: glew.h:280
Mat3 basic 3x3 matrix for certain glsl ops.
Definition: Mat3.h:43
void bindFragDataLocation(const std::string &_programName, GLuint _index, const std::string &_attribName) noexcept
fragment shader output location
Definition: ShaderLib.cpp:572
simple Vec2 encapsulates a 3 float object like glsl Vec2 but not maths use the Vec2 class for maths a...
Definition: Vec2.h:49
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
simple class to hold colour information and set the basic opengl colour state. also has overloaded me...
Definition: Colour.h:40
simple Vector class for OpenGL graphics, contains overloaded operators for most math functions...
Definition: Vec4.h:57
ngl::Shader * getShader(const std::string &_shaderName) noexcept
method to return the specified shader object
Definition: ShaderLib.cpp:262
void setUniform(const std::string &_paramName, Real _v0) noexcept
overloaded method to set shader Uniforms the shader must be the currently active shader of else this ...
Definition: ShaderLib.cpp:802
void loadShaderSourceFromString(const std::string &_shaderName, const std::string &_string) noexcept
load shader from a C string, useful for including code in headers etc
Definition: ShaderLib.cpp:477
void setShaderParam1f(const std::string &_paramName, float _p1) noexcept
set a shader param by name for 1 float param note that the shader must be the currently active shader...
Definition: ShaderLib.cpp:153
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1256
const std::string colourFragmentShader
Definition: ColourShaders.h:33
const std::string diffuseFragmentShader
#define glGetAttribLocation
Definition: glew.h:1925
#define GL_FALSE
Definition: glew.h:314
GLsizei const GLfloat * value
Definition: glew.h:1852
void loadColourShaders() noexcept
this will load the pre-defined text rendering shaders these are stored in the file src/shaders/Colour...
Definition: ShaderLib.cpp:689
void loadDiffuseShaders() noexcept
this will load the pre-defined text rendering shaders these are stored in the file src/shaders/Diffus...
Definition: ShaderLib.cpp:715
void setRegisteredUniform2f(const std::string &_paramName, float _p1, float _p2) noexcept
set the pre-registered uniform
Definition: ShaderLib.cpp:133
GLenum shadertype
Definition: glew.h:6411
simple Vec3 encapsulates a 3 float object like glsl vec3 but not maths use the Vec3 class for maths a...
Definition: Vec3.h:51
void ceckGLError(const std::string &_file, const int _line) noexcept
Definition: ShaderLib.cpp:585
main shader loader / manager class for GLSL shaders
implementation files for RibExport class
Definition: AABB.cpp:22
GLuint in
Definition: glew.h:11550
void compileShader(const std::string &_name) noexcept
compile the shader from _name
Definition: ShaderLib.cpp:287
void bindAttribute(const std::string &_programName, GLuint _index, const std::string &_attribName) noexcept
bind an attribute at index by name
Definition: ShaderLib.cpp:559
unsigned int m_numShaders
the nunmber of shaders loaded
Definition: ShaderLib.h:660
PRECISION Real
create a variable called Real which is the main data type we use (GLfloat for most cases) ...
Definition: Types.h:127
void loadShader(const std::string &_shaderName, const std::string &_vert, const std::string &_frag, const std::string &_geo="", const bool _exitOnError=false) noexcept
method to load shaders
Definition: ShaderLib.cpp:167
GLsizei GLsizei GLchar * source
Definition: glew.h:1835
GLuint GLenum GLenum transform
Definition: glew.h:15053
GLint getAttribLocation(const std::string &_shaderName, const std::string &_paramName) noexcept
return the index to the shader attribute location
Definition: ShaderLib.cpp:206
void setRegisteredUniformVec2(const std::string &_paramName, Vec2 _p1) noexcept
set the pre-registered uniform from a Vector
Definition: ShaderLib.cpp:93
GLuint shader
Definition: glew.h:1816
std::string m_currentShader
the name of the currently active shader
Definition: ShaderLib.h:652
ShaderProgram * operator[](const std::string &_name) noexcept
accessor to the shader program using the subscript operatoir
Definition: ShaderLib.cpp:594
void setRegisteredUniform1f(const std::string &_paramName, float _p1) noexcept
set the pre-registered uniform
Definition: ShaderLib.cpp:160
bool loadFromJson(const std::string &_fname) noexcept
method to load multiple shaders from a json file
Definition: ShaderLib.cpp:372
GLuint id
Definition: glew.h:1682
void setRegisteredUniformFromColour(const std::string &_paramName, Colour _p1) noexcept
set the pre-registered uniform from an Colour
Definition: ShaderLib.cpp:82
const std::string toonVertexShader
Definition: ToonShaders.h:5
GLsizei GLsizei GLuint * shaders
Definition: glew.h:1830
void setRegisteredUniform1i(const std::string &_paramName, int _p1) noexcept
set the pre-registered uniform
Definition: ShaderLib.cpp:145
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:1758
void setRegisteredUniformVec4(const std::string &_paramName, Vec4 _p1) noexcept
set the pre-registered uniform from an Vec4
Definition: ShaderLib.cpp:69
std::unordered_map< std::string, ShaderProgram * > m_shaderPrograms
a map of shader Programs using name as key to shader pointer
Definition: ShaderLib.h:640
void use(const std::string &_name) noexcept
set active shader to name (if not found sets glProgramObject(0)
Definition: ShaderLib.cpp:507
ShaderType
Definition: Shader.h:30
GLfloat GLfloat p
Definition: glew.h:16654
const GLuint * programs
Definition: glew.h:7757
void setShaderParamFromMat4(const std::string &_paramName, Mat4 _p1) noexcept
set a shader param by name for 1 int param note that the shader must be the currently active shader o...
Definition: ShaderLib.cpp:39
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2077
void loadToonShaders() noexcept
this will load the pre-defined text rendering shaders these are stored in the file src/shaders/ToonSh...
Definition: ShaderLib.cpp:743
GLuint buffer
Definition: glew.h:1683
void loadShaderSource(std::string _shaderName, std::string _sourceFile) noexcept
Load shader source from text file the path will be relative from current dir unless a full path is sp...
Definition: ShaderLib.cpp:332
void printProperties() const noexcept
print the properties of the currently active shader
Definition: ShaderLib.cpp:781
void setRegisteredUniform4f(const std::string &_paramName, float _p1, float _p2, float _p3, float _p4) noexcept
set the pre-registered uniform
Definition: ShaderLib.cpp:108
const std::string textFragmentShader
Definition: TextShaders.h:26
main RapidJSON namespace
void useNullProgram() noexcept
use the null program (this will turn off any shaders), if using some drivers this will go to the fixe...
Definition: ShaderLib.cpp:632
void setShaderParam3f(const std::string &_paramName, float _p1, float _p2, float _p3) noexcept
set a shader param by name for 3 float params note that the shader must be the currently active shade...
Definition: ShaderLib.cpp:114
void autoRegisterUniforms(const std::string &_shaderName) noexcept
will parse the shader source and find any uniforms it can and register them
Definition: ShaderLib.cpp:544
void attachShaderToProgram(const std::string &_program, const std::string &_shader) noexcept
attatch a Shader to the ShaderProgram referenced by _name
Definition: ShaderLib.cpp:308
void use() noexcept
use this Shader object as the current Active shader once this is set it is active until unbind us cal...
GLuint program
Definition: glew.h:5909
and encapsulation of an OpenGL Shader object with associations for source code, etc. Used in conjunction with the ShaderProgram class
Definition: Shader.h:40
ShaderType getShaderType(const std::string &type) noexcept
get shader type from string (used for json parsing)
Definition: ShaderLib.cpp:345
void setRegisteredUniform3f(const std::string &_paramName, float _p1, float _p2, float _p3) noexcept
set the pre-registered uniform
Definition: ShaderLib.cpp:120
void setShaderParamFromMat3(const std::string &_paramName, Mat3 _p1) noexcept
set a shader param by name for 1 int param note that the shader must be the currently active shader o...
Definition: ShaderLib.cpp:51
void setShaderParam1i(const std::string &_paramName, int _p1) noexcept
set a shader param by name for 1 int param note that the shader must be the currently active shader o...
Definition: ShaderLib.cpp:138
GLuint const GLchar * name
Definition: glew.h:1817
void setRegisteredUniformFromMat4(const std::string &_registeredUniformName, Mat4 _p1) noexcept
set a shader param by name for 1 int param note that the shader must be the currently active shader o...
Definition: ShaderLib.cpp:45
ShaderProgram * m_nullProgram
null ShaderProgram so we can return when shader not know;
Definition: ShaderLib.h:648
bool m_debugState
flag to indicate the debug state
Definition: ShaderLib.h:656
void setShaderParam2f(const std::string &_paramName, float _p1, float _p2) noexcept
set a shader param by name for 2 float params note that the shader must be the currently active shade...
Definition: ShaderLib.cpp:126
void attachShader(const std::string &_name, ShaderType _type) noexcept
attatch a Shader to the ShaderProgram referenced by _name
Definition: ShaderLib.cpp:279
void setRegisteredUniform(const std::string &_paramName, Real _v0) noexcept
overloaded method to set shader Uniforms that have been pre-registered using auto-register uniforms m...
Definition: ShaderLib.cpp:806
const std::string textVertexShader
Definition: TextShaders.h:5
void loadTextShaders() noexcept
this will load the pre-defined text rendering shaders these are stored in the file src/shaders/TextSh...
Definition: ShaderLib.cpp:660
Matrix Class to do simple matrix operations included operator overloaded functions for maths and matr...
Definition: Mat4.h:58
void setShaderParam4f(const std::string &_paramName, float _p1, float _p2, float _p3, float _p4) noexcept
set a shader param by name for 4 float params note that the shader must be the currently active shade...
Definition: ShaderLib.cpp:102
const std::string toonFragmentShader
Definition: ToonShaders.h:22
#define glUseProgram
Definition: glew.h:1964
void createShaderProgram(const std::string &_name) noexcept
create an empty ShaderProgram for us to attach shaders etc to
Definition: ShaderLib.cpp:301
int GLint
Definition: glew.h:281
void setShaderParamFromVec4(const std::string &_paramName, Vec4 _p1) noexcept
set a shader param by name for 1 int param note that the shader must be the currently active shader o...
Definition: ShaderLib.cpp:62
void setShaderParamFromColour(const std::string &_paramName, Colour _p1) noexcept
set a shader param by name for 1 int param note that the shader must be the currently active shader o...
Definition: ShaderLib.cpp:75
GLuint getUniformBlockIndex(const std::string &_uniformBlockName) const noexcept
grab the index of the unifrom block, this may not be supported on all GPU&#39;s
Definition: ShaderLib.cpp:639
void setRegisteredUniformVec3(const std::string &_paramName, Vec3 _p1) noexcept
set the pre-registered uniform from an Vector
Definition: ShaderLib.cpp:87
std::unordered_map< std::string, Shader * > m_shaders
map of shaders using name as key
Definition: ShaderLib.h:644
void setRegisteredUniformFromMat3(const std::string &_paramName, Mat3 _p1) noexcept
set the registered uniform from Max3x3
Definition: ShaderLib.cpp:57
GLuint getProgramID(const std::string &_name) noexcept
get the Program ID of the GL Program by name
Definition: ShaderLib.cpp:528
void reset() noexcept
reset the Shader manager which will delete all shader objects
Definition: ShaderLib.cpp:195
void linkProgramObject(const std::string &_name) noexcept
link the program Object from _name
Definition: ShaderLib.cpp:492
ShaderLib() noexcept
default ctor private as a singleton
Definition: ShaderLib.cpp:231
NGL_DLLEXPORT void NGLCheckGLError(const std::string &_file, const int _line) noexcept
check for openGL errors and print out.
Definition: Util.cpp:101
GLsizei const GLchar *const * string
Definition: glew.h:1847
GLuint getShaderID(const std::string &_shaderName) noexcept
method to return a shader ID
Definition: ShaderLib.cpp:246
const std::string colourVertexShader
Definition: ColourShaders.h:5
const std::string diffuseVertexShader
Definition: DiffuseShaders.h:6
GLenum const void * paths
Definition: glew.h:13870
GLclampf f
Definition: glew.h:3511