2 * psychlops_g_shader_fig.cpp
3 * Psychlops Standard Library (Universal)
5 * Last Modified 2009/12/14 by Kenchi HOSOKAWA
6 * (C) 2009 Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
11 #include "../../../core/ApplicationInterfaces/psychlops_app_info.h"
12 #include "psychlops_g_shader_fig.h"
17 void ShaderInterface::reparseGLSL1_1(const std::string &source, std::string &result, std::vector<std::string> &args)
19 int main_i, after_main_i, in_i, in_finish_i;
20 main_i = source.find("void main");
21 std::string argstr, argtmp;
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]==';') {
33 argtmp = argstr.substr(begin, len);
34 args.push_back(argtmp);
40 ss << source.substr(0, in_i);
41 ss << source.substr(in_finish_i+1, after_main_i-in_finish_i) << std::endl;
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 << ", ";
48 ss << ";" << std::endl;
50 ss << source.substr(after_main_i+1);
51 result.assign(ss.str());
55 result.assign(source);
60 std::string error_message;
61 void loadGLSL(std::stringstream &buf, const std::string path)
65 is.open(path.c_str(), std::ifstream::in);
67 AppState::alert("Shader: File was not found, or failed to read for some reasons.");
79 os.open("GLSLErrorLog.txt");
81 AppState::alert("Shader: error log file was not found, or failed to read for some reasons.");
91 ShaderImage::~ShaderImage()
94 ShaderImage::ShaderImage()
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;
106 void ShaderImage::setBase()
109 void ShaderImage::setFunction(const char *source, ShaderInterface::Version reparse)
111 std::string tmp(source);
114 void ShaderImage::setFunction(const std::string &source, ShaderInterface::Version reparse)
116 glslversion = reparse;
118 case ShaderInterface::THROUGH:
119 orig_source = source;
121 case ShaderInterface::AUTO_DETECT:
122 case ShaderInterface::GLSL1_1:
123 ShaderInterface::reparseGLSL1_1(source, orig_source, orig_args);
126 orig_source = source;
130 void ShaderImage::argf(
131 double a0, double a1, double a2, double a3,
132 double a4, double a5, double a6, double a7,
133 double a8, double a9, double a10, double a11,
134 double a12, double a13, double a14, double a15
137 arg_tmp[0] = a0; arg_tmp[1] = a1; arg_tmp[2] = a2; arg_tmp[3] = a3;
138 arg_tmp[4] = a4; arg_tmp[5] = a5; arg_tmp[6] = a6; arg_tmp[7] = a7;
139 arg_tmp[8] = a8; arg_tmp[9] = a9; arg_tmp[10]= a10; arg_tmp[11]= a11;
140 arg_tmp[12]= a12; arg_tmp[13]= a13; arg_tmp[14]= a14; arg_tmp[15]= a15;
143 void ShaderImage::cache(DrawableWithCache &target)
145 api.cacheTex(orig_source, orig_args, target);
147 void ShaderImage::cache(const char *source, DrawableWithCache &target)
149 if(!initialized && &target!=0) {
155 void ShaderImage::cacheFromFile(const std::string path, DrawableWithCache &target)
157 std::stringstream buf;
158 Internal::loadGLSL(buf, path);
159 Internal::error_message.clear();
161 setFunction(buf.str().c_str());
162 cache(*Display::the_canvas);
163 } catch (Exception e) {
164 Internal::error_message = e.getErrorString();
165 Internal::logError();
166 } catch (Exception *e) {
167 Internal::error_message = e->getErrorString();
168 Internal::logError();
171 ShaderImage& ShaderImage::draw(Image &img, const double* argv, const int argn, Canvas &target)
173 //if() cache(target);
174 api.drawImage(img, argv, argn, target);
177 void ShaderImage::to(Image &dest, Image &img, const double* argv, const int argn, Canvas &media)
179 Point tmp = img.getDatum();
180 api.imageToImage(dest, img, argv, argn, media);
183 ShaderImage& ShaderImage::draw(Image &img, Canvas &target)
185 return draw(img, arg_tmp, 4, target);
187 void ShaderImage::to(Image &dest, Image &img, Canvas &media)
189 to(dest, img, arg_tmp, 4, media);
193 void ShaderImage2::cache(DrawableWithCache &target)
\r
195 api.cacheTex(orig_source, orig_args, target, 1);
\r
197 ShaderImage2& ShaderImage2::draw(Image &img, const double* argv, const int argn, Canvas &target)
\r
199 //if() cache(target);
\r
200 api.drawImage(img, argv, argn, params, target);
\r
206 ShaderField::~ShaderField()
209 ShaderField::ShaderField()
215 "pix(vec4(0.0, 0.0, 1.0, 0.5)); }";
216 arg_tmp[0] = 0; arg_tmp[1] = 0; arg_tmp[2] = 0; arg_tmp[3] = 0;
217 arg_tmp[4] = 0; arg_tmp[5] = 0; arg_tmp[6] = 0; arg_tmp[7] = 0;
218 arg_tmp[8] = 0; arg_tmp[9] = 0; arg_tmp[10]= 0; arg_tmp[11]= 0;
219 arg_tmp[12]= 0; arg_tmp[13]= 0; arg_tmp[14]= 0; arg_tmp[15]= 0;
221 void ShaderField::setBase()
224 void ShaderField::setFunction(const char* source, ShaderInterface::Version reparse)
226 std::string tmp(source);
227 setFunction(tmp, reparse);
229 void ShaderField::setFunction(const std::string &source, ShaderInterface::Version reparse)
231 glslversion = reparse;
233 case ShaderInterface::THROUGH:
234 orig_source = source;
236 case ShaderInterface::AUTO_DETECT:
237 case ShaderInterface::GLSL1_1:
238 ShaderInterface::reparseGLSL1_1(source, orig_source, orig_args);
241 orig_source = source;
245 void ShaderField::argf(
246 double a0, double a1, double a2, double a3,
247 double a4, double a5, double a6, double a7,
248 double a8, double a9, double a10, double a11,
249 double a12, double a13, double a14, double a15
252 arg_tmp[0] = a0; arg_tmp[1] = a1; arg_tmp[2] = a2; arg_tmp[3] = a3;
253 arg_tmp[4] = a4; arg_tmp[5] = a5; arg_tmp[6] = a6; arg_tmp[7] = a7;
254 arg_tmp[8] = a8; arg_tmp[9] = a9; arg_tmp[10]= a10; arg_tmp[11]= a11;
255 arg_tmp[12]= a12; arg_tmp[13]= a13; arg_tmp[14]= a14; arg_tmp[15]= a15;
257 void ShaderField::cache(DrawableWithCache &target)
259 switch(glslversion) {
260 case ShaderInterface::THROUGH:
261 api.cache(orig_source, orig_args, target);
263 case ShaderInterface::AUTO_DETECT:
264 case ShaderInterface::GLSL1_1:
265 api.cacheField(orig_source, orig_args, target);
268 api.cacheField(orig_source, orig_args, target);
272 void ShaderField::cache(const char *source, DrawableWithCache &target)
274 if(!initialized && &target!=0) {
280 void ShaderField::cacheFromFile(const std::string path, DrawableWithCache &target)
282 std::stringstream buf;
283 Internal::loadGLSL(buf, path);
284 Internal::error_message.clear();
286 setFunction(buf.str().c_str());
287 cache(*Display::the_canvas);
288 } catch (Exception e) {
289 Internal::error_message = e.getErrorString();
290 Internal::logError();
291 } catch (Exception *e) {
292 Internal::error_message = e->getErrorString();
293 Internal::logError();
296 void ShaderField::draw(const Rectangle &rect, const double* argv, const int argn, Drawable &target)
298 api.drawField(rect, argv, argn);
300 void ShaderField::to(Image &dest, const Rectangle &rect, const double* argv, const int argn, Canvas &media)
302 api.fieldToImage(dest, rect, argv, argn, media);
304 void ShaderField::draw(const Rectangle &rect, Drawable &target)
306 api.drawField(rect, arg_tmp, 4);
308 void ShaderField::to(Image &dest, const Rectangle &rect, Canvas &media)
310 api.fieldToImage(dest, rect, arg_tmp, 4, media);
315 ShaderCoordinateTuner::ShaderCoordinateTuner()
318 set(256*pixel, 256*pixel);
320 ShaderCoordinateTuner& ShaderCoordinateTuner::cache(DrawableWithCache &target)
322 field.cache(glsl_source, target);
325 ShaderCoordinateTuner& ShaderCoordinateTuner::draw(Canvas &target)
328 const double Z[4] = { 0,0,0,0 };
329 field.draw(*this, Z, 0, target);
332 void ShaderCoordinateTuner::to(Image &dest, Canvas &media)
335 const double Z[4] = { 0,0,0,0 };
336 field.to(dest, *this, Z, 0, media);
338 ShaderField ShaderCoordinateTuner::field;
339 const char *ShaderCoordinateTuner::glsl_source =
341 "float r = floor(abs(gl_TexCoord[0][0]))/255.0;"
342 "float g = fract(abs(gl_TexCoord[0][0]));"
343 "pix( r, g, 0.0); }";
347 ShaderGrating::ShaderGrating()
350 set(10*pixel, 10*pixel);
352 ShaderGrating& ShaderGrating::setWave(double wavelen, double cont, double orient, double phs)
354 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
356 ShaderGrating& ShaderGrating::setWave(Length wavelen, double cont, Angle orient, Angle phs)
359 wavelength = wavelen;
360 orientation = orient;
364 ShaderGrating& ShaderGrating::cache(DrawableWithCache &target)
366 field.cache(glsl_source, target);
369 ShaderGrating& ShaderGrating::draw(Drawable &target)
372 //const double Z[4] = { phase.at_degree(), contrast, orientation.at_degree(), PI/wavelength*getWidth() };
373 const double Z[4] = { phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength };
374 field.draw(*this, Z, 1, target);
378 void ShaderGrating::to(Image &dest, Canvas &media)
381 // const double Z[4] = { phase.at_degree(), contrast, orientation.at_degree(), PI/wavelength*getWidth() };
382 const double Z[4] = { phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength };
383 field.to(dest, *this, Z, 1, media);
386 ShaderField ShaderGrating::field;
387 const char *ShaderGrating::glsl_source =
389 "float phase = gl_TexCoord[4][0], contrast = gl_TexCoord[4][1], orientation = gl_TexCoord[4][2], frequency = gl_TexCoord[4][3];"
390 "float _x = sin(orientation)*xp()-cos(orientation)*yp();"
391 "pix(0.5 + contrast*0.5*cos(frequency*_x + phase) ); }";
394 ShaderGaussianDot::ShaderGaussianDot()
397 bgcolor = Color::null_color;
398 Rectangle::fill = Color::black;
400 ShaderGaussianDot& ShaderGaussianDot::setSigma(double sigma)
402 Rectangle::set(sigma*8.0, sigma*8.0);
405 ShaderGaussianDot& ShaderGaussianDot::cache(DrawableWithCache &target)
407 field.cache(glsl_source, target);
410 ShaderGaussianDot& ShaderGaussianDot::draw(Drawable &target)
413 const double Z[12] = {
414 2.0/getWidth(), 0, 0, 0,
415 Rectangle::fill.getR(), Rectangle::fill.getG(), Rectangle::fill.getB(), Rectangle::fill.getA(),
416 bgcolor.getR(), bgcolor.getG(), bgcolor.getB(), bgcolor.getA()
418 field.draw(*this, Z, 3, target);
421 void ShaderGaussianDot::to(Image &dest, Canvas &media)
424 const double Z[12] = {
425 2.0/getWidth(), 0, 0, 0,
426 Rectangle::fill.getR(), Rectangle::fill.getG(), Rectangle::fill.getB(), Rectangle::fill.getA(),
427 bgcolor.getR(), bgcolor.getG(), bgcolor.getB(), bgcolor.getA()
429 field.to(dest, *this, Z, 3, media);
431 ShaderField ShaderGaussianDot::field;
432 const char *ShaderGaussianDot::glsl_source =
434 "float r = rp()*gl_TexCoord[4][0]*4.0;"
435 "float r2 = -(r*r) / 2.0;"
436 "vec4 env = mix(gl_TexCoord[6], gl_TexCoord[5], exp(r2));"
441 ShaderGabor::ShaderGabor()
444 set(10*pixel, 10*pixel);
450 ShaderGabor& ShaderGabor::setSigma(double sigma)
452 return setSigma(sigma*pixel);
454 ShaderGabor& ShaderGabor::setSigma(Length sigma)
456 Rectangle::set(sigma*8.0, sigma*8.0);
459 ShaderGabor& ShaderGabor::setWave(double wavelen, double cont, double orient, double phs)
461 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
463 ShaderGabor& ShaderGabor::setWave(Length wavelen, double cont, Angle orient, Angle phs)
466 wavelength = wavelen;
467 orientation = orient;
472 ShaderGabor& ShaderGabor::cache(DrawableWithCache &target)
474 field.cache(glsl_source, target);
477 ShaderGabor& ShaderGabor::draw(Drawable &target)
480 const double Z[8] = { 2.0/getWidth(),0,0,0, phase, contrast, orientation, 2*PI/wavelength };
481 field.draw(*this, Z, 2, target);
484 void ShaderGabor::to(Image &dest, Canvas &media)
487 const double Z[8] = { 2.0/getWidth(),0,0,0, phase, contrast, orientation, 2*PI/wavelength };
488 field.to(dest, *this, Z, 2, media);
491 ShaderField ShaderGabor::field;
492 const char *ShaderGabor::glsl_source =
494 "float _r = rp()*gl_TexCoord[4][0]*4.0;"
495 "float env = exp( -(_r*_r) / 2.0 );"
496 "float phase = gl_TexCoord[5][0], contrast = gl_TexCoord[5][1], orientation = gl_TexCoord[5][2], frequency = gl_TexCoord[5][3];"
497 "float _x = sin(orientation)*xp()-cos(orientation)*yp();"
498 //"float level = 0.5+contrast*0.5*cos(frequency*_x + phase);"
500 "float level = 0.996078*(0.5+env*( contrast*0.5*cos(frequency*_x + phase) ));"
506 ShaderGaborAlpha::ShaderGaborAlpha()
\r
509 set(10*pixel, 10*pixel);
\r
516 ShaderGaborAlpha& ShaderGaborAlpha::setSigma(double sigma)
\r
518 return setSigma(sigma*pixel);
\r
520 ShaderGaborAlpha& ShaderGaborAlpha::setSigma(Length sigma)
\r
522 Rectangle::set(sigma*8.0, sigma*8.0);
\r
525 ShaderGaborAlpha& ShaderGaborAlpha::setWave(double wavelen, double cont, double orient, double phs)
\r
527 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
\r
529 ShaderGaborAlpha& ShaderGaborAlpha::setWave(Length wavelen, double cont, Angle orient, Angle phs)
\r
532 wavelength = wavelen;
\r
533 orientation = orient;
\r
538 ShaderGaborAlpha& ShaderGaborAlpha::cache(DrawableWithCache &target)
\r
540 field.cache(glsl_source, target);
\r
543 ShaderGaborAlpha& ShaderGaborAlpha::draw(Drawable &target)
\r
546 const double Z[8] = { 2.0/getWidth(),alpha,0,0, phase, contrast, orientation, 2*PI/wavelength };
\r
547 field.draw(*this, Z, 2, target);
\r
550 void ShaderGaborAlpha::to(Image &dest, Canvas &media)
\r
553 const double Z[8] = { 2.0/getWidth(),alpha,0,0, phase, contrast, orientation, 2*PI/wavelength };
\r
554 field.to(dest, *this, Z, 2, media);
\r
557 ShaderField ShaderGaborAlpha::field;
\r
558 const char *ShaderGaborAlpha::glsl_source =
\r
559 "void main(void) {"
\r
560 "float _r = rp()*gl_TexCoord[4][0]*4.0;"
\r
561 "float env = exp( -(_r*_r) / 2.0 ) * gl_TexCoord[4][1];"
\r
562 "float phase = gl_TexCoord[5][0], contrast = gl_TexCoord[5][1], orientation = gl_TexCoord[5][2], frequency = gl_TexCoord[5][3];"
\r
563 "float _x = sin(orientation)*xp()-cos(orientation)*yp();"
\r
564 "float level = 0.5+contrast*0.5*cos(frequency*_x + phase);"
\r
571 ShaderPlaid::ShaderPlaid()
574 set(10*pixel, 10*pixel);
576 ShaderPlaid& ShaderPlaid::setSigma(double sigma)
578 return setSigma(sigma*pixel);
580 ShaderPlaid& ShaderPlaid::setSigma(Length sigma)
582 Rectangle::set(sigma*8.0, sigma*8.0);
585 ShaderPlaid& ShaderPlaid::setWave(double wavelen, double cont, double orient, double phs)
587 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
589 ShaderPlaid& ShaderPlaid::setWave(Length wavelen, double cont, Angle orient, Angle phs)
592 wavelength = wavelen;
593 orientation = orient;
597 ShaderPlaid& ShaderPlaid::setWave2(double wavelen, double cont, double orient, double phs)
599 return setWave2(wavelen*pixel, cont, orient*degree, phs*degree);
601 ShaderPlaid& ShaderPlaid::setWave2(Length wavelen, double cont, Angle orient, Angle phs)
604 wavelength2 = wavelen;
605 orientation2 = orient;
609 ShaderPlaid& ShaderPlaid::cache(DrawableWithCache &target)
611 field.cache(glsl_source, target);
614 ShaderPlaid& ShaderPlaid::draw(Drawable &target)
619 2.0/getWidth(),0,0,0,
620 phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength,
621 phase2.at_degree(), contrast2, orientation2.at_degree(), 2*PI/wavelength2
623 field.draw(*this, Z, 3, target);
627 void ShaderPlaid::to(Image &dest, Canvas &media)
632 2.0/getWidth(),0,0,0,
633 phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength,
634 phase2.at_degree(), contrast2, orientation2.at_degree(), 2*PI/wavelength2
636 field.to(dest, *this, Z, 3, media);
639 ShaderField ShaderPlaid::field;
640 const char *ShaderPlaid::glsl_source =
642 "float phase = gl_TexCoord[5][0], contrast = gl_TexCoord[5][1], orientation = gl_TexCoord[5][2], frequency = gl_TexCoord[5][3];"
643 "float phase2 = gl_TexCoord[6][0], contrast2 = gl_TexCoord[6][1], orientation2 = gl_TexCoord[6][2], frequency2 = gl_TexCoord[6][3];"
644 "float _x = sin(orientation)*xp()-cos(orientation)*yp();"
645 "float _x2 = sin(orientation2)*xp()-cos(orientation2)*yp();"
646 "float _r = rp()*gl_TexCoord[4][0]*4.0;"
647 "float env = exp( -(_r*_r) / 2.0 );"
648 "float level = 0.996078*(0.5+env*( contrast*0.5*cos(frequency*_x + phase) + contrast2*0.5*cos(frequency2*_x2 + phase2) ));"
650 //"float level = 0.5 + contrast*0.5*cos(frequency*_x + phase) + contrast2*0.5*cos(frequency2*_x2 + phase2);"
651 //"pix(level, level, level, env);"
656 ShaderPlaidAlpha::ShaderPlaidAlpha()
\r
659 set(10*pixel, 10*pixel);
\r
662 ShaderPlaidAlpha& ShaderPlaidAlpha::setSigma(double sigma)
\r
664 return setSigma(sigma*pixel);
\r
666 ShaderPlaidAlpha& ShaderPlaidAlpha::setSigma(Length sigma)
\r
668 Rectangle::set(sigma*8.0, sigma*8.0);
\r
671 ShaderPlaidAlpha& ShaderPlaidAlpha::setWave(double wavelen, double cont, double orient, double phs)
\r
673 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
\r
675 ShaderPlaidAlpha& ShaderPlaidAlpha::setWave(Length wavelen, double cont, Angle orient, Angle phs)
\r
678 wavelength = wavelen;
\r
679 orientation = orient;
\r
683 ShaderPlaidAlpha& ShaderPlaidAlpha::setWave2(double wavelen, double cont, double orient, double phs)
\r
685 return setWave2(wavelen*pixel, cont, orient*degree, phs*degree);
\r
687 ShaderPlaidAlpha& ShaderPlaidAlpha::setWave2(Length wavelen, double cont, Angle orient, Angle phs)
\r
690 wavelength2 = wavelen;
\r
691 orientation2 = orient;
\r
695 ShaderPlaidAlpha& ShaderPlaidAlpha::cache(DrawableWithCache &target)
\r
697 field.cache(glsl_source, target);
\r
700 ShaderPlaidAlpha& ShaderPlaidAlpha::draw(Drawable &target)
\r
703 const double Z[12] =
\r
705 2.0/getWidth(),alpha,0,0,
\r
706 phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength,
\r
707 phase2.at_degree(), contrast2, orientation2.at_degree(), 2*PI/wavelength2
\r
709 field.draw(*this, Z, 3, target);
\r
713 void ShaderPlaidAlpha::to(Image &dest, Canvas &media)
\r
716 const double Z[12] =
\r
718 2.0/getWidth(),alpha,0,0,
\r
719 phase.at_degree(), contrast, orientation.at_degree(), 2*PI/wavelength,
\r
720 phase2.at_degree(), contrast2, orientation2.at_degree(), 2*PI/wavelength2
\r
722 field.to(dest, *this, Z, 3, media);
\r
725 ShaderField ShaderPlaidAlpha::field;
\r
726 const char *ShaderPlaidAlpha::glsl_source =
\r
727 "void main(void) {"
\r
728 "float phase = gl_TexCoord[5][0], contrast = gl_TexCoord[5][1], orientation = gl_TexCoord[5][2], frequency = gl_TexCoord[5][3];"
\r
729 "float phase2 = gl_TexCoord[6][0], contrast2 = gl_TexCoord[6][1], orientation2 = gl_TexCoord[6][2], frequency2 = gl_TexCoord[6][3];"
\r
730 "float _x = sin(orientation)*xp()-cos(orientation)*yp();"
\r
731 "float _x2 = sin(orientation2)*xp()-cos(orientation2)*yp();"
\r
732 "float _r = rp()*gl_TexCoord[4][0]*4.0;"
\r
733 "float env = exp( -(_r*_r) / 2.0 ) * gl_TexCoord[4][1];"
\r
734 //"float level = 0.996078*(0.5+env*( contrast*0.5*cos(frequency*_x + phase) + contrast2*0.5*cos(frequency2*_x2 + phase2) ));"
\r
736 "float level = 0.5 + contrast*0.5*cos(frequency*_x + phase) + contrast2*0.5*cos(frequency2*_x2 + phase2);"
\r
737 "pix(level, level, level, env);"
\r
741 } /* <- namespace Figures */
742 } /* <- namespace Psycholops */