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