00001
00002 #include "vgui_utils.h"
00003
00004
00005
00006
00007
00008
00009 #include <vcl_cstdlib.h>
00010 #include <vcl_cassert.h>
00011 #include <vcl_iostream.h>
00012
00013 #include <vil1/vil1_rgba.h>
00014 #include <vil1/vil1_save.h>
00015
00016 #include <vgui/vgui_gl.h>
00017 #include <vgui/vgui_glu.h>
00018
00019 #include <vil/vil_rgba.h>
00020
00021
00022
00023 vil1_memory_image_of<vil1_rgb<GLubyte> > vgui_utils::get_image()
00024 {
00025
00026 GLint cur_read_buffer;
00027 glGetIntegerv( GL_READ_BUFFER, &cur_read_buffer );
00028 glReadBuffer( GL_FRONT );
00029
00030
00031 GLint vp[4];
00032 glGetIntegerv(GL_VIEWPORT, vp);
00033 unsigned x = vp[0];
00034 unsigned y = vp[1];
00035 unsigned w = vp[2];
00036 unsigned h = vp[3];
00037
00038
00039
00040 vil1_rgba<GLubyte> *pixels = new vil1_rgba<GLubyte>[ w * h ];
00041
00042
00043 glPixelZoom(1,1);
00044 glPixelTransferi(GL_MAP_COLOR,0);
00045 glPixelTransferi(GL_RED_SCALE,1); glPixelTransferi(GL_RED_BIAS,0);
00046 glPixelTransferi(GL_GREEN_SCALE,1); glPixelTransferi(GL_GREEN_BIAS,0);
00047 glPixelTransferi(GL_BLUE_SCALE,1); glPixelTransferi(GL_BLUE_BIAS,0);
00048
00049
00050 glPixelStorei(GL_PACK_ALIGNMENT,1);
00051 glPixelStorei(GL_PACK_ROW_LENGTH,0);
00052 glPixelStorei(GL_PACK_SKIP_PIXELS,0);
00053 glPixelStorei(GL_PACK_SKIP_ROWS,0);
00054
00055
00056 glReadPixels(x, y,
00057 w, h,
00058 GL_RGBA,
00059 GL_UNSIGNED_BYTE,
00060 pixels);
00061
00062 glReadBuffer( cur_read_buffer );
00063
00064
00065
00066 vil1_memory_image_of<vil1_rgb<GLubyte> > colour_buffer(w, h);
00067 for (unsigned yy=0; yy<h; ++yy)
00068 for (unsigned xx=0; xx<w; ++xx) {
00069 colour_buffer(xx, h-1-yy).r = pixels[xx + w*yy].r;
00070 colour_buffer(xx, h-1-yy).g = pixels[xx + w*yy].g;
00071 colour_buffer(xx, h-1-yy).b = pixels[xx + w*yy].b;
00072 }
00073
00074
00075 delete [] pixels;
00076 return colour_buffer;
00077 }
00078
00079
00080 vil1_memory_image_of<vil1_rgb<unsigned char> >
00081 vgui_utils::colour_buffer_to_image()
00082 {
00083 vil1_memory_image_of<vil1_rgb<GLubyte> > colour_buffer =
00084 vgui_utils::get_image();
00085 vil1_memory_image_of<vil1_rgb<unsigned char> > temp(colour_buffer);
00086 return temp;
00087 }
00088
00089
00090 void vgui_utils::dump_colour_buffer(char const *file)
00091 {
00092 vil1_memory_image_of<vil1_rgb<GLubyte> > colour_buffer =
00093 vgui_utils::get_image();
00094 vil1_save(colour_buffer, file);
00095 }
00096
00097
00098
00099 vil_image_view<GLubyte>
00100 vgui_utils::get_view()
00101 {
00102
00103 GLint vp[4];
00104 glGetIntegerv(GL_VIEWPORT, vp);
00105 unsigned x = vp[0];
00106 unsigned y = vp[1];
00107 unsigned w = vp[2];
00108 unsigned h = vp[3];
00109
00110
00111
00112 vil_rgba<GLubyte> *pixels = new vil_rgba<GLubyte>[ w * h ];
00113
00114
00115 glPixelZoom(1,1);
00116 glPixelTransferi(GL_MAP_COLOR,0);
00117 glPixelTransferi(GL_RED_SCALE,1); glPixelTransferi(GL_RED_BIAS,0);
00118 glPixelTransferi(GL_GREEN_SCALE,1); glPixelTransferi(GL_GREEN_BIAS,0);
00119 glPixelTransferi(GL_BLUE_SCALE,1); glPixelTransferi(GL_BLUE_BIAS,0);
00120
00121
00122 glPixelStorei(GL_PACK_ALIGNMENT,1);
00123 glPixelStorei(GL_PACK_ROW_LENGTH,0);
00124 glPixelStorei(GL_PACK_SKIP_PIXELS,0);
00125 glPixelStorei(GL_PACK_SKIP_ROWS,0);
00126
00127
00128 glReadPixels(x, y,
00129 w, h,
00130 GL_RGBA,
00131 GL_UNSIGNED_BYTE,
00132 pixels);
00133
00134
00135
00136 vil_image_view<GLubyte> view(w, h, 1, 3);
00137 for (unsigned yy=0; yy<h; ++yy)
00138 for (unsigned xx=0; xx<w; ++xx) {
00139 view(xx, h-1-yy, 0) = pixels[xx + w*yy].r;
00140 view(xx, h-1-yy, 1) = pixels[xx + w*yy].g;
00141 view(xx, h-1-yy, 2) = pixels[xx + w*yy].b;
00142 }
00143
00144
00145 delete [] pixels;
00146 return view;
00147 }
00148
00149
00150
00151 vil_image_view<vxl_byte>
00152 vgui_utils::colour_buffer_to_view()
00153 {
00154 vil_image_view<GLubyte> buffer = vgui_utils::get_view();
00155 vil_image_view<vxl_byte> temp(buffer);
00156 return temp;
00157 }
00158
00159
00160
00161
00162
00163
00164 void vgui_utils::do_copy()
00165 {
00166
00167
00168 GLint vp[4];
00169 glGetIntegerv(GL_VIEWPORT, vp);
00170
00171
00172 glMatrixMode(GL_MODELVIEW);
00173 glPushMatrix();
00174 glLoadIdentity();
00175
00176 glMatrixMode(GL_PROJECTION);
00177 glPushMatrix();
00178 glLoadIdentity();
00179 glOrtho(0,vp[2], 0,vp[3], -1,+1);
00180
00181
00182 glRasterPos2i(0, 0);
00183
00184
00185 glMatrixMode(GL_MODELVIEW);
00186 glPopMatrix();
00187
00188 glMatrixMode(GL_PROJECTION);
00189 glPopMatrix();
00190
00191
00192 glPixelZoom(1,1);
00193 glPixelTransferi(GL_MAP_COLOR,0);
00194 glPixelTransferi(GL_RED_SCALE,1); glPixelTransferi(GL_RED_BIAS,0);
00195 glPixelTransferi(GL_GREEN_SCALE,1); glPixelTransferi(GL_GREEN_BIAS,0);
00196 glPixelTransferi(GL_BLUE_SCALE,1); glPixelTransferi(GL_BLUE_BIAS,0);
00197 glPixelTransferi(GL_ALPHA_SCALE,1); glPixelTransferi(GL_ALPHA_BIAS,0);
00198 glDisable(GL_DITHER);
00199 glCopyPixels(0,0,
00200 vp[2],vp[3],
00201 GL_COLOR);
00202 }
00203
00204 void vgui_utils::copy_front_to_back()
00205 {
00206 GLint old_read,old_draw;
00207 glGetIntegerv(GL_READ_BUFFER,&old_read);
00208 glGetIntegerv(GL_DRAW_BUFFER,&old_draw);
00209
00210 glReadBuffer(GL_FRONT);
00211 glDrawBuffer(GL_BACK);
00212 vgui_utils::do_copy();
00213
00214 glReadBuffer(GLenum(old_read));
00215 glDrawBuffer(GLenum(old_draw));
00216 }
00217
00218 void vgui_utils::copy_back_to_front()
00219 {
00220 GLint old_read,old_draw;
00221 glGetIntegerv(GL_READ_BUFFER,&old_read);
00222 glGetIntegerv(GL_DRAW_BUFFER,&old_draw);
00223
00224 glReadBuffer(GL_BACK);
00225 glDrawBuffer(GL_FRONT);
00226 vgui_utils::do_copy();
00227
00228 glReadBuffer(GLenum(old_read));
00229 glDrawBuffer(GLenum(old_draw));
00230 }
00231
00232
00233
00234 static GLint gl_old_buffer = -1;
00235
00236 void vgui_utils::begin_sw_overlay()
00237 {
00238 glGetIntegerv(GL_DRAW_BUFFER, &gl_old_buffer);
00239 if (gl_old_buffer != GL_NONE)
00240 glDrawBuffer(GL_FRONT);
00241 }
00242
00243 void vgui_utils::end_sw_overlay()
00244 {
00245 if (gl_old_buffer == -1) {
00246 vcl_cerr << "WARNING : end_sw_overlay called before begin_sw_overlay\n";
00247 return;
00248 }
00249
00250 glFlush();
00251
00252 glDrawBuffer((GLenum)gl_old_buffer);
00253
00254 gl_old_buffer = -1;
00255 }
00256
00257
00258 static bool in_pick_mode = false;
00259
00260 GLuint* vgui_utils::enter_pick_mode(float x,float y,float w,float h)
00261 {
00262 assert(!in_pick_mode); in_pick_mode = true;
00263
00264 if (h==0) h=w;
00265
00266 static unsigned const HIT_BUFFER_SIZE=4096;
00267 static GLuint buffer[HIT_BUFFER_SIZE];
00268
00269
00270 glSelectBuffer(HIT_BUFFER_SIZE,buffer);
00271
00272
00273 GLint viewport[4];
00274 glGetIntegerv(GL_VIEWPORT, viewport);
00275
00276
00277 glRenderMode(GL_SELECT);
00278
00279
00280 glInitNames();
00281
00282
00283 glMatrixMode(GL_PROJECTION);
00284 glPushMatrix();
00285
00286 float P[16];
00287 glGetFloatv(GL_PROJECTION_MATRIX,P);
00288
00289 glLoadIdentity();
00290 gluPickMatrix(x,y,w,h,viewport);
00291
00292 glMultMatrixf(P);
00293
00294 return buffer;
00295 }
00296
00297
00298 unsigned vgui_utils::leave_pick_mode()
00299 {
00300 assert(in_pick_mode); in_pick_mode = false;
00301
00302
00303 glMatrixMode(GL_PROJECTION);
00304 glPopMatrix();
00305 return glRenderMode(GL_RENDER);
00306 }
00307
00308 void vgui_utils::process_hits(int num_hits, GLuint* ptr, vcl_vector<vcl_vector<unsigned> >& hits)
00309 {
00310 #ifdef DEBUG
00311 vcl_cerr << "hits = " << num_hits << vcl_endl;
00312 #endif
00313
00314 for (int i = 0; i < num_hits; i++) {
00315 GLuint num_names = *ptr;
00316 #ifdef DEBUG
00317 vcl_cerr << "number of names for hit["<< i <<"] = " << num_names << vcl_endl;
00318 #endif
00319 ptr++;
00320 #ifdef DEBUG
00321 vcl_cerr << " z1 is " << *ptr;
00322 #endif
00323 ptr++;
00324 #ifdef DEBUG
00325 vcl_cerr << "; z2 is " << *ptr << vcl_endl;
00326 #endif
00327 ptr++;
00328
00329 vcl_vector<unsigned> names;
00330 #ifdef DEBUG
00331 vcl_cerr << " the name is ";
00332 #endif
00333
00334 for (unsigned int j = 0; j < num_names; j++) {
00335 names.push_back(*ptr);
00336 #ifdef DEBUG
00337 vcl_cerr << *ptr << ' ';
00338 #endif
00339 ptr++;
00340 }
00341 #ifdef DEBUG
00342 vcl_cerr << vcl_endl << "names.size() " << names.size() << vcl_endl;
00343 #endif
00344 hits.push_back(names);
00345
00346 #ifdef DEBUG
00347 vcl_cerr << vcl_endl;
00348 #endif
00349 }
00350 #ifdef DEBUG
00351 vcl_cerr << "hits.size() " << hits.size() << vcl_endl;
00352 #endif
00353 }
00354
00355
00356 int
00357 vgui_utils::bits_per_pixel(GLenum format, GLenum type)
00358 {
00359 #define M(f, t, size) if (format == f && type == t) return size;
00360 M(GL_RGB, GL_UNSIGNED_BYTE, 24);
00361 M(GL_BGR, GL_UNSIGNED_BYTE, 24);
00362 M(GL_RGBA, GL_UNSIGNED_BYTE, 32);
00363 #if defined(GL_UNSIGNED_SHORT_5_6_5)
00364 M(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 16);
00365 #endif
00366 #if defined(GL_UNSIGNED_SHORT_5_5_5_1)
00367 M(GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, 16);
00368 #endif
00369 #if defined(GL_BGRA)
00370 M(GL_BGRA, GL_UNSIGNED_BYTE, 32);
00371 #endif
00372 #if defined(GL_EXT_abgr) || defined(GL_ABGR_EXT)
00373 M(GL_ABGR_EXT, GL_UNSIGNED_BYTE, 32);
00374 #endif
00375 #undef M
00376
00377 vcl_cerr << "vgui_utils::bits_per_pixel: UNKNOWN COMBO, format = " << format << ", type = " << type << vcl_endl;
00378 vcl_abort();
00379 return 0;
00380 }