SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLGLShader Class Reference

Encapsulation of an OpenGL shader object. More...

#include <SLGLShader.h>

Inheritance diagram for SLGLShader:
[legend]

Public Member Functions

 SLGLShader ()
 Default constructor. More...
 
 SLGLShader (const SLstring &filename, SLShaderType type)
 Ctor with shader filename & shader type. More...
 
 ~SLGLShader () override
 
void load (const SLstring &filename)
 SLGLShader::load loads a shader file into string _shaderSource. More...
 
void loadFromMemory (const SLstring &program)
 SLGLShader::load loads a shader file from memory into memory. More...
 
SLstring typeName ()
 Returns the shader type as string. More...
 
SLShaderType type ()
 
SLuint shaderID () const
 
SLstring code ()
 
void code (SLstring strCode)
 
void file (SLstring strFile)
 
- Public Member Functions inherited from SLObject
 SLObject (const SLstring &Name="", const SLstring &url="")
 
virtual ~SLObject ()
 
void name (const SLstring &Name)
 
void url (const SLstring &url)
 
const SLstringname () const
 
const SLstringurl () const
 

Static Public Member Functions

static SLstring removeComments (SLstring src)
 SLGLShader::removeComments for C/C++ comments removal from shader code. More...
 

Protected Attributes

SLShaderType _type
 Shader type enumeration. More...
 
SLuint _shaderID
 Program Object. More...
 
SLstring _code
 ASCII Source-Code. More...
 
SLstring _file
 Path & filename of shader. More...
 
- Protected Attributes inherited from SLObject
SLstring _name
 name of an object More...
 
SLstring _url
 uniform resource locator More...
 

Private Member Functions

SLbool createAndCompile (SLVLight *lights)
 SLGLShader::createAndCompile creates & compiles the OpenGL shader object. More...
 
SLstring preprocessIncludePragmas (SLstring inCode)
 Replaces our custom pragma include directives in GLSL code. More...
 
SLstring preprocessDefinePragmas (SLstring inCode, SLVLight *lights)
 Replaces our custom pragma define directives in GLSL code. More...
 

Friends

class SLGLProgram
 

Detailed Description

Encapsulation of an OpenGL shader object.

The SLGLShader class represents a shader object of the OpenGL Shading Language (GLSL). It can load & compile an GLSL shader file and is later on attached to an OpenGL program (SLGLProgram). Instances of SLShader are owned and deleted by their program (SLGLProgram).

Definition at line 24 of file SLGLShader.h.

Constructor & Destructor Documentation

◆ SLGLShader() [1/2]

SLGLShader::SLGLShader ( )

Default constructor.

Definition at line 26 of file SLGLShader.cpp.

27 {
28  _type = ST_none;
29  _code = "";
30  _shaderID = 0;
31  _file = "";
32 }
@ ST_none
Definition: SLEnums.h:223
SLuint _shaderID
Program Object.
Definition: SLGLShader.h:55
SLShaderType _type
Shader type enumeration.
Definition: SLGLShader.h:54
SLstring _file
Path & filename of shader.
Definition: SLGLShader.h:57
SLstring _code
ASCII Source-Code.
Definition: SLGLShader.h:56

◆ SLGLShader() [2/2]

SLGLShader::SLGLShader ( const SLstring filename,
SLShaderType  shaderType 
)

Ctor with shader filename & shader type.

If the shader filename does not belong to an existing file the shader code will be generated at a later stage by SLGLProgramGenerated.

Parameters
filenamePath and filename of the shader to be loaded or generated.
shaderTypeShader type: ST_vertex, ST_fragment and ST_geometry.

Definition at line 40 of file SLGLShader.cpp.

41  : SLObject(Utils::getFileName(filename), filename)
42 {
43  _type = shaderType;
44  _code = "";
45  _shaderID = 0;
46  _file = filename;
47 
48  // Only load file at this moment, don't compile it.
49  if (SLFileStorage::exists(filename, IOK_shader))
50  load(filename);
51 }
@ IOK_shader
Definition: SLFileStorage.h:42
void load(const SLstring &filename)
SLGLShader::load loads a shader file into string _shaderSource.
Definition: SLGLShader.cpp:54
SLObject(const SLstring &Name="", const SLstring &url="")
Definition: SLObject.h:25
bool exists(std::string path, SLIOStreamKind kind)
Checks whether a given file exists.
string getFileName(const string &pathFilename)
Returns the filename of path-filename string.
Definition: Utils.cpp:580

◆ ~SLGLShader()

SLGLShader::~SLGLShader ( )
override

