OSDN Git Service

cache
[psychlops/cpp.git] / psychlops / platform / gl / extension / psychlops_g_shader_gl.cpp
1 /*
2  *  psychlops_g_shader_Win32GL.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 #define PSYCHLOPS_SHADER_PLATFORM
10 #include "../../../platform/psychlops_platform_selector.h"
11
12 #include "psychlops_g_shader_gl.h"
13
14
15
16 namespace Psychlops {
17
18         static char *shader_const_source[16];
19         static int shader_const_source_n;
20
21         const char* ShaderAPI::shader_core_pix =
22         "void pix(in float r, in float g, in float b, in float a) { gl_FragColor = vec4(floor(255.0*r+0.5)/255.0,floor(255.0*g+0.5)/255.0,floor(255.0*b+0.5)/255.0,a); }\r\n"
23         ;
24         const char* ShaderAPI::shader_core_pix_bitsmono =
25         "const float MAX16 = 255.99609375;"
26 //      "vec4 toBitsMono(in float l) { int w = int(l*65535.0); return vec4( floor(l*255.996094)/255.0, fract(l*255.996094), 0.0, 1.0  ); }"
27         "vec4 toBitsMono(in float l) { return vec4( floor(l*MAX16)/255.0, fract(l*MAX16), 0.0, 1.0  ); }"
28         "void pix(in float l, in float g, in float b, in float a) { gl_FragColor = toBitsMono(l); }"\r
29         //"void pix(in float l, in float g, in float b, in float a) { gl_FragColor = toBitsMono(pow(l,0.30581)); }"
30         ;
31         const char* ShaderAPI::shader_core_pix_bitsmono_bitshift =
32 //      "vec4 toBitsMono(in float l) { int w = int(l*65535.0); return vec4( w && 65280 >> 8 , w && 255, 0.0, 1.0  ); }"
33         "void pix(in float l) { gl_FragColor = toBitsMono(l); }"
34         ;
35         const char* ShaderAPI::shader_core_pix_bitscolor =\r
36         "const float MAX16 = 255.99609375;"
37         "float xp() { return  gl_FragCoord[0]-gl_TexCoord[3][0]; }\r\n"
38         "float yp() { return -gl_FragCoord[1]-gl_TexCoord[3][1]; }\r\n"
39         "float toBitsH(in float v) { return floor(v*MAX16)/255.0; }\r\n"\r
40         "float toBitsL(in float v) { return fract(v*MAX16); }\r\n"\r
41 //      "float toBitsH(in float v) { int w = int(v*65535.0); return (float((w & 0xff00)>>8))/255.0; }\r\n"\r
42 //      "float toBitsL(in float v) { float u = v*65535.0; int w = int(u) & 255; return float(w) / 255.0; }"\r
43         "void pix(in float r, in float g, in float b, in float a) {\r\n"\r
44         " float aa = 1.0; if(a==0.0) { aa = 0.0; }\r\n"\r
45 //      " if(mod(gl_FragCoord[0],2.0)<=1.0){"\r
46         " if(int(gl_FragCoord.x)%2 == 0){\r\n"\r
47         "  gl_FragColor = vec4(toBitsH(r), toBitsH(g), toBitsH(b), aa);\r\n"\r
48         " } else {\r\n"\r
49         "  gl_FragColor = vec4(toBitsL(r), toBitsL(g), toBitsL(b), aa);\r\n"\r
50 //      "  gl_FragColor = vec4(r, g, b, 1.0);"\r
51         " }\r\n"\r
52         "}\r\n"\r
53         ;
54
55         const char* ShaderAPI::shader_core_getpix =
56         "vec4 getPix() { return texture2D(texture0, vec2(gl_TexCoord[0][0], gl_TexCoord[0][1]) ); }\r\n"
57         //"vec4 getPix(in int x, in int y) { return texelFetch( texture0, ivec2( x, y ), 0 ); }"
58         "vec4 getPix(in int x, in int y) { return texture2D( texture0, vec2( float(x)/float(SIZE_LOG.x), float(y)/float(SIZE_LOG.y)  ) ); }\r\n"
59         "vec4 getPixOffset(in int x, in int y) { return texture2D( texture0, gl_TexCoord[0].xy + vec2( float(x)/float(SIZE_LOG.x), float(y)/float(SIZE_LOG.y)  ) ); }\r\n"
60         ;
61         const char* ShaderAPI::shader_core_getpix_bitsmono =
62         "vec4 getPix() { return texture2D(texture0, vec2(gl_TexCoord[0][0], gl_TexCoord[0][1]) ); }"
63         //"vec4 getPix(in int x, in int y) { return texelFetch( texture0, ivec2( x, y ), 0 ); }"
64         "vec4 getPix(in int x, in int y) { return texture2D( texture0, vec2( float(x)/float(SIZE_LOG.x), float(y)/float(SIZE_LOG.y)  ) ); }"
65         "vec4 getPixOffset(in int x, in int y) { return texture2D( texture0, gl_TexCoord[0].xy + vec2( float(x)/float(SIZE_LOG.x), float(y)/float(SIZE_LOG.y)  ) ); }"
66         //"vec4 toBitsMono(in float l) { int w = int(l*65535.0); return vec4( floor(l*255.996094)/255.0, fract(l*255.996094), 0.0, 1.0  ); }"
67         //"void pix(in float l) { gl_FragColor = toBitsMono(l); }"
68         ;
69         const char* ShaderAPI::shader_core_getpix_bitsmono_bitshift =
70         "vec4 getPix() { vec4 c = texture2D(texture0, vec2(gl_TexCoord[0][0], gl_TexCoord[0][1]) ); double l = ((c.r*255.0)<<8) + (c.b*255.0); return vec4( l, l, l, 1.0 ): }"
71         //"vec4 getPix(in int x, in int y) { return texelFetch( texture0, ivec2( x, y ), 0 ); }"
72         "vec4 getPix(in int x, in int y) { return texture2D( texture0, vec2( float(x)/float(SIZE_LOG.x), float(y)/float(SIZE_LOG.y)  ) ); }"
73         "vec4 getPixOffset(in int x, in int y) { return texture2D( texture0, gl_TexCoord[0].xy + vec2( float(x)/float(SIZE_LOG.x), float(y)/float(SIZE_LOG.y)  ) ); }"
74         //"vec4 toBitsMono(in float l) { int w = int(l*65535.0); return vec4( w && 65280 >> 8 , w && 255, 0.0, 1.0  ); }"
75         //"void pix(in float l) { gl_FragColor = toBitsMono(l); }"
76         ;
77
78         const char* ShaderAPI::shader_base_funcs =
79         "const float PI = 3.14159265358979323846264338327950288;\r\n"
80         "const float E  = 2.718281828459045235360287471352;\r\n"
81         "const int PSYCHLOPS_ARG_BASE = 4;\r\n"
82         "float NormalDistibution(in float x, in float mu, in float sigma) { float xm = x-mu, sig22 = 2.0*sigma*sigma; return exp( -( xm*xm / sig22 ) ) / sqrt(PI*sig22); }\r\n"
83         "float GaussianM0(in float x, in float sigma) { return exp( -(x*x) / (2.0*sigma*sigma) ); }\r\n"
84 //      "float argv(in int i) { return gl_TexCoord[i/4+PSYCHLOPS_ARG_BASE][i%4]; }"
85 //      "float argv(in int high, in int low) { return gl_TexCoord[high+PSYCHLOPS_ARG_BASE][low]; }"
86         "const vec4 PSYCHLOPS_COLOR_ADJ = vec4(0.001953125,0.001953125,0.001953125,0.0);\r\n"
87 //      "void pix(in float r, in float g, in float b, in float a) { gl_FragColor = vec4(floor(255.0*r+0.5)/255.0,floor(255.0*g+0.5)/255.0,floor(255.0*b+0.5)/255.0,a); }"
88 //      "void pix(in float r, in float g, in float b, in float a) { gl_FragColor = vec4(round(255.0*r)/255.0,round(255.0*g)/255.0,round(255.0*b)/255.0,a); }"
89 //      "void pix(in float r, in float g, in float b, in float a) { gl_FragColor = round(255.0*vec4(r,g,b,a))/255.0; }"
90 //      "void pix(in float r, in float g, in float b, in float a) { gl_FragColor = vec4(r,g,b,a)+PSYCHLOPS_COLOR_ADJ; }"
91         "void pix(in float r, in float g, in float b) { pix(r,g,b,1.0); }\r\n"
92         "void pix(in float l, in float a) { pix(l,l,l,a); }\r\n"
93         "void pix(in float l) { pix(l,l,l,1.0); }\r\n"
94         "void pix(in vec4 c) { pix(c.r, c.g, c.b, c.a); }\r\n"
95         "float width() { return gl_TexCoord[3][2]; }\r\n"
96         "float height() { return gl_TexCoord[3][3]; }\r\n"
97         ;
98
99         const char* ShaderAPI::shader_field_funcs_platform =
100         "const vec4 field_origin = vec4(0.5,0.5,0.0,1.0);\r\n"
101         "float xp() { return  gl_FragCoord[0]-gl_TexCoord[3][0]; }\r\n"
102         "float yp() { return -gl_FragCoord[1]-gl_TexCoord[3][1]; }\r\n"
103         "float rp() { return length(vec2(xp(),yp())); }\r\n"
104         "float thetaf() { return atan(yp(), xp()); }\r\n"
105         ;
106
107         const char* ShaderAPI::shader_figure_funcs_platform =
108         "uniform vec4 UNIFORM_PARAMETER;\r\n"
109         ;
110
111         const char* ShaderAPI::shader_texture_funcs_platform =
112         "uniform sampler2D texture0;\r\n"
113         "uniform ivec2 SIZE_REAL, SIZE_LOG;\r\n"
114         "const vec4 field_origin = vec4(0.5,0.5,0.0,1.0);\r\n"
115         "float xp() { return  gl_FragCoord[0]-gl_TexCoord[3][0]; }\r\n"
116         "float yp() { return -gl_FragCoord[1]+gl_TexCoord[3][1]; }\r\n"
117         "float rp() { return length(vec2(xp(),yp())); }\r\n"
118         "float thetaf() { return atan(yp(), xp()); }\r\n"\r
119         ;\r
120 \r
121         const char* ShaderAPI::shader_texture_funcs_platform2 =\r
122         "uniform sampler2D texture0;\r\n"\r
123         "uniform sampler2D texture1;\r\n"\r
124         "uniform ivec2 SIZE_REAL, SIZE_LOG;\r\n"\r
125         "const vec4 field_origin = vec4(0.5,0.5,0.0,1.0);\r\n"\r
126         "float xp() { return  gl_FragCoord[0]-gl_TexCoord[3][0]; }\r\n"\r
127         "float yp() { return -gl_FragCoord[1]+gl_TexCoord[3][1]; }\r\n"\r
128         "float rp() { return length(vec2(xp(),yp())); }\r\n"\r
129         "float thetaf() { return atan(yp(), xp()); }\r\n"
130         ;
131
132         const char* ShaderAPI::shader_texture_pix[2] = {
133                 ""
134                 ,
135                 ""
136         };\r
137 \r
138         void ShaderAPI::initializeInstance()\r
139         {\r
140                 vertShader = 0;\r
141                 gl1Program = 0;\r
142                 fragShader = 0;\r
143                 gl2Program = 0;\r
144         }\r
145 \r
146         void ShaderAPI::cacheVertex(const std::string &final_source, Drawable &target)\r
147         {\r
148                 initialize();\r
149 \r
150                 const char *source = final_source.c_str();\r
151                 GLint length = final_source.length();\r
152                 char *logbuf;\r
153                 std::string errormsg;\r
154                 GLint logSize;\r
155 \r
156                 GLint compiled, linked;\r
157                 vertShader = glCreateShader(GL_VERTEX_SHADER);\r
158                 glShaderSource(vertShader, 1, &source, &length);\r
159                 glCompileShader(vertShader);\r
160                 glGetShaderiv(vertShader, GL_COMPILE_STATUS, &compiled);\r
161                 if(compiled == GL_FALSE) {\r
162                         glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH , &logSize);\r
163                         char *logbuf = new char[logSize+3];\r
164                         logbuf[logSize+2] = 0;\r
165                         if(logSize>1) {\r
166                                 glGetShaderInfoLog(vertShader, logSize, &logSize, logbuf);\r
167                         }\r
168                         errormsg = logbuf;\r
169                         delete [] logbuf;\r
170                         throw new Exception(typeid(*this), "Shader compile failed", errormsg);\r
171                 }\r
172 \r
173                 if(gl2Program==0) gl2Program = glCreateProgram();\r
174                 glAttachShader(gl2Program, vertShader);\r
175 \r
176                 //glLinkProgram(gl1Program);\r
177                 //glGetProgramiv(gl1Program, GL_LINK_STATUS, &linked);\r
178                 //if(linked == GL_FALSE) throw new Exception("Shader link failed");\r
179         }
180
181         void ShaderAPI::cache(const std::string &final_source, const std::vector<std::string> &vars, Drawable &target)
182         {
183                 initialize();
184                 initField();
185
186                 const char *source = final_source.c_str();
187                 GLint length = final_source.length();
188                 char *logbuf;
189                 std::string errormsg;
190                 GLint logSize;
191
192                 GLint compiled, linked;
193                 fragShader = glCreateShader(GL_FRAGMENT_SHADER);
194                 glShaderSource(fragShader, 1, &source, &length);
195                 glCompileShader(fragShader);
196                 glGetShaderiv(fragShader, GL_COMPILE_STATUS, &compiled);
197                 if(compiled == GL_FALSE) {
198                         glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH , &logSize);
199                         char *logbuf = new char[logSize+3];
200                         logbuf[logSize+2] = 0;
201                         if(logSize>1) {
202                                 glGetShaderInfoLog(fragShader, logSize, &logSize, logbuf);
203                         }
204                         errormsg = logbuf;
205                         delete [] logbuf;
206                         throw new Exception(typeid(*this), "Shader compile failed", errormsg);
207                 }
208 \r
209                 if(gl2Program==0) gl2Program = glCreateProgram();
210                 glAttachShader(gl2Program, fragShader);
211
212                 glLinkProgram(gl2Program);
213                 glGetProgramiv(gl2Program, GL_LINK_STATUS, &linked);
214                 if(linked == GL_FALSE) throw new Exception("Shader link failed");
215         }
216         void ShaderAPI::cacheField(const std::string &orig_source, const std::vector<std::string> &vars, Drawable &target)
217         {
218                 //std::string final_source = "#version 130\r\n#extension GL_EXT_gpu_shader4 : enable\r\n\r\n";
219                 std::string final_source = "";
220
221                 int mode = 0;
222                 if(Color::getCalibrationMode() == Color::BITS_MONO) mode = 3;
223                 switch(mode)
224                 {
225                 case 3:
226                         final_source.append(shader_core_pix_bitsmono);
227 //                      final_source.append(shader_core_getpix_bitsmono);
228                         //final_source.append(shader_core_getpix_bitsmono_bitshift);
229                         //final_source.append(shader_core_pix_bitsmono_bitshift;
230                         break;
231                 default:
232                         final_source.append(shader_core_pix);
233 //                      final_source.append(shader_core_getpix);
234                 }
235
236                 final_source.append(shader_base_funcs);
237                 final_source.append(shader_field_funcs_platform);
238                 final_source.append(orig_source);
239                 cache(final_source, vars, target);
240         }
241         void ShaderAPI::cacheTex(const std::string &orig_source, const std::vector<std::string> &vars, Drawable &target, int opt)
242         {
243                 std::string final_source = "";
244 \r
245                 if(opt==1) {\r
246                         final_source.append(shader_texture_funcs_platform2);\r
247                 } else {\r
248                         final_source.append(shader_texture_funcs_platform);\r
249                 }\r
250 \r
251                 int mode = 0;
252                 if(Color::getCalibrationMode() == Color::BITS_MONO) mode = 3;
253                 switch(mode)
254                 {
255                 case 3:
256                         final_source.append(shader_core_pix_bitsmono);
257                         final_source.append(shader_core_getpix_bitsmono);
258                         //final_source.append(shader_core_getpix_bitsmono_bitshift);
259                         //final_source.append(shader_core_pix_bitsmono_bitshift;
260                         break;
261                 default:
262                         final_source.append(shader_core_pix);
263                         final_source.append(shader_core_getpix);
264                 }
265
266                 final_source.append(shader_base_funcs);
267                 final_source.append(orig_source);
268                 cache(final_source, vars, target);
269                 texture[0] =  glGetUniformLocation(gl2Program, "texture0");\r
270                 if(opt==1) {\r
271                         texture[1] =  glGetUniformLocation(gl2Program, "texture1");\r
272                 }
273                 size     = glGetUniformLocation(gl2Program, "SIZE_REAL");
274                 size_log = glGetUniformLocation(gl2Program, "SIZE_LOG");
275         }
276
277
278         bool ShaderAPI::field_initialized = false;
279         GLuint ShaderAPI::null_texture;
280         const unsigned char ShaderAPI::NULL_TEX[16] = {0,0,0,0 ,0,0,0,0 ,0,0,0,0 ,0,0,0,0};
281         void ShaderAPI::initField()
282         {
283                 if(!field_initialized) {
284                         glEnable(GL_TEXTURE_2D);
285                         glGenTextures(1, &null_texture);
286                         glBindTexture(GL_TEXTURE_2D, null_texture);
287                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
288                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
289                         glTexImage2D(GL_TEXTURE_2D, 0, 1, 4, 4, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &NULL_TEX);
290                         glDisable(GL_TEXTURE_2D);
291                         field_initialized = true;
292                 }
293         }
294
295         void drawFigure(Figure &fig, const double *argv, const int argn, Drawable &target)
296         {
297         }
298         void ShaderAPI::drawField(const Rectangle &rect, const double *arga, const int argn)
299         {
300                 const double WID = rect.getWidth(), HEI = rect.getHeight();
301                 const double ADJPX = -0.125, ADJPY = -0.1255;
302                 const double PX = rect.getLeft()+WID/2+.5, PY = rect.getTop()+HEI/2-Display::getHeight()+.5;
303                 glUseProgram(gl2Program);
304                 int i=0;
305                 glEnable(GL_TEXTURE_2D);
306                 /*for(i=0; i<argn+1; i++) {
307                         glActiveTexture(GL_TEXTURE0+i);
308                         glBindTexture(GL_TEXTURE_2D, null_texture);
309                 }*/
310                 glBegin(GL_QUADS);
311                         glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
312                         //glMultiTexCoord4d(GL_TEXTURE0, -WID/2+ADJPX, -HEI/2+ADJPY, WID, HEI);
313                         for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
314                         //for(i=0; i<argn; i++) glVertexAttrib1d(argv[i], *(arga+i));
315                                 glVertex2f(rect.getLeft(),  rect.getTop());
316                         glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
317                         //glMultiTexCoord4d(GL_TEXTURE0,  WID/2+ADJPX, -HEI/2+ADJPY, WID, HEI);
318                         for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
319                         //for(i=0; i<argn; i++) glVertexAttrib1d(argv[i], *(arga+i));
320                                 glVertex2f(rect.getRight()+1, rect.getTop());
321                         glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
322                         //glMultiTexCoord4d(GL_TEXTURE0,  WID/2+ADJPX,  HEI/2+ADJPY, WID, HEI);
323                         for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
324                         //for(i=0; i<argn; i++) glVertexAttrib1d(argv[i], *(arga+i));
325                                 glVertex2f(rect.getRight()+1, rect.getBottom()+1);
326                         glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
327                         //glMultiTexCoord4d(GL_TEXTURE0, -WID/2+ADJPX,  HEI/2+ADJPY, WID, HEI);
328                         for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
329                         //for(i=0; i<argn; i++) glVertexAttrib1d(argv[i], *(arga+i));
330                                 glVertex2f(rect.getLeft(),  rect.getBottom()+1);
331                 glEnd();
332                 glActiveTexture(GL_TEXTURE0);
333                 glDisable(GL_TEXTURE_2D);
334                 glUseProgram(0);
335         }
336         void ShaderAPI::fieldToImage(Image &target, const Rectangle &rect, const double *argv, const int argn, Canvas &media)
337         {
338                 //Rectangle rect2(rect.getWidth(), rect.getHeight());
339                 glDrawBuffer(GL_AUX0);
340                 glReadBuffer(GL_AUX0);
341                 media.rect(rect, Color::black);
342                 drawField(rect, argv, argn);
343                 media.to(target, rect);
344                 glDrawBuffer(GL_BACK);
345                 glReadBuffer(GL_BACK);
346         }\r
347 \r
348
349         int ceil2n(int x) {
350                  return pow(2, ceil(log((double)x)/log(2.0)));
351         }
352         void ShaderAPI::drawImage(Image &img, const double *arga, const int argn, Canvas &target)
353         {
354                 if(img.caches.count(&target)!=0) {
355                         APIImageCache *api_ = img.caches[&target].id;
356                         double tex_top = 1.0;
357                         double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;
358                         const double WID = img.targetarea_.getWidth(), HEI = img.targetarea_.getHeight();
359                         const double left = img.targetarea_.getLeft(), top = img.targetarea_.getTop(),
360                                      right = left+WID, bottom = top+HEI;
361                         //const double PX = left+WID/2+.5, PY =top+HEI/2-HEI+.5;
362                         const double PX = left+.5, PY = target.getHeight()-top+.5;
363                         int i;
364
365                         glUseProgram(gl2Program);
366                         glUniform1i(texture[0], 0);
367                         glUniform2i(size,     WID, HEI);
368                         glUniform2i(size_log, api_->tex_width, api_->tex_height);
369                         glEnable(GL_TEXTURE_2D);
370                         glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
371                         glBegin(GL_QUADS);
372                                 glMultiTexCoord2d(GL_TEXTURE0, 0, tex_top);
373                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
374                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
375                                         glVertex2f(left, top);
376                                 glMultiTexCoord2d(GL_TEXTURE0, (double)img.width_/api_->tex_width , tex_top);
377                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
378                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
379                                         glVertex2f(right, top);
380                                 glMultiTexCoord2d(GL_TEXTURE0, (double)img.width_/api_->tex_width , tex_bottom);
381                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
382                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
383                                         glVertex2f(right, bottom);
384                                 glMultiTexCoord2d(GL_TEXTURE0, 0 , tex_bottom);
385                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
386                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
387                                         glVertex2f(left, bottom);
388                         glEnd();
389                         glActiveTexture(GL_TEXTURE0);
390                         glDisable(GL_TEXTURE_2D);
391                         glUseProgram(0);
392                 } else {
393                 }
394         }
395         void ShaderAPI::imageToImage(Image &target, Image &img, const double *argv, const int argn, Canvas &media)
396         {
397                 glDrawBuffer(GL_AUX0);
398                 glReadBuffer(GL_AUX0);
399                 drawImage(img, argv, argn, media);
400                 media.to(target, Rectangle(img.getLeft(), img.getTop(), img.getRight(), img.getBottom()));
401                 glDrawBuffer(GL_BACK);
402                 glReadBuffer(GL_BACK);
403         }\r
404         void ShaderAPI::drawImage(Image &img, const double *arga, const int argn, Image &arg_img, Canvas &target)\r
405         {\r
406                 if(img.caches.count(&target)!=0 && arg_img.caches.count(&target)!=0) {\r
407                         APIImageCache *api_ = img.caches[&target].id;\r
408                         APIImageCache *arg_api_ = arg_img.caches[&target].id;\r
409                         double tex_top = 1.0;\r
410                         double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;\r
411                         const double WID = img.targetarea_.getWidth(), HEI = img.targetarea_.getHeight();\r
412                         const double left = img.targetarea_.getLeft(), top = img.targetarea_.getTop(),\r
413                                      right = left+WID, bottom = top+HEI;\r
414                         //const double PX = left+WID/2+.5, PY =top+HEI/2-HEI+.5;\r
415                         const double PX = left+.5, PY = target.getHeight()-top+.5;\r
416                         int i;\r
417 \r
418                         glUseProgram(gl2Program);\r
419                         glUniform1i(texture[0], 0);\r
420                         glUniform1i(texture[1], 1);\r
421                         glUniform2i(size,     WID, HEI);\r
422                         glUniform2i(size_log, api_->tex_width, api_->tex_height);\r
423 \r
424                         glActiveTexture(GL_TEXTURE0);\r
425                         glEnable(GL_TEXTURE_2D);\r
426                         glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());\r
427 \r
428                         glActiveTexture(GL_TEXTURE1);\r
429                         glEnable(GL_TEXTURE_2D);\r
430                         glBindTexture(GL_TEXTURE_2D, arg_api_->getTexIndex());\r
431 \r
432                         glBegin(GL_QUADS);\r
433                                 glMultiTexCoord2d(GL_TEXTURE0, 0, tex_top);\r
434                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);\r
435                                 glMultiTexCoord2d(GL_TEXTURE1, 0, 0);\r
436                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);\r
437                                         glVertex2f(left, top);\r
438                                 glMultiTexCoord2d(GL_TEXTURE0, (double)img.width_/api_->tex_width , tex_top);\r
439                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);\r
440                                 glMultiTexCoord2d(GL_TEXTURE1, 15, 0);\r
441                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);\r
442                                         glVertex2f(right, top);\r
443                                 glMultiTexCoord2d(GL_TEXTURE0, (double)img.width_/api_->tex_width , tex_bottom);\r
444                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);\r
445                                 glMultiTexCoord2d(GL_TEXTURE1, 15, 15);\r
446                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);\r
447                                         glVertex2f(right, bottom);\r
448                                 glMultiTexCoord2d(GL_TEXTURE0, 0 , tex_bottom);\r
449                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);\r
450                                 glMultiTexCoord2d(GL_TEXTURE1, 0, 15);\r
451                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);\r
452                                         glVertex2f(left, bottom);\r
453                         glEnd();\r
454 \r
455                         glDisable(GL_TEXTURE_2D);\r
456                         glActiveTexture(GL_TEXTURE0);\r
457                         glDisable(GL_TEXTURE_2D);\r
458 \r
459                         glUseProgram(0);\r
460                 } else {\r
461                 }\r
462         }
463
464
465 }       /*      <- namespace Psycholops         */