00001
00002 #include "vgui_glut_adaptor.h"
00003
00004
00005
00006
00007 #include "vgui_glut_window.h"
00008 #include "vgui_glut_popup_impl.h"
00009 #include "menu_hack.h"
00010
00011 #include <vcl_cassert.h>
00012 #include <vcl_cstdlib.h>
00013 #include <vcl_iostream.h>
00014 #include <vcl_algorithm.h>
00015
00016 #include <vgui/vgui_glut.h>
00017 #include <vgui/vgui_macro.h>
00018 #include <vgui/vgui_popup_params.h>
00019 #include <vgui/internals/vgui_overlay_helper.h>
00020
00021
00022
00023 vgui_glut_adaptor::vgui_glut_adaptor( vgui_window *win_, int id_ )
00024 : vgui_adaptor()
00025
00026 , id(id_)
00027 , win(win_)
00028
00029 , popup_modifier(vgui_MODIFIER_NULL)
00030 , popup_button(vgui_BUTTON_NULL)
00031
00032
00033 , ovl_established( false )
00034 , ovl_helper( 0 )
00035
00036 , super(0)
00037
00038 , popup(0)
00039 {
00040 all().push_back(this);
00041 register_static_callbacks();
00042 }
00043
00044 vgui_glut_adaptor::~vgui_glut_adaptor()
00045 {
00046
00047 if (ovl_helper)
00048 delete ovl_helper;
00049 ovl_helper = 0;
00050
00051
00052 glutDestroyWindow( id );
00053 id = 0;
00054 win = 0;
00055
00056
00057 if (popup)
00058 delete popup;
00059 popup = 0;
00060
00061
00062 for (unsigned i=0; i<sub_contexts.size(); ++i)
00063 delete sub_contexts[i];
00064 sub_contexts.clear();
00065
00066
00067 vcl_vector<vgui_glut_adaptor*>::iterator it = vcl_find(all().begin(), all().end(), this);
00068 assert(it != all().end());
00069 all().erase(it);
00070 }
00071
00072
00073
00074 void vgui_glut_adaptor::swap_buffers()
00075 {
00076
00077 int old = glutGetWindow();
00078 glutSetWindow( id );
00079 glutSwapBuffers();
00080 glutSetWindow( old );
00081 }
00082
00083 void vgui_glut_adaptor::make_current()
00084 {
00085 glutSetWindow( id );
00086 }
00087
00088 unsigned vgui_glut_adaptor::get_width() const
00089 {
00090 int old = glutGetWindow();
00091 glutSetWindow( id );
00092 unsigned val = glutGet(GLenum(GLUT_WINDOW_WIDTH));
00093 glutSetWindow( old );
00094 return val;
00095 }
00096
00097 unsigned vgui_glut_adaptor::get_height() const
00098 {
00099 int old = glutGetWindow();
00100 glutSetWindow( id );
00101 unsigned val = glutGet(GLenum(GLUT_WINDOW_HEIGHT));
00102 glutSetWindow( old );
00103 return val;
00104 }
00105
00106 void vgui_glut_adaptor::post_redraw()
00107 {
00108 int old = glutGetWindow();
00109 glutSetWindow( id );
00110 glutPostRedisplay();
00111 glutSetWindow( old );
00112 }
00113
00114 void vgui_glut_adaptor::post_overlay_redraw()
00115 {
00116 int old = glutGetWindow();
00117 glutSetWindow( id );
00118 establish_overlays();
00119 if (ovl_helper)
00120 ovl_helper->post_overlay_redraw();
00121 else
00122 glutPostOverlayRedisplay();
00123 glutSetWindow( old );
00124 }
00125
00126 extern void vgui_glut_impl_quit();
00127
00128 void vgui_glut_adaptor::post_destroy()
00129 {
00130
00131
00132 vgui_glut_impl_quit();
00133 }
00134
00135
00136
00137 extern bool vgui_emulate_overlays;
00138
00139
00140
00141
00142 void vgui_glut_adaptor::establish_overlays()
00143 {
00144
00145 if (ovl_established)
00146 return;
00147
00148
00149 make_current();
00150 bool use_hardware;
00151 if (vgui_emulate_overlays || getenv("vgui_emulate_overlays") != 0)
00152 use_hardware = false;
00153 else {
00154 glutInitDisplayMode( GLUT_RGBA | GLUT_SINGLE );
00155 use_hardware = glutLayerGet(GLenum(GLUT_OVERLAY_POSSIBLE)) != 0;
00156 if (!use_hardware) {
00157
00158
00159 glutInitDisplayMode( GLUT_INDEX | GLUT_SINGLE );
00160 use_hardware = glutLayerGet(GLenum(GLUT_OVERLAY_POSSIBLE)) != 0;
00161 }
00162 }
00163
00164
00165 if (use_hardware) {
00166 glutEstablishOverlay();
00167
00168 glutOverlayDisplayFunc(overlay_display_callback);
00169
00170 glutUseLayer(GLenum(GLUT_NORMAL));
00171 vcl_cerr << "GLUT hardware overlay established\n";
00172 }
00173 else {
00174 assert(! ovl_helper);
00175 ovl_helper = new vgui_overlay_helper(this);
00176 vcl_cerr << "emulation overlay helper established\n";
00177 }
00178
00179
00180 ovl_established = true;
00181 }
00182
00183 bool vgui_glut_adaptor::glut_dispatch(vgui_event &e)
00184 {
00185 if (win)
00186 static_cast<vgui_glut_window*>(win)->hello_from_adaptor();
00187
00188
00189 e.wy = get_height()-1 - e.wy;
00190
00191
00192 if (e.type == vgui_DRAW_OVERLAY)
00193 establish_overlays();
00194
00195
00196 if (ovl_helper)
00197 return ovl_helper->dispatch(e);
00198
00199
00200 else {
00201
00202 if (e.type == vgui_DRAW) {
00203
00204
00205
00206 bool f = dispatch_to_tableau(e);
00207 #ifdef DUMP_FRAME
00208 fsm_hook();
00209 #endif
00210 swap_buffers();
00211 return f;
00212 }
00213
00214
00215 else if (e.type == vgui_DRAW_OVERLAY)
00216 {
00217
00218
00219
00220
00221 GLboolean is_index_mode;
00222 glGetBooleanv(GL_INDEX_MODE, &is_index_mode);
00223 if (is_index_mode)
00224 {
00225
00226 int index = glutLayerGet(GLenum(GLUT_TRANSPARENT_INDEX));
00227 {
00228 static bool once=false;
00229 if (!once)
00230 {
00231 GLint bits;
00232 glGetIntegerv(GL_INDEX_BITS, &bits);
00233 vcl_cerr << __FILE__ ": color index information:\n";
00234 int cmapsize = glutGet(GLenum(GLUT_WINDOW_COLORMAP_SIZE));
00235 vcl_cerr << " color map size is " << cmapsize << vcl_endl
00236 << " transparent color index is " << index << vcl_endl
00237 << " # color index bits is " << bits << vcl_endl;
00238
00239
00240
00241
00242
00243 glutSetColor(0, 0, 0, 0);
00244 glutSetColor(1, 0, 0, 1);
00245 glutSetColor(2, 0, 1, 0);
00246 glutSetColor(3, 0, 1, 1);
00247 glutSetColor(4, 1, 0, 0);
00248 glutSetColor(5, 1, 0, 1);
00249 glutSetColor(6, 1, 1, 0);
00250 glutSetColor(7, 1, 1, 1);
00251 int tmp = cmapsize; tmp = 8; ++tmp;
00252 #if 1
00253 for (int cell=0; cell<tmp; ++cell)
00254 vcl_cerr << cell << ':'
00255 << glutGetColor(cell, GLUT_RED) << ' '
00256 << glutGetColor(cell, GLUT_GREEN) << ' '
00257 << glutGetColor(cell, GLUT_BLUE) << vcl_endl;
00258 #endif
00259 once=true;
00260 }
00261 }
00262 glClearIndex(index);
00263 }
00264 else
00265 glClearColor(0,0,0,0);
00266
00267
00268
00269 glClear(GL_COLOR_BUFFER_BIT);
00270
00271
00272 return dispatch_to_tableau(e);
00273 }
00274
00275
00276 else
00277 return dispatch_to_tableau(e);
00278 }
00279 }
00280
00281
00282
00283 void vgui_glut_adaptor::register_static_callbacks()
00284 {
00285 make_current();
00286 glutDisplayFunc(display_callback);
00287
00288 glutReshapeFunc(reshape_callback);
00289 glutKeyboardFunc(keyboard_callback);
00290 glutMouseFunc(mouse_callback);
00291 glutMotionFunc(motion_callback);
00292 glutPassiveMotionFunc(passive_motion_callback);
00293 glutEntryFunc(entry_callback);
00294 glutVisibilityFunc(visibility_callback);
00295
00296
00297
00298 glutSpecialFunc(special_callback);
00299 #if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) && !defined(VCL_KAI) //wrong
00300 glutKeyboardUpFunc(keyboard_up_callback);
00301 glutSpecialUpFunc(special_up_callback);
00302 #endif
00303
00304 glutMenuStatusFunc(menustatus_callback);
00305 }
00306
00307
00308
00309 vcl_vector<vgui_glut_adaptor*> &vgui_glut_adaptor::all()
00310 {
00311 static vcl_vector<vgui_glut_adaptor*> *the_vector = 0;
00312 if (!the_vector)
00313 the_vector = new vcl_vector<vgui_glut_adaptor*>;
00314 return *the_vector;
00315 }
00316
00317 vgui_glut_adaptor *vgui_glut_adaptor::get_adaptor(int window_id)
00318 {
00319 vcl_vector<vgui_glut_adaptor*> &all = vgui_glut_adaptor::all();
00320 for (unsigned i=0; i<all.size(); ++i)
00321 if (all[i]->id == window_id)
00322 return all[i];
00323 vgui_macro_warning << "window id " << window_id << " is not a glut context\n";
00324 return 0;
00325 }
00326
00327
00328
00329
00330
00331
00332 void vgui_glut_adaptor::display()
00333 {
00334 if (glutLayerGet(GLenum(GLUT_LAYER_IN_USE)) != GLUT_NORMAL)
00335 vgui_macro_warning << "*** current layer is overlay\n";
00336
00337
00338 vgui_event e(vgui_DRAW);
00339 glut_dispatch(e);
00340 }
00341
00342 void vgui_glut_adaptor::overlay_display()
00343 {
00344 if (glutLayerGet(GLenum(GLUT_LAYER_IN_USE)) != GLUT_OVERLAY)
00345 vgui_macro_warning << "*** current layer is normal\n";
00346
00347 {
00348 GLint isdouble=0;
00349 glGetIntegerv(GL_DOUBLEBUFFER, &isdouble);
00350 if (isdouble)
00351 vgui_macro_warning << "overlay plane is double buffered\n";
00352 }
00353
00354
00355 vgui_event e(vgui_DRAW_OVERLAY);
00356 glut_dispatch(e);
00357 }
00358
00359
00360 static void do_modifiers(vgui_event &e)
00361 {
00362 static vgui_modifier last_mods = vgui_MODIFIER_NULL;
00363
00364 if (e.type == vgui_KEY_PRESS ||
00365 e.type == vgui_KEY_RELEASE ||
00366 e.type == vgui_BUTTON_DOWN ||
00367 e.type == vgui_BUTTON_UP) {
00368 int mods=glutGetModifiers();
00369 int modifier = 0;
00370 if (mods & GLUT_ACTIVE_CTRL)
00371 modifier |= vgui_CTRL;
00372 if (mods & GLUT_ACTIVE_SHIFT)
00373 modifier |= vgui_SHIFT;
00374 if (mods & GLUT_ACTIVE_ALT)
00375 modifier |= vgui_META;
00376 last_mods = vgui_modifier(modifier);
00377 }
00378
00379
00380 e.modifier = last_mods;
00381 }
00382 #if 0
00383 static void do_modifiers(vgui_event &e)
00384 {
00385 int mods=glutGetModifiers();
00386 int modifier = 0;
00387 if (mods & GLUT_ACTIVE_CTRL)
00388 modifier |= vgui_CTRL;
00389 if (mods & GLUT_ACTIVE_SHIFT)
00390 modifier |= vgui_SHIFT;
00391 if (mods & GLUT_ACTIVE_ALT)
00392 modifier |= vgui_META;
00393 e.modifier = vgui_modifier(modifier);
00394 }
00395 #endif
00396 #if 0
00397 #include <X11/X.h>
00398 extern unsigned __glutModifierMask;
00399 static void do_modifiers(vgui_event &e)
00400 {
00401 int modifier = 0;
00402 if (__glutModifierMask & ControlMask)
00403 modifier |= vgui_CTRL;
00404 if (__glutModifierMask & (ShiftMask|LockMask))
00405 modifier |= vgui_SHIFT;
00406 if (__glutModifierMask & Mod1Mask)
00407 modifier |= vgui_META;
00408 e.modifier = vgui_modifier(modifier);
00409 }
00410 #endif
00411
00412 static vgui_key xlate_key_code(unsigned char key)
00413 {
00414 switch (key)
00415 {
00416 case 127: return vgui_DELETE;
00417 default: return vgui_key(key);
00418 }
00419 }
00420
00421 void vgui_glut_adaptor::keyboard(unsigned char key,int x,int y)
00422 {
00423 vgui_event e(vgui_KEY_PRESS);
00424 do_modifiers(e);
00425 e.key = xlate_key_code(key);
00426 e.wx = x;
00427 e.wy = y;
00428 glut_dispatch(e);
00429 }
00430
00431 void vgui_glut_adaptor::keyboard_up(unsigned char key,int x,int y)
00432 {
00433 vgui_event e(vgui_KEY_RELEASE);
00434 do_modifiers(e);
00435 e.key = xlate_key_code(key);
00436 e.wx = x;
00437 e.wy = y;
00438 glut_dispatch(e);
00439 }
00440
00441 void vgui_glut_adaptor::mouse(int button,int state,int x,int y)
00442 {
00443 vgui_event e( (state == GLUT_DOWN) ? vgui_BUTTON_DOWN : vgui_BUTTON_UP );
00444 do_modifiers(e);
00445
00446 if (vgui_glut_menu_hack::mouse(button, state, x, y))
00447 return;
00448
00449 if (button == GLUT_LEFT_BUTTON)
00450 e.button = vgui_LEFT;
00451 else if (button == GLUT_MIDDLE_BUTTON)
00452 e.button = vgui_MIDDLE;
00453 else if (button == GLUT_RIGHT_BUTTON)
00454 e.button = vgui_RIGHT;
00455 else
00456 e.button = vgui_BUTTON_NULL;
00457 e.wx = x;
00458 e.wy = y;
00459 glut_dispatch(e);
00460 }
00461
00462 void vgui_glut_adaptor::reshape(int width,int height)
00463 {
00464 vgui_event e;
00465 e.type = vgui_RESHAPE;
00466 bool f=glut_dispatch(e);
00467 if (!f) {
00468 glViewport(0, 0, width, height);
00469 glScissor (0, 0, width, height);
00470 }
00471
00472
00473 for (unsigned i=0;i<sub_contexts.size();i++) {
00474
00475 vgui_macro_warning << "subcontext reshape not implemented\n";
00476 }
00477 }
00478
00479 void vgui_glut_adaptor::passive_motion(int x,int y)
00480 {
00481 vgui_event e(vgui_MOTION);
00482 do_modifiers(e);
00483 e.wx = x;
00484 e.wy = y;
00485 glut_dispatch(e);
00486 }
00487
00488 void vgui_glut_adaptor::motion(int x,int y)
00489 {
00490 vgui_event e(vgui_MOTION);
00491 do_modifiers(e);
00492 e.wx = x;
00493 e.wy = y;
00494 glut_dispatch(e);
00495 }
00496
00497 void vgui_glut_adaptor::timer(int value)
00498 {
00499 vgui_event e(vgui_TIMER);
00500 e.timer_id = value;
00501 glut_dispatch(e);
00502 }
00503
00504 void vgui_glut_adaptor::entry(int state)
00505 {
00506 vgui_event e( (state == GLUT_ENTERED) ? vgui_ENTER : vgui_LEAVE );
00507 glut_dispatch(e);
00508 }
00509
00510 void vgui_glut_adaptor::visibility(int )
00511 {
00512 }
00513
00514 static void xlate_special_key(int key,vgui_event &e)
00515 {
00516 switch (key)
00517 {
00518 case GLUT_KEY_LEFT: e.key = vgui_CURSOR_LEFT; break;
00519 case GLUT_KEY_UP: e.key = vgui_CURSOR_UP; break;
00520 case GLUT_KEY_RIGHT: e.key = vgui_CURSOR_RIGHT; break;
00521 case GLUT_KEY_DOWN: e.key = vgui_CURSOR_DOWN; break;
00522 case GLUT_KEY_PAGE_UP: e.key = vgui_PAGE_UP; break;
00523 case GLUT_KEY_PAGE_DOWN: e.key = vgui_PAGE_DOWN; break;
00524 case GLUT_KEY_HOME: e.key = vgui_HOME; break;
00525 case GLUT_KEY_END: e.key = vgui_END; break;
00526 case GLUT_KEY_INSERT: e.key = vgui_INSERT; break;
00527 case GLUT_KEY_F1: case GLUT_KEY_F2: case GLUT_KEY_F3: case GLUT_KEY_F4:
00528 case GLUT_KEY_F5: case GLUT_KEY_F6: case GLUT_KEY_F7: case GLUT_KEY_F8:
00529 case GLUT_KEY_F9: case GLUT_KEY_F10: case GLUT_KEY_F11: case GLUT_KEY_F12:
00530 e.key = vgui_key(vgui_F1 + key - GLUT_KEY_F1); break;
00531 default: e.key = vgui_key(key); break;
00532 }
00533 }
00534
00535 void vgui_glut_adaptor::special(int key,int x,int y)
00536 {
00537 vgui_event e(vgui_KEY_PRESS);
00538 do_modifiers(e);
00539 xlate_special_key(key,e);
00540 e.wx = x;
00541 e.wy = y;
00542 glut_dispatch(e);
00543 }
00544
00545 void vgui_glut_adaptor::special_up(int key,int x,int y)
00546 {
00547 vgui_event e(vgui_KEY_RELEASE);
00548 do_modifiers(e);
00549 xlate_special_key(key,e);
00550 e.wx = x;
00551 e.wy = y;
00552 glut_dispatch(e);
00553 }
00554
00555
00556
00557
00558
00559
00560 void vgui_glut_adaptor::pre_menu_hook(int menu_id)
00561 {
00562
00563
00564 for (unsigned i=0; i<all().size(); ++i) {
00565 vgui_glut_adaptor *ct = all()[i];
00566 if (ct->popup && ct->popup->menu_id==menu_id) {
00567 ct->make_popup();
00568 return;
00569 }
00570 }
00571 vgui_macro_warning << "unrecognised menu id " << menu_id << vcl_endl;
00572 }
00573
00574 void vgui_glut_adaptor::make_popup()
00575 {
00576 make_current();
00577
00578
00579 if (popup)
00580 popup->clear();
00581 else
00582 popup = new vgui_glut_popup_impl;
00583 {
00584 vgui_popup_params params;
00585 params.x = 0;
00586 params.y = 0;
00587 params.recurse = true;
00588 vgui_menu menu;
00589 if (win)
00590 menu.include( static_cast<vgui_glut_window*>(win)->menubar );
00591 menu.include( get_total_popup(params) );
00592 popup->build( menu );
00593 }
00594
00595
00596 int button = 0;
00597 switch (popup_button)
00598 {
00599 case vgui_LEFT:
00600 button = GLUT_LEFT_BUTTON;
00601 break;
00602 case vgui_MIDDLE:
00603 button = GLUT_MIDDLE_BUTTON;
00604 break;
00605 default:
00606 vgui_macro_warning << "unknown vgui_button - assuming right button\n";
00607 case vgui_RIGHT:
00608 button = GLUT_RIGHT_BUTTON;
00609 break;
00610 }
00611 #ifdef DEBUG
00612 vcl_cerr << "button = " << button << '\n';
00613 #endif
00614
00615
00616 int mods = 0;
00617 if (popup_modifier & vgui_CTRL)
00618 mods |= GLUT_ACTIVE_CTRL;
00619 if (popup_modifier & vgui_SHIFT)
00620 mods |= GLUT_ACTIVE_SHIFT;
00621 if (popup_modifier & vgui_ALT)
00622 mods |= GLUT_ACTIVE_ALT;
00623 #ifdef DEBUG
00624 vcl_cerr << "mods = " << mods << '\n';
00625 #endif
00626
00627
00628 vgui_glut_menu_hack::bind(button, mods, popup->menu_id);
00629 vgui_glut_menu_hack::last_minute_change_callback = pre_menu_hook;
00630 }
00631
00632 void vgui_glut_adaptor::bind_popups(vgui_modifier mod, vgui_button but)
00633 {
00634 popup_button = but;
00635 popup_modifier = mod;
00636 this->make_popup();
00637 }
00638
00639
00640
00641
00642
00643
00644 struct vgui_glut_adaptor_callback_data
00645 {
00646 vgui_glut_adaptor *org;
00647 int val;
00648 };
00649
00650 #include <vcl_utility.h>
00651 #include <vcl_list.h>
00652 typedef vcl_pair<void*, int> pair_Pv_i;
00653 typedef vcl_list<pair_Pv_i> list_Pv_i;
00654 static list_Pv_i *timer_posts = 0;
00655
00656
00657 void vgui_glut_adaptor::post_timer(float timeout, int name)
00658 {
00659 vgui_glut_adaptor_callback_data *ff = new vgui_glut_adaptor_callback_data;
00660 ff->org = this;
00661 ff->val = name;
00662
00663
00664 int value = 0;
00665 if (!timer_posts)
00666 timer_posts = new list_Pv_i;
00667 for (list_Pv_i::iterator i=timer_posts->begin(); i!=timer_posts->end(); ++i)
00668 if (value <= (*i).second)
00669 value = (*i).second + 1;
00670 timer_posts->push_front(pair_Pv_i(ff, value));
00671
00672
00673 glutTimerFunc(int(timeout), vgui_glut_adaptor::timer_callback, value);
00674 }
00675
00676 void vgui_glut_adaptor::timer_callback(int value)
00677 {
00678
00679 vgui_glut_adaptor_callback_data *ff = 0;
00680 assert(timer_posts);
00681 for (list_Pv_i::iterator i=timer_posts->begin(); i!=timer_posts->end(); ++i)
00682 if (value == (*i).second) {
00683 ff = static_cast<vgui_glut_adaptor_callback_data*>( (*i).first );
00684 timer_posts->erase(i);
00685 break;
00686 }
00687 assert(ff);
00688
00689 ff->org->timer(ff->val);
00690 delete ff;
00691 }
00692
00693
00694
00695
00696 void vgui_glut_adaptor::menustatus_callback(int status, int x, int y)
00697 {
00698 vgui_glut_menu_hack::menustatus(status,x,y);
00699 }
00700
00701
00702 #define implement_static_callback(name, proto, args) \
00703 void vgui_glut_adaptor::name##_callback proto \
00704 { \
00705 vgui_glut_adaptor *v=get_adaptor(glutGetWindow()); \
00706 if (v) v->name args; \
00707 else vcl_abort(); \
00708 }
00709
00710 implement_static_callback(display,(),());
00711 implement_static_callback(overlay_display,(),());
00712 implement_static_callback(reshape,(int width,int height),(width,height));
00713 implement_static_callback(keyboard,(unsigned char key,int x,int y),(key,x,y));
00714 implement_static_callback(keyboard_up,(unsigned char key,int x,int y),(key,x,y));
00715 implement_static_callback(mouse,(int button,int state,int x,int y),(button,state,x,y));
00716 implement_static_callback(visibility,(int state),(state));
00717 implement_static_callback(motion,(int x,int y),(x,y));
00718 implement_static_callback(entry,(int state),(state));
00719 implement_static_callback(passive_motion,(int x,int y),(x,y));
00720 implement_static_callback(special,(int key,int x,int y),(key,x,y));
00721 implement_static_callback(special_up,(int key,int x,int y),(key,x,y));
00722
00723
00724
00725 #ifdef DUMP_FRAME
00726 #include <vul/vul_sprintf.h>
00727 #include <vil1/vil1_save.h>
00728 #include <vil1/vil1_rgb.h>
00729 #include <vil1/vil1_rgba.h>
00730 #include <vil1/vil1_memory_image_of.h>
00731 static
00732 void fsm_dump(char const *file)
00733 {
00734
00735 GLint vp[4];
00736 glGetIntegerv(GL_VIEWPORT, vp);
00737 unsigned x = vp[0];
00738 unsigned y = vp[1];
00739 unsigned w = vp[2];
00740 unsigned h = vp[3];
00741
00742
00743
00744 static vil1_rgba<GLubyte> *pixels = 0;
00745 if (! pixels)
00746 pixels = new vil1_rgba<GLubyte>[ w * h ];
00747
00748
00749 glPixelZoom(1,1);
00750 glPixelTransferi(GL_MAP_COLOR,0);
00751 glPixelTransferi(GL_RED_SCALE,1); glPixelTransferi(GL_RED_BIAS,0);
00752 glPixelTransferi(GL_GREEN_SCALE,1); glPixelTransferi(GL_GREEN_BIAS,0);
00753 glPixelTransferi(GL_BLUE_SCALE,1); glPixelTransferi(GL_BLUE_BIAS,0);
00754
00755
00756 glPixelStorei(GL_PACK_ALIGNMENT,1);
00757 glPixelStorei(GL_PACK_ROW_LENGTH,0);
00758 glPixelStorei(GL_PACK_SKIP_PIXELS,0);
00759 glPixelStorei(GL_PACK_SKIP_ROWS,0);
00760
00761
00762 glReadBuffer(GL_BACK);
00763
00764
00765 glReadPixels(x, y,
00766 w, h,
00767 GL_RGBA,
00768 GL_UNSIGNED_BYTE,
00769 pixels);
00770
00771
00772
00773 static vil1_memory_image_of<vil1_rgb<GLubyte> > colour_buffer;
00774 colour_buffer.resize(w, h);
00775
00776 for (unsigned yy=0; yy<h; ++yy)
00777 for (unsigned xx=0; xx<w; ++xx) {
00778 colour_buffer(xx, h-1-yy).r = pixels[xx + w*yy].r;
00779 colour_buffer(xx, h-1-yy).g = pixels[xx + w*yy].g;
00780 colour_buffer(xx, h-1-yy).b = pixels[xx + w*yy].b;
00781 }
00782
00783
00784 vil1_save(colour_buffer, file, "pnm");
00785 }
00786
00787 bool fsm_hook_flag = false;
00788 static
00789 void fsm_hook()
00790 {
00791 if (fsm_hook_flag) {
00792 static int frame_counter = 0;
00793 fsm_dump(vul_sprintf("/tmp/dump%03d.pnm", frame_counter++).c_str());
00794 }
00795 }
00796 #endif