1 #ifndef SHADER_COMMON_H
2 #define SHADER_COMMON_H
3 
4 #include "resource.h"
5 #include "regex.h"
6 #include "vectors.h"
7 
8 #include <map>
9 #include <list>
10 #include <string>
11 #include <exception>
12 #include <vector>
13 
14 extern std::string gSDLAppShaderDir;
15 
16 enum { SHADER_UNIFORM_FLOAT,
17        SHADER_UNIFORM_BOOL,
18        SHADER_UNIFORM_SAMPLER_1D,
19        SHADER_UNIFORM_SAMPLER_2D,
20        SHADER_UNIFORM_INT,
21        SHADER_UNIFORM_VEC2,
22        SHADER_UNIFORM_VEC3,
23        SHADER_UNIFORM_VEC4,
24        SHADER_UNIFORM_MAT3,
25        SHADER_UNIFORM_MAT4,
26        SHADER_UNIFORM_VEC2_ARRAY,
27        SHADER_UNIFORM_VEC3_ARRAY,
28        SHADER_UNIFORM_VEC4_ARRAY
29 };
30 
31 extern Regex Shader_pre_version;
32 extern Regex Shader_pre_extension;
33 extern Regex Shader_pre_include;
34 extern Regex Shader_uniform_def;
35 extern Regex Shader_error_line;
36 extern Regex Shader_error2_line;
37 extern Regex Shader_error3_line;
38 extern Regex Shader_warning_line;
39 extern Regex Shader_redefine_line;
40 
41 class ShaderException : public std::exception {
42 protected:
43     std::string message;
44     std::string source;
45 public:
46     ShaderException(const std::string& message);
47     ShaderException(const std::string& message, const std::string& source);
48 
throw()49     ~ShaderException() throw () {};
50 
what()51     virtual const char* what() const throw() { return message.c_str(); }
52 
53     const std::string& getSource() const;
54 };
55 
56 class AbstractShader;
57 
58 class ShaderUniform {
59 protected:
60     std::string name;
61     std::string comment;
62     int  location;
63     AbstractShader* shader;
64     int uniform_type;
65     std::string type_name;
66     bool modified;
67     bool initialized;
68     bool baked;
69 public:
70 
71     ShaderUniform(AbstractShader* shader, const std::string& name, int uniform_type, const std::string& type_name);
~ShaderUniform()72     virtual ~ShaderUniform() {};
73 
74     virtual void unload();
75 
76     int getLocation();
77 
getType()78     int getType() { return uniform_type; };
79 
write(std::string & content)80     virtual void write(std::string& content) const {};
81 
82     const std::string& getName() const;
isInitialized()83     bool  isInitialized() const { return initialized; };
84 
isBaked()85     bool isBaked() const    { return baked; };
isModified()86     bool isModified() const { return modified; };
87 
88     void setComment(const std::string& comment);
89     const std::string& getComment() const;
90 
setInitialized(bool initialized)91     void setInitialized(bool initialized) { this->initialized = initialized; };
92 
93     virtual void setBaked(bool baked);
setModified(bool modified)94     virtual void setModified(bool modified) { this->modified = modified; };
95 };
96 
97 class FloatShaderUniform : public ShaderUniform {
98     float value;
99 public:
100     FloatShaderUniform(AbstractShader* shader, const std::string& name, float value = 0.0f);
101 
102     void write(std::string& content) const;
103 
104     void setValue(float value);
105 
106     float& getValue();
107 };
108 
109 class IntShaderUniform : public ShaderUniform {
110     int value;
111 public:
112     IntShaderUniform(AbstractShader* shader, const std::string& name, int value = 0);
113 
114     void write(std::string& content) const;
115 
116     void setValue(int value);
117 
118     int& getValue();
119 };
120 
121 class BoolShaderUniform : public ShaderUniform {
122     bool value;
123 public:
124     BoolShaderUniform(AbstractShader* shader, const std::string& name, bool value = false);
125 
126     void write(std::string& content) const;
127 
128     void setValue(bool value);
129 
130     bool& getValue();
131 };
132 
133 class Sampler1DShaderUniform : public ShaderUniform {
134     int value;
135 public:
136     Sampler1DShaderUniform(AbstractShader* shader, const std::string& name, int value = 0);
137 
138     void write(std::string& content) const;
139 
140     void setBaked(bool baked);
141 
142     void setValue(int value);
143 
144     int& getValue();
145 };
146 
147 class Sampler2DShaderUniform : public ShaderUniform {
148     int value;
149 public:
150     Sampler2DShaderUniform(AbstractShader* shader, const std::string& name, int value = 0);
151 
152     void write(std::string& content) const;
153 
154     void setBaked(bool baked);
155 
156     void setValue(int value);
157 
158     int& getValue();
159 };
160 
161 class Vec2ShaderUniform : public ShaderUniform {
162     vec2 value;
163 public:
164     Vec2ShaderUniform(AbstractShader* shader, const std::string& name, const vec2& value = vec2(0.0f)) ;
165 
166     void write(std::string& content) const;
167 
168     void setValue(const vec2& value);
169 
170     vec2& getValue();
171 };
172 
173 class Vec3ShaderUniform : public ShaderUniform {
174     vec3 value;
175 public:
176     Vec3ShaderUniform(AbstractShader* shader, const std::string& name, const vec3& value = vec3(0.0f));
177 
178     void write(std::string& content) const;
179 
180     void setValue(const vec3& value);
181 
182     vec3& getValue();
183 };
184 
185 class Vec4ShaderUniform : public ShaderUniform {
186     vec4 value;
187 public:
188     Vec4ShaderUniform(AbstractShader* shader, const std::string& name, const vec4& value = vec4(0.0f));
189 
190     void write(std::string& content) const;
191 
192     void setValue(const vec4& value);
193 
194     vec4& getValue();
195 };
196 
197 class Mat3ShaderUniform : public ShaderUniform {
198     mat3 value;
199 public:
200     Mat3ShaderUniform(AbstractShader* shader, const std::string& name, const mat3& value = mat3(1.0f));
201 
202     void write(std::string& content) const;
203 
204     void setValue(const mat3& value);
205 
206     mat3& getValue();
207 };
208 
209 class Mat4ShaderUniform : public ShaderUniform {
210     mat4 value;
211 public:
212     Mat4ShaderUniform(AbstractShader* shader, const std::string& name, const mat4& value = mat4(1.0f));
213 
214     void write(std::string& content) const;
215 
216     void setValue(const mat4& value);
217 
218     mat4& getValue();
219 };
220 
221 class Vec2ArrayShaderUniform : public ShaderUniform {
222     std::vector<vec2> value;
223     size_t length;
224 
225     void copyValue(const vec2* value);
226     void copyValue(const std::vector<vec2>& value);
227 public:
228     Vec2ArrayShaderUniform(AbstractShader* shader, const std::string& name, size_t length, const vec2* value = 0);
229     ~Vec2ArrayShaderUniform();
230 
231     void write(std::string& content) const;
232 
233     void setValue(const vec2* value);
234     void setValue(const std::vector<vec2>& value);
235 
236     const std::vector<vec2>& getValue();
237 
238     size_t getLength() const;
239 };
240 
241 class Vec3ArrayShaderUniform : public ShaderUniform {
242     std::vector<vec3> value;
243     size_t length;
244 
245     void copyValue(const vec3* value);
246     void copyValue(const std::vector<vec3>& value);
247 public:
248     Vec3ArrayShaderUniform(AbstractShader* shader, const std::string& name, size_t length, const vec3* value = 0);
249     ~Vec3ArrayShaderUniform();
250 
251     void write(std::string& content) const;
252 
253     void setValue(const vec3* value);
254     void setValue(const std::vector<vec3>& value);
255 
256     const std::vector<vec3>& getValue();
257 
258     size_t getLength() const;
259 };
260 
261 class Vec4ArrayShaderUniform : public ShaderUniform {
262     std::vector<vec4> value;
263     size_t length;
264 
265     void copyValue(const vec4* value);
266     void copyValue(const std::vector<vec4>& value);
267 public:
268     Vec4ArrayShaderUniform(AbstractShader* shader, const std::string& name, size_t length, const vec4* value = 0);
269     ~Vec4ArrayShaderUniform();
270 
271     void write(std::string& content) const;
272 
273     void setValue(const vec4* value);
274     void setValue(const std::vector<vec4>& value);
275 
276     const std::vector<vec4>& getValue();
277 
278     size_t getLength() const;
279 };
280 
281 class ShaderPart {
282 
283     std::string filename;
284 
285     std::string raw_source;
286     std::string processed_source;
287 
288     std::map<std::string,std::string> defines;
289     std::map<std::string,std::string> substitutions;
290 
291     void preprocess();
292     void loadSourceFile();
293 
294     void applySubstitution(std::string& source, const std::string& name, const std::string& value);
295 
296     void applyDefines(std::string& source);
297     void applySubstitutions(std::string& source);
298 public:
299     ShaderPart();
300 
301     void setSourceFile(const std::string& filename);
302     void setSource(const std::string& source);
303 
304     void reload();
305     void reset();
306 
307     void substitute(const std::string& name, const char *value, ...);
308     void substitute(const std::string& name, const std::string& value);
309 
310     void define(const std::string& name);
311     void define(const std::string& name, const char *value, ...);
312     void define(const std::string& name, const std::string& value);
313 
314     const std::string& getSource();
315 };
316 
317 class AbstractShaderPass {
318 protected:
319     int          shader_object_type;
320     std::string  shader_object_desc;
321     unsigned int shader_object;
322 
323     int version;
324     std::map<std::string,std::string> extensions;
325 
326     AbstractShader* parent;
327 
328     std::string source;
329     std::string shader_object_source;
330 
331     std::list<ShaderUniform*> uniforms;
332 
333     void showContext(std::string& context, int line_no, int amount);
334     bool errorContext(const char* log_message, std::string& context);
335 
336     bool preprocess(const std::string& line);
337 public:
338     AbstractShaderPass(AbstractShader* parent, int shader_object_type, const std::string& shader_object_desc);
~AbstractShaderPass()339     virtual ~AbstractShaderPass() {};
340 
getType()341     int getType() { return shader_object_type; };
342 
343     bool isEmpty();
344 
345     void toString(std::string& out);
346     const std::string& getObjectSource();
347 
348     ShaderUniform* addArrayUniform(const std::string& name, const std::string& type, size_t length);
349     ShaderUniform* addUniform(const std::string& name, const std::string& type);
350 
351     void includeSource(const std::string& source);
352     void includeFile(const std::string& filename);
353 
354     std::list<ShaderUniform*>& getUniforms();
355 
356     virtual void attachTo(unsigned int program) = 0;
357     virtual void unload() = 0;
358     virtual void compile() = 0;
359     virtual void checkError() = 0;
360 
361 };
362 
363 class AbstractShader : public Resource {
364 protected:
365     std::map<std::string, ShaderUniform*>  uniforms;
366     std::list<ShaderUniform*> uniform_list;
367     std::map<std::string,std::string> substitutions;
368 
369     std::string prefix;
370     unsigned int program;
371     bool dynamic_compile;
372 
373     void setDefaults();
374 
375     virtual void loadPrefix() = 0;
376     virtual void checkProgramError() = 0;
377 public:
378     AbstractShaderPass* vertex_shader;
379     AbstractShaderPass* geometry_shader;
380     AbstractShaderPass* fragment_shader;
381 
382     AbstractShader();
383     AbstractShader(const std::string& prefix);
384 
385     unsigned int getProgram();
386 
387     void clear();
388 
389     void reload(bool force = false);
390 
391     bool isEmpty();
392 
393     void includeSource(unsigned int shader_object_type, const std::string& source);
394     void includeFile(unsigned int shader_object_type,   const std::string& filename);
395 
396     static void substitute(std::string& source, const std::string& name, const std::string& value);
397 
398     void addSubstitute(const std::string& name, const std::string& value);
399     void addSubstitute(const std::string& name, const char *value, ...);
400 
401     void applySubstitutions(std::string& source);
402 
403     void addUniform(ShaderUniform* uniform);
404     ShaderUniform* getUniform(const std::string& name);
405 
406     void setDynamicCompile(bool dynamic_compile);
407     bool needsCompile();
408 
409     const std::list<ShaderUniform*>& getUniforms();
410 
411     void applyUniforms();
412 
413     void setBool(const std::string& name, bool value);
414     void setInteger (const std::string& name, int value);
415     void setSampler1D(const std::string& name, int value);
416     void setSampler2D(const std::string& name, int value);
417     void setFloat(const std::string& name, float value);
418     void setVec2 (const std::string& name, const vec2& value);
419     void setVec3 (const std::string& name, const vec3& value);
420     void setVec4 (const std::string& name, const vec4& value);
421     void setMat3 (const std::string& name, const mat3& value);
422     void setMat4 (const std::string& name, const mat4& value);
423 
424     void setVec2Array(const std::string& name, vec2* value);
425     void setVec2Array(const std::string& name, std::vector<vec2>& value);
426 
427     void setVec3Array(const std::string& name, vec3* value);
428     void setVec3Array(const std::string& name, std::vector<vec3>& value);
429 
430     void setVec4Array(const std::string& name, vec4* value);
431     void setVec4Array(const std::string& name, std::vector<vec4>& value);
432 
433     void setBaked(const std::string& name, bool baked);
434     void setBakedUniforms(bool baked);
435 
436     virtual AbstractShaderPass* grabShaderPass(unsigned int shader_object_type) = 0;
437 
438     virtual void applyUniform(ShaderUniform* u) = 0;
439 
440     virtual int getUniformLocation(const std::string& uniform_name) = 0;
441 
442     virtual void load() = 0;
443     virtual void unload() = 0;
444 
445     virtual void bind() = 0;
446     virtual void unbind() = 0;
447 
448     void use();
449 };
450 
451 #endif
452