OSDN Git Service

5e63b4ff654e163fe0edf56e419379270bca89fe
[psychlops/cpp.git] / psychlops / extension / standard / shader / psychlops_g_shader_fig.cpp
1 /*
2  *  psychlops_g_shader_fig.cpp
3  *  Psychlops Standard Library (Universal)
4  *
5  *  Last Modified 2009/12/14 by Kenchi HOSOKAWA
6  *  (C) 2009 Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
7  */
8
9 #include <iostream>
10 #include <fstream>
11 #include "../../../core/ApplicationInterfaces/psychlops_app_info.h"
12 #include "psychlops_g_shader_fig.h"
13
14
15 namespace Psychlops {
16
17                 void ShaderInterface::reparseGLSL1_1(const std::string &source, std::string &result, std::vector<std::string> &args)
18                 {
19                         int main_i, after_main_i, in_i, in_finish_i;
20                         main_i = source.find("void main");
21                         std::string argstr, argtmp;
22                         int begin=0, len;
23                         args.clear();
24                         if( main_i != std::string::npos ) {
25                                 after_main_i = source.find_first_of("{", main_i );
26                                 in_i = source.find("in float ");
27                                 if( in_i != std::string::npos && in_i<main_i ) {
28                                         in_finish_i = source.find_first_of(";", in_i );
29                                         argstr = source.substr(in_i+9, in_finish_i-(in_i+9)+1);
30                                         for(int i=0; i<argstr.length(); i++) {
31                                                 if(argstr[i]==',' || argstr[i]==';') {
32                                                         len = i-begin;
33                                                         argtmp = argstr.substr(begin, len);
34                                                         args.push_back(argtmp);
35                                                         begin = i+1;
36                                                 }
37                                         }
38                                         result = "";
39                                         std::stringstream ss;
40                                         ss << source.substr(0, in_i);
41                                         ss << source.substr(in_finish_i+1, after_main_i-in_finish_i) << std::endl;
42                                         if(!args.empty()) {
43                                                 ss << "\tfloat ";
44                                                 for(int i=0; i<args.size(); i++) {
45                                                         ss << args[i] << " = gl_TexCoord[" << i/4+4 << "][" << i%4 << "]";
46                                                         if(i<args.size()-1) ss << ", ";
47                                                 }
48                                                 ss << ";" << std::endl;
49                                         }
50                                         ss << source.substr(after_main_i+1);
51                                         result.assign(ss.str());
52                                         return;
53                                 }
54                         }
55                         result.assign(source);
56                 }
57
58 namespace Internal
59 {
60         std::string error_message;
61         void loadGLSL(std::stringstream &buf, const std::string path)
62         {
63                 char one;
64                 std::ifstream is;
65                 is.open(path.c_str(), std::ifstream::in);
66                 if(is.fail()) {
67                         AppState::alert("Shader: File was not found, or failed to read for some reasons.");
68                         return;
69                 }
70                 while(is.good()) {
71                         is.get(one);
72                         buf << one;
73                 }
74         }
75
76         void logError()
77         {
78                 std::ofstream os;
79                 os.open("GLSLErrorLog.txt");
80                 if(os.fail()) {
81                         AppState::alert("Shader: error log file was not found, or failed to read for some reasons.");
82                         return;
83                 }
84                 os << error_message;
85         }
86 }
87
88 namespace Figures {
89
90
91         ShaderImage::~ShaderImage()
92         {
93         }
94         ShaderImage::ShaderImage()
95         : api() {
96                 initialized = false;
97                 setBase();
98                 orig_source =
99                 "void main(void){ "
100                 "gl_FragColor = getPix(); }";
101                 arg_tmp[0] = 0; arg_tmp[1] = 0; arg_tmp[2] = 0; arg_tmp[3] = 0;
102                 arg_tmp[4] = 0; arg_tmp[5] = 0; arg_tmp[6] = 0; arg_tmp[7] = 0;
103                 arg_tmp[8] = 0; arg_tmp[9] = 0; arg_tmp[10]= 0; arg_tmp[11]= 0;
104                 arg_tmp[12]= 0; arg_tmp[13]= 0; arg_tmp[14]= 0; arg_tmp[15]= 0;
105         }
106         void ShaderImage::setBase()
107         {
108         }
109         void ShaderImage::setFunction(const char *source, ShaderInterface::Version reparse)
110         {
111                 std::string tmp(source);
112                 setFunction(tmp);
113         }
114         void ShaderImage::setFunction(const std::string &source, ShaderInterface::Version reparse)
115         {
116                 switch(reparse) {
117                 case ShaderInterface::AUTO_DETECT:
118                 case ShaderInterface::GLSL1_1:
119                         ShaderInterface::reparseGLSL1_1(source, orig_source, orig_args);
120                         break;
121                 default:
122                         orig_source = source;
123                         break;
124                 }
125         }
126         void ShaderImage::argf(
127                 double  a0, double  a1, double  a2, double  a3,
128                 double  a4, double  a5, double  a6, double  a7,
129                 double  a8, double  a9, double a10, double a11,
130                 double a12, double a13, double a14, double a15
131         )
132         {
133                 arg_tmp[0] =  a0; arg_tmp[1] =  a1; arg_tmp[2] =  a2; arg_tmp[3] =  a3;
134                 arg_tmp[4] =  a4; arg_tmp[5] =  a5; arg_tmp[6] =  a6; arg_tmp[7] =  a7;
135                 arg_tmp[8] =  a8; arg_tmp[9] =  a9; arg_tmp[10]= a10; arg_tmp[11]= a11;
136                 arg_tmp[12]= a12; arg_tmp[13]= a13; arg_tmp[14]= a14; arg_tmp[15]= a15;
137         }
138
139         void ShaderImage::cache(DrawableWithCache &target)
140         {
141                 api.cacheTex(orig_source, orig_args, target);
142         }
143         void ShaderImage::cache(const char *source, DrawableWithCache &target)
144         {
145                 if(!initialized && &target!=0) {
146                         setFunction(source);
147                         cache(target);
148                         initialized = true;
149                 }
150         }
151         void ShaderImage::cacheFromFile(const std::string path, DrawableWithCache &target)
152         {
153                 std::stringstream buf;
154                 Internal::loadGLSL(buf, path);
155                 Internal::error_message.clear();
156                 try{
157                         setFunction(buf.str().c_str());
158                         cache(*Display::the_canvas);
159                 } catch (Exception e) {
160                         Internal::error_message = e.getErrorString();
161                         Internal::logError();
162                 } catch (Exception *e) {
163                         Internal::error_message = e->getErrorString();
164                         Internal::logError();
165                 }
166         }
167         ShaderImage& ShaderImage::draw(Image &img, const double* argv, const int argn, Canvas &target)
168         {
169                 //if() cache(target);
170                 api.drawImage(img, argv, argn, target);
171                 return *this;
172         }
173         void ShaderImage::to(Image &dest, Image &img, const double* argv, const int argn, Canvas &media)
174         {
175                 Point tmp = img.getDatum();
176                 api.imageToImage(dest, img, argv, argn, media);
177                 img.setDatum(tmp);
178         }
179         ShaderImage& ShaderImage::draw(Image &img, Canvas &target)
180         {
181                 return draw(img, arg_tmp, 4, target);
182         }
183         void ShaderImage::to(Image &dest, Image &img, Canvas &media)
184         {
185                 to(dest, img, arg_tmp, 4, media);
186         }
187 \r
188 \r
189         void ShaderImage2::cache(DrawableWithCache &target)\r
190         {\r
191                 api.cacheTex(orig_source, orig_args, target, 1);\r
192         }\r
193         ShaderImage2& ShaderImage2::draw(Image &img, const double* argv, const int argn, Canvas &target)\r
194         {\r
195                 //if() cache(target);\r
196                 api.drawImage(img, argv, argn, params, target);\r
197                 return *this;\r
198         }\r
199 \r
200
201
202         ShaderField::~ShaderField()
203         {
204         }
205         ShaderField::ShaderField()
206         : api() {
207                 initialized = false;
208                 setBase();
209                 orig_source =
210                 "void main(void){ "
211                 "pix(vec4(0.0, 0.0, 1.0, 0.5)); }";
212                 arg_tmp[0] = 0; arg_tmp[1] = 0; arg_tmp[2] = 0; arg_tmp[3] = 0;
213                 arg_tmp[4] = 0; arg_tmp[5] = 0; arg_tmp[6] = 0; arg_tmp[7] = 0;
214                 arg_tmp[8] = 0; arg_tmp[9] = 0; arg_tmp[10]= 0; arg_tmp[11]= 0;
215                 arg_tmp[12]= 0; arg_tmp[13]= 0; arg_tmp[14]= 0; arg_tmp[15]= 0;
216         }
217         void ShaderField::setBase()
218         {
219         }
220         void ShaderField::setFunction(const char* source, ShaderInterface::Version reparse)
221         {
222                 std::string tmp(source);
223                 setFunction(tmp);
224         }
225         void ShaderField::setFunction(const std::string &source, ShaderInterface::Version reparse)
226         {
227                 switch(reparse) {
228                 case ShaderInterface::AUTO_DETECT:
229                 case ShaderInterface::GLSL1_1:
230                         ShaderInterface::reparseGLSL1_1(source, orig_source, orig_args);
231                         break;
232                 default:
233                         orig_source = source;
234                         break;
235                 }
236         }
237         void ShaderField::argf(
238                 double  a0, double  a1, double  a2, double  a3,
239                 double  a4, double  a5, double  a6, double  a7,
240                 double  a8, double  a9, double a10, double a11,
241                 double a12, double a13, double a14, double a15
242         )
243         {
244                 arg_tmp[0] =  a0; arg_tmp[1] =  a1; arg_tmp[2] =  a2; arg_tmp[3] =  a3;
245                 arg_tmp[4] =  a4; arg_tmp[5] =  a5; arg_tmp[6] =  a6; arg_tmp[7] =  a7;
246                 arg_tmp[8] =  a8; arg_tmp[9] =  a9; arg_tmp[10]= a10; arg_tmp[11]= a11;
247                 arg_tmp[12]= a12; arg_tmp[13]= a13; arg_tmp[14]= a14; arg_tmp[15]= a15;
248         }
249         void ShaderField::cache(DrawableWithCache &target)
250         {
251                 api.cacheField(orig_source, orig_args, target);
252         }
253         void ShaderField::cache(const char *source, DrawableWithCache &target)
254         {
255                 if(!initialized && &target!=0) {
256                         setFunction(source);
257                         cache(target);
258                         initialized = true;
259                 }
260         }
261         void ShaderField::cacheFromFile(const std::string path, DrawableWithCache &target)
262         {
263                 std::stringstream buf;
264                 Internal::loadGLSL(buf, path);
265                 Internal::error_message.clear();
266                 try{
267                         setFunction(buf.str().c_str());
268                         cache(*Display::the_canvas);
269                 } catch (Exception e) {
270                         Internal::error_message = e.getErrorString();
271                         Internal::logError();
272                 } catch (Exception *e) {
273                         Internal::error_message = e->getErrorString();
274                         Internal::logError();
275                 }
276         }
277         void ShaderField::draw(const Rectangle &rect, const double* argv, const int argn, Drawable &target)
278         {
279                 api.drawField(rect, argv, argn);
280         }
281         void ShaderField::to(Image &dest, const Rectangle &rect, const double* argv, const int argn, Canvas &media)
282         {
283                 api.fieldToImage(dest, rect, argv, argn, media);
284         }
285         void ShaderField::draw(const Rectangle &rect, Drawable &target)
286         {
287                 api.drawField(rect, arg_tmp, 4);
288         }
289         void ShaderField::to(Image &dest, const Rectangle &rect, Canvas &media)
290         {
291                 api.fieldToImage(dest, rect, arg_tmp, 4, media);
292         }
293
294
295
296         ShaderCoordinateTuner::ShaderCoordinateTuner()
297         {
298                 cache();
299                 set(256*pixel, 256*pixel);
300         }
301         ShaderCoordinateTuner& ShaderCoordinateTuner::cache(DrawableWithCache &target)
302         {
303                 field.cache(glsl_source, target);
304                 return *this;
305         }
306         ShaderCoordinateTuner& ShaderCoordinateTuner::draw(Canvas &target)
307         {
308                 cache(target);
309                 const double Z[4] = { 0,0,0,0 };
310                 field.draw(*this, Z, 0, target);
311                 return *this;
312         }
313         void ShaderCoordinateTuner::to(Image &dest, Canvas &media)
314         {
315                 cache(media);
316                 const double Z[4] = { 0,0,0,0 };
317                 field.to(dest, *this, Z, 0, media);
318         }
319         ShaderField ShaderCoordinateTuner::field;
320         const char *ShaderCoordinateTuner::glsl_source =
321                         "void main(void){ "
322                         "float r = floor(abs(gl_TexCoord[0][0]))/255.0;"
323                         "float g = fract(abs(gl_TexCoord[0][0]));"
324                         "pix( r, g, 0.0); }";
325
326
327
328         ShaderGrating::ShaderGrating()
329         {
330                 cache();
331                 set(10*pixel, 10*pixel);
332         }
333         ShaderGrating& ShaderGrating::setWave(double wavelen, double cont, double orient, double phs)
334         {
335                 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
336         }
337         ShaderGrating& ShaderGrating::setWave(Length wavelen, double cont, Angle orient, Angle phs)
338         {
339                 contrast = cont;
340                 wavelength = wavelen;
341                 orientation = orient;
342                 phase = phs;
343                 return *this;
344         }
345         ShaderGrating& ShaderGrating::cache(DrawableWithCache &target)
346         {
347                 field.cache(glsl_source, target);
348                 return *this;
349         }
350         ShaderGrating& ShaderGrating::draw(Drawable &target)
351         {
352                 cache();
353                 //const double Z[4] = { phase.at_degree(), contrast, orientation.at_degree(), PI/wavelength*getWidth() };
354                 const double Z[4] = { phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength };
355                 field.draw(*this, Z, 1, target);
356                 return *this;
357         }
358
359         void ShaderGrating::to(Image &dest, Canvas &media)
360         {
361                 cache(media);
362 //              const double Z[4] = { phase.at_degree(), contrast, orientation.at_degree(), PI/wavelength*getWidth() };
363                 const double Z[4] = { phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength };
364                 field.to(dest, *this, Z, 1, media);
365         }
366
367         ShaderField ShaderGrating::field;
368         const char *ShaderGrating::glsl_source =
369                         "void main(void){ "
370                         "float phase = gl_TexCoord[4][0], contrast = gl_TexCoord[4][1], orientation = gl_TexCoord[4][2], frequency = gl_TexCoord[4][3];"
371                         "float _x = sin(orientation)*xp()-cos(orientation)*yp();"
372                         "pix(0.5 + contrast*0.5*cos(frequency*_x + phase) ); }";
373
374
375         ShaderGaussianDot::ShaderGaussianDot()
376         {
377                 cache();
378                 bgcolor = Color::null_color;
379                 Rectangle::fill = Color::black;
380         }
381         ShaderGaussianDot& ShaderGaussianDot::setSigma(double sigma)
382         {
383                 Rectangle::set(sigma*8.0, sigma*8.0);
384                 return *this;
385         }
386         ShaderGaussianDot& ShaderGaussianDot::cache(DrawableWithCache &target)
387         {
388                 field.cache(glsl_source, target);
389                 return *this;
390         }
391         ShaderGaussianDot& ShaderGaussianDot::draw(Drawable &target)
392         {
393                 cache();
394                 const double Z[12] = {
395                         2.0/getWidth(), 0, 0, 0,
396                         Rectangle::fill.getR(), Rectangle::fill.getG(), Rectangle::fill.getB(), Rectangle::fill.getA(),
397                         bgcolor.getR(), bgcolor.getG(), bgcolor.getB(), bgcolor.getA()
398                 };
399                 field.draw(*this, Z, 3, target);
400                 return *this;
401         }
402         void ShaderGaussianDot::to(Image &dest, Canvas &media)
403         {
404                 cache(media);
405                 const double Z[12] = {
406                         2.0/getWidth(), 0, 0, 0,
407                         Rectangle::fill.getR(), Rectangle::fill.getG(), Rectangle::fill.getB(), Rectangle::fill.getA(),
408                         bgcolor.getR(), bgcolor.getG(), bgcolor.getB(), bgcolor.getA()
409                 };
410                 field.to(dest, *this, Z, 3, media);
411         }
412         ShaderField ShaderGaussianDot::field;
413         const char *ShaderGaussianDot::glsl_source =
414                         "void main(void) {"
415                         "float r = rp()*gl_TexCoord[4][0]*4.0;"
416                         "float r2 = -(r*r) / 2.0;"
417                         "vec4 env = mix(gl_TexCoord[6], gl_TexCoord[5], exp(r2));"
418                         "pix(env);"
419                         "}";
420
421
422         ShaderGabor::ShaderGabor()
423         {
424                 cache();
425                 set(10*pixel, 10*pixel);
426                 contrast = 1;
427                 wavelength = 5;
428                 orientation = 0;
429                 phase = 0;
430         }
431         ShaderGabor& ShaderGabor::setSigma(double sigma)
432         {
433                 return setSigma(sigma*pixel);
434         }
435         ShaderGabor& ShaderGabor::setSigma(Length sigma)
436         {
437                 Rectangle::set(sigma*8.0, sigma*8.0);
438                 return *this;
439         }
440         ShaderGabor& ShaderGabor::setWave(double wavelen, double cont, double orient, double phs)
441         {
442                 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
443         }
444         ShaderGabor& ShaderGabor::setWave(Length wavelen, double cont, Angle orient, Angle phs)
445         {
446                 contrast = cont;
447                 wavelength = wavelen;
448                 orientation = orient;
449                 phase = phs;
450                 return *this;
451         }
452
453         ShaderGabor& ShaderGabor::cache(DrawableWithCache &target)
454         {
455                 field.cache(glsl_source, target);
456                 return *this;
457         }
458         ShaderGabor& ShaderGabor::draw(Drawable &target)
459         {
460                 cache();
461                 const double Z[8] = { 2.0/getWidth(),0,0,0, phase, contrast, orientation, 2*PI/wavelength };
462                 field.draw(*this, Z, 2, target);
463                 return *this;
464         }
465         void ShaderGabor::to(Image &dest, Canvas &media)
466         {
467                 cache(media);
468                 const double Z[8] = { 2.0/getWidth(),0,0,0, phase, contrast, orientation, 2*PI/wavelength };
469                 field.to(dest, *this, Z, 2, media);
470         }
471
472         ShaderField ShaderGabor::field;
473         const char *ShaderGabor::glsl_source =
474                         "void main(void) {"
475                         "float _r = rp()*gl_TexCoord[4][0]*4.0;"
476                         "float env = exp( -(_r*_r) / 2.0 );"
477                         "float phase = gl_TexCoord[5][0], contrast = gl_TexCoord[5][1], orientation = gl_TexCoord[5][2], frequency = gl_TexCoord[5][3];"
478                         "float _x = sin(orientation)*xp()-cos(orientation)*yp();"
479                         //"float level = 0.5+contrast*0.5*cos(frequency*_x + phase);"
480                         //"pix(level,env);"
481                         "float level = 0.996078*(0.5+env*( contrast*0.5*cos(frequency*_x + phase) ));"
482                         "pix(level);"
483                         "}";
484 \r
485 \r
486 \r
487         ShaderGaborAlpha::ShaderGaborAlpha()\r
488         {\r
489                 cache();\r
490                 set(10*pixel, 10*pixel);\r
491                 contrast = 1;\r
492                 wavelength = 5;\r
493                 orientation = 0;\r
494                 alpha = 1.0;\r
495                 phase = 0;\r
496         }\r
497         ShaderGaborAlpha& ShaderGaborAlpha::setSigma(double sigma)\r
498         {\r
499                 return setSigma(sigma*pixel);\r
500         }\r
501         ShaderGaborAlpha& ShaderGaborAlpha::setSigma(Length sigma)\r
502         {\r
503                 Rectangle::set(sigma*8.0, sigma*8.0);\r
504                 return *this;\r
505         }\r
506         ShaderGaborAlpha& ShaderGaborAlpha::setWave(double wavelen, double cont, double orient, double phs)\r
507         {\r
508                 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);\r
509         }\r
510         ShaderGaborAlpha& ShaderGaborAlpha::setWave(Length wavelen, double cont, Angle orient, Angle phs)\r
511         {\r
512                 contrast = cont;\r
513                 wavelength = wavelen;\r
514                 orientation = orient;\r
515                 phase = phs;\r
516                 return *this;\r
517         }\r
518 \r
519         ShaderGaborAlpha& ShaderGaborAlpha::cache(DrawableWithCache &target)\r
520         {\r
521                 field.cache(glsl_source, target);\r
522                 return *this;\r
523         }\r
524         ShaderGaborAlpha& ShaderGaborAlpha::draw(Drawable &target)\r
525         {\r
526                 cache();\r
527                 const double Z[8] = { 2.0/getWidth(),alpha,0,0, phase, contrast, orientation, 2*PI/wavelength };\r
528                 field.draw(*this, Z, 2, target);\r
529                 return *this;\r
530         }\r
531         void ShaderGaborAlpha::to(Image &dest, Canvas &media)\r
532         {\r
533                 cache(media);\r
534                 const double Z[8] = { 2.0/getWidth(),alpha,0,0, phase, contrast, orientation, 2*PI/wavelength };\r
535                 field.to(dest, *this, Z, 2, media);\r
536         }\r
537 \r
538         ShaderField ShaderGaborAlpha::field;\r
539         const char *ShaderGaborAlpha::glsl_source =\r
540                         "void main(void) {"\r
541                         "float _r = rp()*gl_TexCoord[4][0]*4.0;"\r
542                         "float env = exp( -(_r*_r) / 2.0 ) * gl_TexCoord[4][1];"\r
543                         "float phase = gl_TexCoord[5][0], contrast = gl_TexCoord[5][1], orientation = gl_TexCoord[5][2], frequency = gl_TexCoord[5][3];"\r
544                         "float _x = sin(orientation)*xp()-cos(orientation)*yp();"\r
545                         "float level = 0.5+contrast*0.5*cos(frequency*_x + phase);"\r
546                         "pix(level,env);"\r
547                         "}";
548 \r
549 \r
550
551
552         ShaderPlaid::ShaderPlaid()
553         {
554                 cache();
555                 set(10*pixel, 10*pixel);
556         }
557         ShaderPlaid& ShaderPlaid::setSigma(double sigma)
558         {
559                 return setSigma(sigma*pixel);
560         }
561         ShaderPlaid& ShaderPlaid::setSigma(Length sigma)
562         {
563                 Rectangle::set(sigma*8.0, sigma*8.0);
564                 return *this;
565         }
566         ShaderPlaid& ShaderPlaid::setWave(double wavelen, double cont, double orient, double phs)
567         {
568                 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
569         }
570         ShaderPlaid& ShaderPlaid::setWave(Length wavelen, double cont, Angle orient, Angle phs)
571         {
572                 contrast = cont;
573                 wavelength = wavelen;
574                 orientation = orient;
575                 phase = phs;
576                 return *this;
577         }
578         ShaderPlaid& ShaderPlaid::setWave2(double wavelen, double cont, double orient, double phs)
579         {
580                 return setWave2(wavelen*pixel, cont, orient*degree, phs*degree);
581         }
582         ShaderPlaid& ShaderPlaid::setWave2(Length wavelen, double cont, Angle orient, Angle phs)
583         {
584                 contrast2 = cont;
585                 wavelength2 = wavelen;
586                 orientation2 = orient;
587                 phase2 = phs;
588                 return *this;
589         }
590         ShaderPlaid& ShaderPlaid::cache(DrawableWithCache &target)
591         {
592                 field.cache(glsl_source, target);
593                 return *this;
594         }
595         ShaderPlaid& ShaderPlaid::draw(Drawable &target)
596         {
597                 cache();
598                 const double Z[12] =
599                 {
600                         2.0/getWidth(),0,0,0,
601                         phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength,
602                         phase2.at_degree(), contrast2, orientation2.at_degree(), 2*PI/wavelength2
603                 };
604                 field.draw(*this, Z, 3, target);
605                 return *this;
606         }
607
608         void ShaderPlaid::to(Image &dest, Canvas &media)
609         {
610                 cache(media);
611                 const double Z[12] =
612                 {
613                         2.0/getWidth(),0,0,0,
614                         phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength,
615                         phase2.at_degree(), contrast2, orientation2.at_degree(), 2*PI/wavelength2
616                 };
617                 field.to(dest, *this, Z, 3, media);
618         }
619
620         ShaderField ShaderPlaid::field;
621         const char *ShaderPlaid::glsl_source =
622                         "void main(void) {"
623                         "float phase = gl_TexCoord[5][0], contrast = gl_TexCoord[5][1], orientation = gl_TexCoord[5][2], frequency = gl_TexCoord[5][3];"
624                         "float phase2 = gl_TexCoord[6][0], contrast2 = gl_TexCoord[6][1], orientation2 = gl_TexCoord[6][2], frequency2 = gl_TexCoord[6][3];"
625                         "float _x  = sin(orientation)*xp()-cos(orientation)*yp();"
626                         "float _x2 = sin(orientation2)*xp()-cos(orientation2)*yp();"
627                         "float _r = rp()*gl_TexCoord[4][0]*4.0;"
628                         "float env = exp( -(_r*_r) / 2.0 );"
629                         "float level = 0.996078*(0.5+env*( contrast*0.5*cos(frequency*_x + phase) + contrast2*0.5*cos(frequency2*_x2 + phase2) ));"
630                         "pix(level);"
631                         //"float level = 0.5 + contrast*0.5*cos(frequency*_x + phase) + contrast2*0.5*cos(frequency2*_x2 + phase2);"
632                         //"pix(level, level, level, env);"
633                         "}";
634
635 \r
636 \r
637         ShaderPlaidAlpha::ShaderPlaidAlpha()\r
638         {\r
639                 cache();\r
640                 set(10*pixel, 10*pixel);\r
641                 alpha = 1.0;\r
642         }\r
643         ShaderPlaidAlpha& ShaderPlaidAlpha::setSigma(double sigma)\r
644         {\r
645                 return setSigma(sigma*pixel);\r
646         }\r
647         ShaderPlaidAlpha& ShaderPlaidAlpha::setSigma(Length sigma)\r
648         {\r
649                 Rectangle::set(sigma*8.0, sigma*8.0);\r
650                 return *this;\r
651         }\r
652         ShaderPlaidAlpha& ShaderPlaidAlpha::setWave(double wavelen, double cont, double orient, double phs)\r
653         {\r
654                 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);\r
655         }\r
656         ShaderPlaidAlpha& ShaderPlaidAlpha::setWave(Length wavelen, double cont, Angle orient, Angle phs)\r
657         {\r
658                 contrast = cont;\r
659                 wavelength = wavelen;\r
660                 orientation = orient;\r
661                 phase = phs;\r
662                 return *this;\r
663         }\r
664         ShaderPlaidAlpha& ShaderPlaidAlpha::setWave2(double wavelen, double cont, double orient, double phs)\r
665         {\r
666                 return setWave2(wavelen*pixel, cont, orient*degree, phs*degree);\r
667         }\r
668         ShaderPlaidAlpha& ShaderPlaidAlpha::setWave2(Length wavelen, double cont, Angle orient, Angle phs)\r
669         {\r
670                 contrast2 = cont;\r
671                 wavelength2 = wavelen;\r
672                 orientation2 = orient;\r
673                 phase2 = phs;\r
674                 return *this;\r
675         }\r
676         ShaderPlaidAlpha& ShaderPlaidAlpha::cache(DrawableWithCache &target)\r
677         {\r
678                 field.cache(glsl_source, target);\r
679                 return *this;\r
680         }\r
681         ShaderPlaidAlpha& ShaderPlaidAlpha::draw(Drawable &target)\r
682         {\r
683                 cache();\r
684                 const double Z[12] =\r
685                 {\r
686                         2.0/getWidth(),alpha,0,0,\r
687                         phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength,\r
688                         phase2.at_degree(), contrast2, orientation2.at_degree(), 2*PI/wavelength2\r
689                 };\r
690                 field.draw(*this, Z, 3, target);\r
691                 return *this;\r
692         }\r
693 \r
694         void ShaderPlaidAlpha::to(Image &dest, Canvas &media)\r
695         {\r
696                 cache(media);\r
697                 const double Z[12] =\r
698                 {\r
699                         2.0/getWidth(),alpha,0,0,\r
700                         phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength,\r
701                         phase2.at_degree(), contrast2, orientation2.at_degree(), 2*PI/wavelength2\r
702                 };\r
703                 field.to(dest, *this, Z, 3, media);\r
704         }\r
705 \r
706         ShaderField ShaderPlaidAlpha::field;\r
707         const char *ShaderPlaidAlpha::glsl_source =\r
708                         "void main(void) {"\r
709                         "float phase = gl_TexCoord[5][0], contrast = gl_TexCoord[5][1], orientation = gl_TexCoord[5][2], frequency = gl_TexCoord[5][3];"\r
710                         "float phase2 = gl_TexCoord[6][0], contrast2 = gl_TexCoord[6][1], orientation2 = gl_TexCoord[6][2], frequency2 = gl_TexCoord[6][3];"\r
711                         "float _x  = sin(orientation)*xp()-cos(orientation)*yp();"\r
712                         "float _x2 = sin(orientation2)*xp()-cos(orientation2)*yp();"\r
713                         "float _r = rp()*gl_TexCoord[4][0]*4.0;"\r
714                         "float env = exp( -(_r*_r) / 2.0 ) * gl_TexCoord[4][1];"\r
715                         //"float level = 0.996078*(0.5+env*( contrast*0.5*cos(frequency*_x + phase) + contrast2*0.5*cos(frequency2*_x2 + phase2) ));"\r
716                         //"pix(level);"\r
717                         "float level = 0.5 + contrast*0.5*cos(frequency*_x + phase) + contrast2*0.5*cos(frequency2*_x2 + phase2);"\r
718                         "pix(level, level, level, env);"\r
719                         "}";\r
720 \r
721
722 }       /*      <- namespace Figures    */
723 }       /*      <- namespace Psycholops         */
724