2 * psychlops_g_shader_Win32GL.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
9 #define PSYCHLOPS_SHADER_PLATFORM
10 #include "../../../platform/psychlops_platform_selector.h"
12 #include "psychlops_g_shader_gl.h"
18 static char *shader_const_source[16];
19 static int shader_const_source_n;
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"
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)); }"
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); }"
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
49 " gl_FragColor = vec4(toBitsL(r), toBitsL(g), toBitsL(b), aa);\r\n"
\r
50 // " gl_FragColor = vec4(r, g, b, 1.0);"
\r
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"
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); }"
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); }"
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"
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"
107 const char* ShaderAPI::shader_figure_funcs_platform =
108 "uniform vec4 UNIFORM_PARAMETER;\r\n"
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
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"
132 const char* ShaderAPI::shader_texture_pix[2] = {
138 void ShaderAPI::initializeInstance()
\r
146 void ShaderAPI::cacheVertex(const std::string &final_source, Drawable &target)
\r
150 const char *source = final_source.c_str();
\r
151 GLint length = final_source.length();
\r
153 std::string errormsg;
\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
166 glGetShaderInfoLog(vertShader, logSize, &logSize, logbuf);
\r
170 throw new Exception(typeid(*this), "Shader compile failed", errormsg);
\r
173 if(gl2Program==0) gl2Program = glCreateProgram();
\r
174 glAttachShader(gl2Program, vertShader);
\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
181 void ShaderAPI::cache(const std::string &final_source, const std::vector<std::string> &vars, Drawable &target)
186 const char *source = final_source.c_str();
187 GLint length = final_source.length();
189 std::string errormsg;
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;
202 glGetShaderInfoLog(fragShader, logSize, &logSize, logbuf);
206 throw new Exception(typeid(*this), "Shader compile failed", errormsg);
209 if(gl2Program==0) gl2Program = glCreateProgram();
210 glAttachShader(gl2Program, fragShader);
212 glLinkProgram(gl2Program);
213 glGetProgramiv(gl2Program, GL_LINK_STATUS, &linked);
214 if(linked == GL_FALSE) throw new Exception("Shader link failed");
216 void ShaderAPI::cacheField(const std::string &orig_source, const std::vector<std::string> &vars, Drawable &target)
218 //std::string final_source = "#version 130\r\n#extension GL_EXT_gpu_shader4 : enable\r\n\r\n";
219 std::string final_source = "";
222 if(Color::getCalibrationMode() == Color::BITS_MONO) mode = 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;
232 final_source.append(shader_core_pix);
233 // final_source.append(shader_core_getpix);
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);
241 void ShaderAPI::cacheTex(const std::string &orig_source, const std::vector<std::string> &vars, Drawable &target, int opt)
243 std::string final_source = "";
246 final_source.append(shader_texture_funcs_platform2);
\r
248 final_source.append(shader_texture_funcs_platform);
\r
252 if(Color::getCalibrationMode() == Color::BITS_MONO) mode = 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;
262 final_source.append(shader_core_pix);
263 final_source.append(shader_core_getpix);
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
271 texture[1] = glGetUniformLocation(gl2Program, "texture1");
\r
273 size = glGetUniformLocation(gl2Program, "SIZE_REAL");
274 size_log = glGetUniformLocation(gl2Program, "SIZE_LOG");
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()
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;
295 void drawFigure(Figure &fig, const double *argv, const int argn, Drawable &target)
298 void ShaderAPI::drawField(const Rectangle &rect, const double *arga, const int argn)
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);
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);
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);
332 glActiveTexture(GL_TEXTURE0);
333 glDisable(GL_TEXTURE_2D);
336 void ShaderAPI::fieldToImage(Image &target, const Rectangle &rect, const double *argv, const int argn, Canvas &media)
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);
350 return pow(2, ceil(log((double)x)/log(2.0)));
352 void ShaderAPI::drawImage(Image &img, const double *arga, const int argn, Canvas &target)
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;
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());
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);
389 glActiveTexture(GL_TEXTURE0);
390 glDisable(GL_TEXTURE_2D);
395 void ShaderAPI::imageToImage(Image &target, Image &img, const double *argv, const int argn, Canvas &media)
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);
404 void ShaderAPI::drawImage(Image &img, const double *arga, const int argn, Image &arg_img, Canvas &target)
\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
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
424 glActiveTexture(GL_TEXTURE0);
\r
425 glEnable(GL_TEXTURE_2D);
\r
426 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
\r
428 glActiveTexture(GL_TEXTURE1);
\r
429 glEnable(GL_TEXTURE_2D);
\r
430 glBindTexture(GL_TEXTURE_2D, arg_api_->getTexIndex());
\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
455 glDisable(GL_TEXTURE_2D);
\r
456 glActiveTexture(GL_TEXTURE0);
\r
457 glDisable(GL_TEXTURE_2D);
\r
465 } /* <- namespace Psycholops */