OSDN Git Service

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