Definition at line 74 of file SLGLShader.cpp.

75 {
76  // SL_LOG("~SLGLShader(%s)", name().c_str());
77  if (_shaderID)
78  glDeleteShader(_shaderID);
80 }
#define GET_GL_ERROR
Definition: SLGLState.h:56

Member Function Documentation

◆ code() [1/2]

SLstring SLGLShader::code ( )
inline

Definition at line 42 of file SLGLShader.h.

42 { return _code; }

◆ code() [2/2]

void SLGLShader::code ( SLstring  strCode)
inline

Definition at line 45 of file SLGLShader.h.

45 { _code = strCode; }

◆ createAndCompile()

SLbool SLGLShader::createAndCompile ( SLVLight lights)
private

SLGLShader::createAndCompile creates & compiles the OpenGL shader object.

Returns
true if compilation was successful

Definition at line 86 of file SLGLShader.cpp.

87 {
88  // delete if object already exits
89  if (_shaderID)
90  glDeleteShader(_shaderID);
91 
92  if (_code.empty())
93  {
94  SL_WARN_MSG("SLGLShader::createAndCompile: Nothing to compile!");
95  std::cout << "file: " << _file << std::endl;
96  return false;
97  }
98 
99  switch (_type)
100  {
101  case ST_vertex:
102  _shaderID = glCreateShader(GL_VERTEX_SHADER);
103  break;
104  case ST_geometry:
105  /*
106  * 0x8DD9 == GL_GEOMETRY_SHADER would be defined in <GLES3/gl32.h>
107  * So far this header is not included by default in Android SDK and therefore
108  * it is not guaranteed that an Android device hat OpenGL ES 3.2 and this header.
109  * The app knows the OpenGL version when it is running. App that are below OpenGL ES 3.2
110  * should not try to create geometry shaders as used for particles.
111  */
112  _shaderID = glCreateShader(0x8DD9);
113  break;
114  case ST_fragment:
115  _shaderID = glCreateShader(GL_FRAGMENT_SHADER);
116  break;
117  default:
118  SL_EXIT_MSG("SLGLShader::load: Unknown shader type.");
119  }
120  GET_GL_ERROR;
121 
122  // Build version string as the first statement
123  SLGLState* state = SLGLState::instance();
124  SLstring verGLSL = state->glSLVersionNO();
125  SLstring srcVersion = "#version " + verGLSL;
126  if (state->glIsES3()) srcVersion += " es";
127  srcVersion += "\n";
128 
130 
131  // Concatenate final code string
132  _code = srcVersion + _code;
133 
134  const char* src = _code.c_str();
135  glShaderSource(_shaderID, 1, &src, nullptr);
136  GET_GL_ERROR;
137 
138  glCompileShader(_shaderID);
139  GET_GL_ERROR;
140 
141  // Check compiler log
142  SLint compileSuccess = 0;
143  glGetShaderiv(_shaderID, GL_COMPILE_STATUS, &compileSuccess);
144  GET_GL_ERROR;
145  if (compileSuccess == GL_FALSE)
146  {
147  GLchar log[1024];
149  glGetShaderInfoLog(_shaderID, sizeof(log), nullptr, &log[0]);
150  SL_LOG("*** COMPILER ERROR ***");
151  SL_LOG("Source file: %s\n", _file.c_str());
152  SL_LOG("%s---", log);
154  SLint lineNum = 1;
155  for (string& line : lines)
156  SL_LOG("%4d: %s", lineNum++, line.c_str());
157  SL_LOG("\n");
158  return false;
159  }
160 
161 #ifndef SL_EMSCRIPTEN
162  // Write generated shader out
163  if (!_file.empty())
164  {
165 # if defined(DEBUG) || defined(_DEBUG)
166  string filename = Utils::getFileName(_file);
167  string path = Utils::getDirName(_file);
168  if (Utils::dirExists(path))
169  {
170  if (Utils::containsString(path, "generatedShaders"))
171  {
173  SL_LOG("Exported Shader : %s", filename.c_str());
174  }
175  }
176  else
177  SL_WARN_MSG("**** No path to write shader ***");
178 # else
180  {
181  string filename = Utils::getFileName(_file);
182  string path = Utils::getDirName(_file);
183  if (Utils::dirExists(path))
184  {
186  SL_LOG("Exported Shader : %s", filename.c_str());
187  }
188  else
189  SL_WARN_MSG("**** No path to write shader ***");
190  }
191 # endif
192  }
193  else
194  SL_WARN_MSG("**** No shader path and filename for shader ***");
195 #endif
196 
197  return true;
198 }
#define SL_LOG(...)
Definition: SL.h:233
#define SL_WARN_MSG(message)
Definition: SL.h:241
vector< SLstring > SLVstring
Definition: SL.h:201
#define SL_EXIT_MSG(message)
Definition: SL.h:240
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
SLstring preprocessDefinePragmas(SLstring inCode, SLVLight *lights)
Replaces our custom pragma define directives in GLSL code.
Definition: SLGLShader.cpp:304
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
SLbool glIsES3() const
Definition: SLGLState.h:136
SLstring glSLVersionNO()
Definition: SLGLState.h:133
void writeString(std::string path, SLIOStreamKind kind, const std::string &string)
Writes a string to a file.
bool dirExists(const string &path)
Returns true if a directory exists.
Definition: Utils.cpp:790
bool containsString(const string &container, const string &search)
Returns true if container contains the search string.
Definition: Utils.cpp:345
vector< string > getStringLines(const string &multiLineString)
Returns a vector of string one per line of a multiline string.
Definition: Utils.cpp:195
string getDirName(const string &pathFilename)
Strip last component from file name.
Definition: Utils.cpp:598
bool onlyErrorLogs
if this flag is set to true all calls to log get ignored
Definition: Utils.cpp:84
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1103

