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)
117 case ShaderInterface::AUTO_DETECT:
118 case ShaderInterface::GLSL1_1:
119 ShaderInterface::reparseGLSL1_1(source, orig_source, orig_args);
122 orig_source = source;
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
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;
139 void ShaderImage::cache(DrawableWithCache &target)
141 api.cacheTex(orig_source, orig_args, target);
143 void ShaderImage::cache(const char *source, DrawableWithCache &target)
145 if(!initialized && &target!=0) {
151 void ShaderImage::cacheFromFile(const std::string path, DrawableWithCache &target)
153 std::stringstream buf;
154 Internal::loadGLSL(buf, path);
155 Internal::error_message.clear();
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();
167 ShaderImage& ShaderImage::draw(Image &img, const double* argv, const int argn, Canvas &target)
169 //if() cache(target);
170 api.drawImage(img, argv, argn, target);
173 void ShaderImage::to(Image &dest, Image &img, const double* argv, const int argn, Canvas &media)
175 Point tmp = img.getDatum();
176 api.imageToImage(dest, img, argv, argn, media);
179 ShaderImage& ShaderImage::draw(Image &img, Canvas &target)
181 return draw(img, arg_tmp, 4, target);
183 void ShaderImage::to(Image &dest, Image &img, Canvas &media)
185 to(dest, img, arg_tmp, 4, media);
189 void ShaderImage2::cache(DrawableWithCache &target)
\r
191 api.cacheTex(orig_source, orig_args, target, 1);
\r
193 ShaderImage2& ShaderImage2::draw(Image &img, const double* argv, const int argn, Canvas &target)
\r
195 //if() cache(target);
\r
196 api.drawImage(img, argv, argn, params, target);
\r
202 ShaderField::~ShaderField()
205 ShaderField::ShaderField()
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;
217 void ShaderField::setBase()
220 void ShaderField::setFunction(const char* source, ShaderInterface::Version reparse)
222 std::string tmp(source);
225 void ShaderField::setFunction(const std::string &source, ShaderInterface::Version reparse)
228 case ShaderInterface::AUTO_DETECT:
229 case ShaderInterface::GLSL1_1:
230 ShaderInterface::reparseGLSL1_1(source, orig_source, orig_args);
233 orig_source = source;
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
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;
249 void ShaderField::cache(DrawableWithCache &target)
251 api.cacheField(orig_source, orig_args, target);
253 void ShaderField::cache(const char *source, DrawableWithCache &target)
255 if(!initialized && &target!=0) {
261 void ShaderField::cacheFromFile(const std::string path, DrawableWithCache &target)
263 std::stringstream buf;
264 Internal::loadGLSL(buf, path);
265 Internal::error_message.clear();
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();
277 void ShaderField::draw(const Rectangle &rect, const double* argv, const int argn, Drawable &target)
279 api.drawField(rect, argv, argn);
281 void ShaderField::to(Image &dest, const Rectangle &rect, const double* argv, const int argn, Canvas &media)
283 api.fieldToImage(dest, rect, argv, argn, media);
285 void ShaderField::draw(const Rectangle &rect, Drawable &target)
287 api.drawField(rect, arg_tmp, 4);
289 void ShaderField::to(Image &dest, const Rectangle &rect, Canvas &media)
291 api.fieldToImage(dest, rect, arg_tmp, 4, media);
296 ShaderCoordinateTuner::ShaderCoordinateTuner()
299 set(256*pixel, 256*pixel);
301 ShaderCoordinateTuner& ShaderCoordinateTuner::cache(DrawableWithCache &target)
303 field.cache(glsl_source, target);
306 ShaderCoordinateTuner& ShaderCoordinateTuner::draw(Canvas &target)
309 const double Z[4] = { 0,0,0,0 };
310 field.draw(*this, Z, 0, target);
313 void ShaderCoordinateTuner::to(Image &dest, Canvas &media)
316 const double Z[4] = { 0,0,0,0 };
317 field.to(dest, *this, Z, 0, media);
319 ShaderField ShaderCoordinateTuner::field;
320 const char *ShaderCoordinateTuner::glsl_source =
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); }";
328 ShaderGrating::ShaderGrating()
331 set(10*pixel, 10*pixel);
333 ShaderGrating& ShaderGrating::setWave(double wavelen, double cont, double orient, double phs)
335 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
337 ShaderGrating& ShaderGrating::setWave(Length wavelen, double cont, Angle orient, Angle phs)
340 wavelength = wavelen;
341 orientation = orient;
345 ShaderGrating& ShaderGrating::cache(DrawableWithCache &target)
347 field.cache(glsl_source, target);
350 ShaderGrating& ShaderGrating::draw(Drawable &target)
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);
359 void ShaderGrating::to(Image &dest, Canvas &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);
367 ShaderField ShaderGrating::field;
368 const char *ShaderGrating::glsl_source =
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) ); }";
375 ShaderGaussianDot::ShaderGaussianDot()
378 bgcolor = Color::null_color;
379 Rectangle::fill = Color::black;
381 ShaderGaussianDot& ShaderGaussianDot::setSigma(double sigma)
383 Rectangle::set(sigma*8.0, sigma*8.0);
386 ShaderGaussianDot& ShaderGaussianDot::cache(DrawableWithCache &target)
388 field.cache(glsl_source, target);
391 ShaderGaussianDot& ShaderGaussianDot::draw(Drawable &target)
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()
399 field.draw(*this, Z, 3, target);
402 void ShaderGaussianDot::to(Image &dest, Canvas &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()
410 field.to(dest, *this, Z, 3, media);
412 ShaderField ShaderGaussianDot::field;
413 const char *ShaderGaussianDot::glsl_source =
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));"
422 ShaderGabor::ShaderGabor()
425 set(10*pixel, 10*pixel);
431 ShaderGabor& ShaderGabor::setSigma(double sigma)
433 return setSigma(sigma*pixel);
435 ShaderGabor& ShaderGabor::setSigma(Length sigma)
437 Rectangle::set(sigma*8.0, sigma*8.0);
440 ShaderGabor& ShaderGabor::setWave(double wavelen, double cont, double orient, double phs)
442 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
444 ShaderGabor& ShaderGabor::setWave(Length wavelen, double cont, Angle orient, Angle phs)
447 wavelength = wavelen;
448 orientation = orient;
453 ShaderGabor& ShaderGabor::cache(DrawableWithCache &target)
455 field.cache(glsl_source, target);
458 ShaderGabor& ShaderGabor::draw(Drawable &target)
461 const double Z[8] = { 2.0/getWidth(),0,0,0, phase, contrast, orientation, 2*PI/wavelength };
462 field.draw(*this, Z, 2, target);
465 void ShaderGabor::to(Image &dest, Canvas &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);
472 ShaderField ShaderGabor::field;
473 const char *ShaderGabor::glsl_source =
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);"
481 "float level = 0.996078*(0.5+env*( contrast*0.5*cos(frequency*_x + phase) ));"
487 ShaderGaborAlpha::ShaderGaborAlpha()
\r
490 set(10*pixel, 10*pixel);
\r
497 ShaderGaborAlpha& ShaderGaborAlpha::setSigma(double sigma)
\r
499 return setSigma(sigma*pixel);
\r
501 ShaderGaborAlpha& ShaderGaborAlpha::setSigma(Length sigma)
\r
503 Rectangle::set(sigma*8.0, sigma*8.0);
\r
506 ShaderGaborAlpha& ShaderGaborAlpha::setWave(double wavelen, double cont, double orient, double phs)
\r
508 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
\r
510 ShaderGaborAlpha& ShaderGaborAlpha::setWave(Length wavelen, double cont, Angle orient, Angle phs)
\r
513 wavelength = wavelen;
\r
514 orientation = orient;
\r
519 ShaderGaborAlpha& ShaderGaborAlpha::cache(DrawableWithCache &target)
\r
521 field.cache(glsl_source, target);
\r
524 ShaderGaborAlpha& ShaderGaborAlpha::draw(Drawable &target)
\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
531 void ShaderGaborAlpha::to(Image &dest, Canvas &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
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
552 ShaderPlaid::ShaderPlaid()
555 set(10*pixel, 10*pixel);
557 ShaderPlaid& ShaderPlaid::setSigma(double sigma)
559 return setSigma(sigma*pixel);
561 ShaderPlaid& ShaderPlaid::setSigma(Length sigma)
563 Rectangle::set(sigma*8.0, sigma*8.0);
566 ShaderPlaid& ShaderPlaid::setWave(double wavelen, double cont, double orient, double phs)
568 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
570 ShaderPlaid& ShaderPlaid::setWave(Length wavelen, double cont, Angle orient, Angle phs)
573 wavelength = wavelen;
574 orientation = orient;
578 ShaderPlaid& ShaderPlaid::setWave2(double wavelen, double cont, double orient, double phs)
580 return setWave2(wavelen*pixel, cont, orient*degree, phs*degree);
582 ShaderPlaid& ShaderPlaid::setWave2(Length wavelen, double cont, Angle orient, Angle phs)
585 wavelength2 = wavelen;
586 orientation2 = orient;
590 ShaderPlaid& ShaderPlaid::cache(DrawableWithCache &target)
592 field.cache(glsl_source, target);
595 ShaderPlaid& ShaderPlaid::draw(Drawable &target)
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
604 field.draw(*this, Z, 3, target);
608 void ShaderPlaid::to(Image &dest, Canvas &media)
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
617 field.to(dest, *this, Z, 3, media);
620 ShaderField ShaderPlaid::field;
621 const char *ShaderPlaid::glsl_source =
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) ));"
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);"
637 ShaderPlaidAlpha::ShaderPlaidAlpha()
\r
640 set(10*pixel, 10*pixel);
\r
643 ShaderPlaidAlpha& ShaderPlaidAlpha::setSigma(double sigma)
\r
645 return setSigma(sigma*pixel);
\r
647 ShaderPlaidAlpha& ShaderPlaidAlpha::setSigma(Length sigma)
\r
649 Rectangle::set(sigma*8.0, sigma*8.0);
\r
652 ShaderPlaidAlpha& ShaderPlaidAlpha::setWave(double wavelen, double cont, double orient, double phs)
\r
654 return setWave(wavelen*pixel, cont, orient*degree, phs*degree);
\r
656 ShaderPlaidAlpha& ShaderPlaidAlpha::setWave(Length wavelen, double cont, Angle orient, Angle phs)
\r
659 wavelength = wavelen;
\r
660 orientation = orient;
\r
664 ShaderPlaidAlpha& ShaderPlaidAlpha::setWave2(double wavelen, double cont, double orient, double phs)
\r
666 return setWave2(wavelen*pixel, cont, orient*degree, phs*degree);
\r
668 ShaderPlaidAlpha& ShaderPlaidAlpha::setWave2(Length wavelen, double cont, Angle orient, Angle phs)
\r
671 wavelength2 = wavelen;
\r
672 orientation2 = orient;
\r
676 ShaderPlaidAlpha& ShaderPlaidAlpha::cache(DrawableWithCache &target)
\r
678 field.cache(glsl_source, target);
\r
681 ShaderPlaidAlpha& ShaderPlaidAlpha::draw(Drawable &target)
\r
684 const double Z[12] =
\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
690 field.draw(*this, Z, 3, target);
\r
694 void ShaderPlaidAlpha::to(Image &dest, Canvas &media)
\r
697 const double Z[12] =
\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
703 field.to(dest, *this, Z, 3, media);
\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
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
722 } /* <- namespace Figures */
723 } /* <- namespace Psycholops */