OSDN Git Service

first
[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 = "";
219
220                 int mode = 0;
221                 if(Color::getCalibrationMode() == Color::BITS_MONO) mode = 3;
222                 switch(mode)
223                 {
224                 case 3:
225                         final_source.append(shader_core_pix_bitsmono);
226 //                      final_source.append(shader_core_getpix_bitsmono);
227                         //final_source.append(shader_core_getpix_bitsmono_bitshift);
228                         //final_source.append(shader_core_pix_bitsmono_bitshift;
229                         break;
230                 default:
231                         final_source.append(shader_core_pix);
232 //                      final_source.append(shader_core_getpix);
233                 }
234
235                 final_source.append(shader_base_funcs);
236                 final_source.append(shader_field_funcs_platform);
237                 final_source.append(orig_source);
238                 cache(final_source, vars, target);
239         }
240         void ShaderAPI::cacheTex(const std::string &orig_source, const std::vector<std::string> &vars, Drawable &target, int opt)
241         {
242                 std::string final_source = "";
243 \r
244                 if(opt==1) {\r
245                         final_source.append(shader_texture_funcs_platform2);\r
246                 } else {\r
247                         final_source.append(shader_texture_funcs_platform);\r
248                 }\r
249 \r
250                 int mode = 0;
251                 if(Color::getCalibrationMode() == Color::BITS_MONO) mode = 3;
252                 switch(mode)
253                 {
254                 case 3:
255                         final_source.append(shader_core_pix_bitsmono);
256                         final_source.append(shader_core_getpix_bitsmono);
257                         //final_source.append(shader_core_getpix_bitsmono_bitshift);
258                         //final_source.append(shader_core_pix_bitsmono_bitshift;
259                         break;
260                 default:
261                         final_source.append(shader_core_pix);
262                         final_source.append(shader_core_getpix);
263                 }
264
265                 final_source.append(shader_base_funcs);
266                 final_source.append(orig_source);
267                 cache(final_source, vars, target);
268                 texture[0] =  glGetUniformLocation(gl2Program, "texture0");\r
269                 if(opt==1) {\r
270                         texture[1] =  glGetUniformLocation(gl2Program, "texture1");\r
271                 }
272                 size     = glGetUniformLocation(gl2Program, "SIZE_REAL");
273                 size_log = glGetUniformLocation(gl2Program, "SIZE_LOG");
274         }
275
276
277         bool ShaderAPI::field_initialized = false;
278         GLuint ShaderAPI::null_texture;
279         const unsigned char ShaderAPI::NULL_TEX[16] = {0,0,0,0 ,0,0,0,0 ,0,0,0,0 ,0,0,0,0};
280         void ShaderAPI::initField()
281         {
282                 if(!field_initialized) {
283                         glEnable(GL_TEXTURE_2D);
284                         glGenTextures(1, &null_texture);
285                         glBindTexture(GL_TEXTURE_2D, null_texture);
286                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
287                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
288                         glTexImage2D(GL_TEXTURE_2D, 0, 1, 4, 4, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &NULL_TEX);
289                         glDisable(GL_TEXTURE_2D);
290                         field_initialized = true;
291                 }
292         }
293
294         void drawFigure(Figure &fig, const double *argv, const int argn, Drawable &target)
295         {
296         }
297         void ShaderAPI::drawField(const Rectangle &rect, const double *arga, const int argn)
298         {
299                 const double WID = rect.getWidth(), HEI = rect.getHeight();
300                 const double ADJPX = -0.125, ADJPY = -0.1255;
301                 const double PX = rect.getLeft()+WID/2+.5, PY = rect.getTop()+HEI/2-Display::getHeight()+.5;
302                 glUseProgram(gl2Program);
303                 int i=0;
304                 glEnable(GL_TEXTURE_2D);
305                 /*for(i=0; i<argn+1; i++) {
306                         glActiveTexture(GL_TEXTURE0+i);
307                         glBindTexture(GL_TEXTURE_2D, null_texture);
308                 }*/
309                 glBegin(GL_QUADS);
310                         glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
311                         //glMultiTexCoord4d(GL_TEXTURE0, -WID/2+ADJPX, -HEI/2+ADJPY, WID, HEI);
312                         for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
313                         //for(i=0; i<argn; i++) glVertexAttrib1d(argv[i], *(arga+i));
314                                 glVertex2f(rect.getLeft(),  rect.getTop());
315                         glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
316                         //glMultiTexCoord4d(GL_TEXTURE0,  WID/2+ADJPX, -HEI/2+ADJPY, WID, HEI);
317                         for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
318                         //for(i=0; i<argn; i++) glVertexAttrib1d(argv[i], *(arga+i));
319                                 glVertex2f(rect.getRight()+1, rect.getTop());
320                         glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
321                         //glMultiTexCoord4d(GL_TEXTURE0,  WID/2+ADJPX,  HEI/2+ADJPY, WID, HEI);
322                         for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
323                         //for(i=0; i<argn; i++) glVertexAttrib1d(argv[i], *(arga+i));
324                                 glVertex2f(rect.getRight()+1, rect.getBottom()+1);
325                         glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
326                         //glMultiTexCoord4d(GL_TEXTURE0, -WID/2+ADJPX,  HEI/2+ADJPY, WID, HEI);
327                         for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
328                         //for(i=0; i<argn; i++) glVertexAttrib1d(argv[i], *(arga+i));
329                                 glVertex2f(rect.getLeft(),  rect.getBottom()+1);
330                 glEnd();
331                 glActiveTexture(GL_TEXTURE0);
332                 glDisable(GL_TEXTURE_2D);
333                 glUseProgram(0);
334         }
335         void ShaderAPI::fieldToImage(Image &target, const Rectangle &rect, const double *argv, const int argn, Canvas &media)
336         {
337                 //Rectangle rect2(rect.getWidth(), rect.getHeight());
338                 glDrawBuffer(GL_AUX0);
339                 glReadBuffer(GL_AUX0);
340                 media.rect(rect, Color::black);
341                 drawField(rect, argv, argn);
342                 media.to(target, rect);
343                 glDrawBuffer(GL_BACK);
344                 glReadBuffer(GL_BACK);
345         }\r
346 \r
347
348         int ceil2n(int x) {
349                  return pow(2, ceil(log((double)x)/log(2.0)));
350         }
351         void ShaderAPI::drawImage(Image &img, const double *arga, const int argn, Canvas &target)
352         {
353                 if(img.caches.count(&target)!=0) {
354                         APIImageCache *api_ = img.caches[&target].id;
355                         double tex_top = 1.0;
356                         double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;
357                         const double WID = img.targetarea_.getWidth(), HEI = img.targetarea_.getHeight();
358                         const double left = img.targetarea_.getLeft(), top = img.targetarea_.getTop(),
359                                      right = left+WID, bottom = top+HEI;
360                         //const double PX = left+WID/2+.5, PY =top+HEI/2-HEI+.5;
361                         const double PX = left+.5, PY = target.getHeight()-top+.5;
362                         int i;
363
364                         glUseProgram(gl2Program);
365                         glUniform1i(texture[0], 0);
366                         glUniform2i(size,     WID, HEI);
367                         glUniform2i(size_log, api_->tex_width, api_->tex_height);
368                         glEnable(GL_TEXTURE_2D);
369                         glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
370                         glBegin(GL_QUADS);
371                                 glMultiTexCoord2d(GL_TEXTURE0, 0, tex_top);
372                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
373                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
374                                         glVertex2f(left, top);
375                                 glMultiTexCoord2d(GL_TEXTURE0, (double)img.width_/api_->tex_width , tex_top);
376                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
377                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
378                                         glVertex2f(right, top);
379                                 glMultiTexCoord2d(GL_TEXTURE0, (double)img.width_/api_->tex_width , tex_bottom);
380                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
381                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
382                                         glVertex2f(right, bottom);
383                                 glMultiTexCoord2d(GL_TEXTURE0, 0 , tex_bottom);
384                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);
385                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);
386                                         glVertex2f(left, bottom);
387                         glEnd();
388                         glActiveTexture(GL_TEXTURE0);
389                         glDisable(GL_TEXTURE_2D);
390                         glUseProgram(0);
391                 } else {
392                 }
393         }
394         void ShaderAPI::imageToImage(Image &target, Image &img, const double *argv, const int argn, Canvas &media)
395         {
396                 glDrawBuffer(GL_AUX0);
397                 glReadBuffer(GL_AUX0);
398                 drawImage(img, argv, argn, media);
399                 media.to(target, Rectangle(img.getLeft(), img.getTop(), img.getRight(), img.getBottom()));
400                 glDrawBuffer(GL_BACK);
401                 glReadBuffer(GL_BACK);
402         }\r
403         void ShaderAPI::drawImage(Image &img, const double *arga, const int argn, Image &arg_img, Canvas &target)\r
404         {\r
405                 if(img.caches.count(&target)!=0 && arg_img.caches.count(&target)!=0) {\r
406                         APIImageCache *api_ = img.caches[&target].id;\r
407                         APIImageCache *arg_api_ = arg_img.caches[&target].id;\r
408                         double tex_top = 1.0;\r
409                         double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;\r
410                         const double WID = img.targetarea_.getWidth(), HEI = img.targetarea_.getHeight();\r
411                         const double left = img.targetarea_.getLeft(), top = img.targetarea_.getTop(),\r
412                                      right = left+WID, bottom = top+HEI;\r
413                         //const double PX = left+WID/2+.5, PY =top+HEI/2-HEI+.5;\r
414                         const double PX = left+.5, PY = target.getHeight()-top+.5;\r
415                         int i;\r
416 \r
417                         glUseProgram(gl2Program);\r
418                         glUniform1i(texture[0], 0);\r
419                         glUniform1i(texture[1], 1);\r
420                         glUniform2i(size,     WID, HEI);\r
421                         glUniform2i(size_log, api_->tex_width, api_->tex_height);\r
422 \r
423                         glActiveTexture(GL_TEXTURE0);\r
424                         glEnable(GL_TEXTURE_2D);\r
425                         glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());\r
426 \r
427                         glActiveTexture(GL_TEXTURE1);\r
428                         glEnable(GL_TEXTURE_2D);\r
429                         glBindTexture(GL_TEXTURE_2D, arg_api_->getTexIndex());\r
430 \r
431                         glBegin(GL_QUADS);\r
432                                 glMultiTexCoord2d(GL_TEXTURE0, 0, tex_top);\r
433                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);\r
434                                 glMultiTexCoord2d(GL_TEXTURE1, 0, 0);\r
435                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);\r
436                                         glVertex2f(left, top);\r
437                                 glMultiTexCoord2d(GL_TEXTURE0, (double)img.width_/api_->tex_width , tex_top);\r
438                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);\r
439                                 glMultiTexCoord2d(GL_TEXTURE1, 15, 0);\r
440                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);\r
441                                         glVertex2f(right, top);\r
442                                 glMultiTexCoord2d(GL_TEXTURE0, (double)img.width_/api_->tex_width , tex_bottom);\r
443                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);\r
444                                 glMultiTexCoord2d(GL_TEXTURE1, 15, 15);\r
445                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);\r
446                                         glVertex2f(right, bottom);\r
447                                 glMultiTexCoord2d(GL_TEXTURE0, 0 , tex_bottom);\r
448                                 glMultiTexCoord4d(GL_TEXTURE3, PX, PY, WID, HEI);\r
449                                 glMultiTexCoord2d(GL_TEXTURE1, 0, 15);\r
450                                 for(i=0; i<argn; i++) glMultiTexCoord4dv(GL_TEXTURE4+i, arga+i*4);\r
451                                         glVertex2f(left, bottom);\r
452                         glEnd();\r
453 \r
454                         glDisable(GL_TEXTURE_2D);\r
455                         glActiveTexture(GL_TEXTURE0);\r
456                         glDisable(GL_TEXTURE_2D);\r
457 \r
458                         glUseProgram(0);\r
459                 } else {\r
460                 }\r
461         }
462
463
464 }       /*      <- namespace Psycholops         */