◆ file()

void SLGLShader::file ( SLstring  strFile)
inline

Definition at line 46 of file SLGLShader.h.

46 { _file = strFile; }

◆ load()

void SLGLShader::load ( const SLstring filename)

SLGLShader::load loads a shader file into string _shaderSource.

Definition at line 54 of file SLGLShader.cpp.

55 {
57  _code = SLstring(buffer.data, buffer.data + buffer.size);
58  buffer.deallocate();
59 
60  // Expand include pragmas. This has to be done here because we are not
61  // allowed to perform I/O later on when compiling the shader.
63 
64  // remove comments because some stupid ARM compiler can't handle GLSL comments
66 }
SLstring preprocessIncludePragmas(SLstring inCode)
Replaces our custom pragma include directives in GLSL code.
Definition: SLGLShader.cpp:254
static SLstring removeComments(SLstring src)
SLGLShader::removeComments for C/C++ comments removal from shader code.
Definition: SLGLShader.cpp:201
SLIOBuffer readIntoBuffer(std::string path, SLIOStreamKind kind)
Reads an entire file into memory.
Utility struct that holds a pointer and its length.
Definition: SLFileStorage.h:28
void deallocate()
Deallocates the data owned by the buffer.
size_t size
Definition: SLFileStorage.h:30
unsigned char * data
Definition: SLFileStorage.h:29

◆ loadFromMemory()

void SLGLShader::loadFromMemory ( const SLstring program)

SLGLShader::load loads a shader file from memory into memory.

Definition at line 69 of file SLGLShader.cpp.

70 {
71  _code = shaderSource;
72 }

◆ preprocessDefinePragmas()

SLstring SLGLShader::preprocessDefinePragmas ( SLstring  inCode,
SLVLight lights 
)
private

Replaces our custom pragma define directives in GLSL code.

Definition at line 304 of file SLGLShader.cpp.

305 {
306  // Check first if #pragma exists at all
307  size_t pragmaStart = inCode.find("#pragma");
308  if (pragmaStart == string::npos)
309  return inCode;
310 
311  SLVstring codeLines = Utils::getStringLines(inCode);
312 
313  string outCode;
314 
315  for (string& line : codeLines)
316  {
317  pragmaStart = line.find("#pragma");
318  if (pragmaStart == string::npos)
319  outCode += line + '\n';
320  else
321  {
322  SLVstring pragmaParts;
323  Utils::splitString(line, ' ', pragmaParts);
324 
325  for (auto& part : pragmaParts)
326  part = Utils::trimString(part);
327 
328  if (pragmaParts[1] == "define") //............................
329  {
330  if (pragmaParts[2] == "NUM_LIGHTS")
331  {
332  outCode += "#define NUM_LIGHTS " +
333  std::to_string(lights->size()) + "\n";
334  }
335  else
336  outCode += line + '\n';
337  } //...............................................................
338  else
339  outCode += line + '\n';
340  }
341  }
342  return outCode;
343 }
void splitString(const string &s, char delimiter, vector< string > &splits)
Splits an input string at a delimiter character into a string vector.
Definition: Utils.cpp:152
string trimString(const string &s, const string &drop)
Trims a string at both end.
Definition: Utils.cpp:128

◆ preprocessIncludePragmas()

SLstring SLGLShader::preprocessIncludePragmas ( SLstring  inCode)
private

Replaces our custom pragma include directives in GLSL code.

Definition at line 254 of file SLGLShader.cpp.

255 {
256  // Check first if #pragma exists at all
257  size_t pragmaStart = inCode.find("#pragma");
258  if (pragmaStart == string::npos)
259  return inCode;
260 
261  SLVstring codeLines = Utils::getStringLines(inCode);
262 
263  string outCode;
264 
265  for (string& line : codeLines)
266  {
267  pragmaStart = line.find("#pragma");
268  if (pragmaStart == string::npos)
269  outCode += line + '\n';
270  else
271  {
272  SLVstring pragmaParts;
273  Utils::splitString(line, ' ', pragmaParts);
274 
275  for (auto& part : pragmaParts)
276  part = Utils::trimString(part);
277 
278  if (pragmaParts[1] == "include") //................................
279  {
280  string filename = Utils::trimString(pragmaParts[2], "\"");
281  string path = Utils::getPath(_file);
282  string pathFile = path + filename;
283  if (SLFileStorage::exists(pathFile, IOK_shader))
284  {
285  string includeCode = SLFileStorage::readIntoString(pathFile, IOK_shader);
286  includeCode = removeComments(includeCode);
287  outCode += includeCode + '\n';
288  }
289  else
290  {
291  SL_LOG("SLGLShader::preprocessPragmas: File doesn't exist: %s",
292  pathFile.c_str());
293  outCode += line + '\n';
294  }
295  }
296  else
297  outCode += line + '\n';
298  }
299  }
300  return outCode;
301 }
std::string readIntoString(std::string path, SLIOStreamKind kind)
Reads an entire file into a string.
string getPath(const string &pathFilename)
Returns the path w. '\' of path-filename string.
Definition: Utils.cpp:392

◆ removeComments()

SLstring SLGLShader::removeComments ( SLstring  src)
static

SLGLShader::removeComments for C/C++ comments removal from shader code.

Definition at line 201 of file SLGLShader.cpp.

202 {
203  SLstring dst;
204  SLuint len = (SLuint)src.length();
205  SLuint i = 0;
206  SLint column = 0;
207 
208  while (i < len)
209  {
210  if (src[i] == '/' && src[i + 1] == '/')
211  {
212  if (column > 0)
213  dst += '\n';
214  while (i < len && src[i] != '\n')
215  i++;
216  i++;
217  }
218  else if (src[i] == '/' && src[i + 1] == '*')
219  {
220  while (i < len && !(src[i] == '*' && src[i + 1] == '/'))
221  {
222  if (src[i] == '\n') dst += '\n';
223  i++;
224  }
225  i += 2;
226  }
227  else
228  {
229  if (src[i] == '\n')
230  column = 0;
231  else
232  column++;
233 
234  dst += src[i++];
235  }
236  }
237  return dst;
238 }
unsigned int SLuint
Definition: SL.h:171

◆ shaderID()

SLuint SLGLShader::shaderID ( ) const
inline

Definition at line 41 of file SLGLShader.h.

41 { return _shaderID; }

◆ type()

SLShaderType SLGLShader::type ( )
inline

Definition at line 40 of file SLGLShader.h.

40 { return _type; }

◆ typeName()

SLstring SLGLShader::typeName ( )

Returns the shader type as string.

Definition at line 241 of file SLGLShader.cpp.

242 {
243  switch (_type)
244  {
245  case ST_vertex: return "Vertex";
246  case ST_fragment: return "Fragment";
247  case ST_geometry: return "Geometry";
248  case ST_tesselation: return "Tesselation";
249  default: return "Unknown";
250  }
251 }
@ ST_tesselation
Definition: SLEnums.h:227

Friends And Related Function Documentation

◆ SLGLProgram

friend class SLGLProgram
friend

Definition at line 26 of file SLGLShader.h.

Member Data Documentation

◆ _code

SLstring SLGLShader::_code
protected

ASCII Source-Code.

Definition at line 56 of file SLGLShader.h.

◆ _file

SLstring SLGLShader::_file
protected

Path & filename of shader.

Definition at line 57 of file SLGLShader.h.

◆ _shaderID

SLuint SLGLShader::_shaderID
protected

Program Object.

Definition at line 55 of file SLGLShader.h.

◆ _type

SLShaderType SLGLShader::_type
protected

Shader type enumeration.

Definition at line 54 of file SLGLShader.h.


The documentation for this class was generated from the following files: