[852] | 1 | /*
|
---|
| 2 | glh - is a platform-indepenedent C++ OpenGL helper library
|
---|
| 3 |
|
---|
| 4 |
|
---|
| 5 | Copyright (c) 2000 Cass Everitt
|
---|
| 6 | Copyright (c) 2000 NVIDIA Corporation
|
---|
| 7 | All rights reserved.
|
---|
| 8 |
|
---|
| 9 | Redistribution and use in source and binary forms, with or
|
---|
| 10 | without modification, are permitted provided that the following
|
---|
| 11 | conditions are met:
|
---|
| 12 |
|
---|
| 13 | * Redistributions of source code must retain the above
|
---|
| 14 | copyright notice, this list of conditions and the following
|
---|
| 15 | disclaimer.
|
---|
| 16 |
|
---|
| 17 | * Redistributions in binary form must reproduce the above
|
---|
| 18 | copyright notice, this list of conditions and the following
|
---|
| 19 | disclaimer in the documentation and/or other materials
|
---|
| 20 | provided with the distribution.
|
---|
| 21 |
|
---|
| 22 | * The names of contributors to this software may not be used
|
---|
| 23 | to endorse or promote products derived from this software
|
---|
| 24 | without specific prior written permission.
|
---|
| 25 |
|
---|
| 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
---|
| 27 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
---|
| 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
---|
| 29 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
---|
| 30 | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
---|
| 31 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
---|
| 32 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
---|
| 33 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
---|
| 34 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
---|
| 35 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
---|
| 36 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
---|
| 37 | POSSIBILITY OF SUCH DAMAGE.
|
---|
| 38 |
|
---|
| 39 |
|
---|
| 40 | Cass Everitt - cass@r3.nu
|
---|
| 41 | */
|
---|
| 42 |
|
---|
| 43 | #ifndef GLH_GLUT_REPLAY_H
|
---|
| 44 | #define GLH_GLUT_REPLAY_H
|
---|
| 45 |
|
---|
| 46 | // a facility for recording and playing back glut events
|
---|
| 47 |
|
---|
| 48 | #include <list>
|
---|
| 49 | #include <glh/glh_glut.h>
|
---|
| 50 |
|
---|
| 51 | namespace glh
|
---|
| 52 | {
|
---|
| 53 |
|
---|
| 54 |
|
---|
| 55 | struct glut_event
|
---|
| 56 | {
|
---|
| 57 | enum event_type
|
---|
| 58 | {
|
---|
| 59 | DISPLAY, IDLE, KEYBOARD, MENU_STATUS, MOTION, MOUSE,
|
---|
| 60 | PASSIVE_MOTION, RESHAPE, SPECIAL, TIMER, VISIBILITY
|
---|
| 61 | };
|
---|
| 62 | glut_event(event_type t) : type(t) {}
|
---|
| 63 | virtual ~glut_event() {}
|
---|
| 64 | virtual void dispatch() = 0;
|
---|
| 65 | const event_type type;
|
---|
| 66 | };
|
---|
| 67 |
|
---|
| 68 | struct glut_display_event : public glut_event
|
---|
| 69 | {
|
---|
| 70 | glut_display_event() : glut_event(DISPLAY) {}
|
---|
| 71 | virtual void dispatch() { glut_display_function(); }
|
---|
| 72 | };
|
---|
| 73 |
|
---|
| 74 | struct glut_idle_event : public glut_event
|
---|
| 75 | {
|
---|
| 76 | glut_idle_event() : glut_event(IDLE) {}
|
---|
| 77 | virtual void dispatch() { glut_idle_function(); }
|
---|
| 78 | };
|
---|
| 79 |
|
---|
| 80 | struct glut_keyboard_event : public glut_event
|
---|
| 81 | {
|
---|
| 82 | glut_keyboard_event(unsigned char key, int xpos, int ypos)
|
---|
| 83 | : glut_event(KEYBOARD), k(key), x(xpos), y(ypos)
|
---|
| 84 | {}
|
---|
| 85 | virtual void dispatch() { glut_keyboard_function(k,x,y); }
|
---|
| 86 | unsigned char k;
|
---|
| 87 | int x, y;
|
---|
| 88 | };
|
---|
| 89 |
|
---|
| 90 | struct glut_menu_status_event : public glut_event
|
---|
| 91 | {
|
---|
| 92 | glut_menu_status_event(int status, int xpos, int ypos)
|
---|
| 93 | : glut_event(MENU_STATUS), s(status), x(xpos), y(ypos)
|
---|
| 94 | {}
|
---|
| 95 | virtual void dispatch() { glut_menu_status_function(s,x,y); }
|
---|
| 96 | int s, x, y;
|
---|
| 97 | };
|
---|
| 98 |
|
---|
| 99 | struct glut_motion_event : public glut_event
|
---|
| 100 | {
|
---|
| 101 | glut_motion_event(int xpos, int ypos)
|
---|
| 102 | : glut_event(MOTION), x(xpos), y(ypos)
|
---|
| 103 | {}
|
---|
| 104 | virtual void dispatch() { glut_motion_function(x,y); }
|
---|
| 105 | int x, y;
|
---|
| 106 | };
|
---|
| 107 |
|
---|
| 108 | struct glut_mouse_event : public glut_event
|
---|
| 109 | {
|
---|
| 110 | glut_mouse_event(int button, int state, int xpos, int ypos)
|
---|
| 111 | : glut_event(MOUSE), b(button), s(state), x(xpos), y(ypos)
|
---|
| 112 | {}
|
---|
| 113 | virtual void dispatch() { glut_mouse_function(b,s,x,y); }
|
---|
| 114 | int b, s, x, y;
|
---|
| 115 | };
|
---|
| 116 |
|
---|
| 117 | struct glut_passive_motion_event : public glut_event
|
---|
| 118 | {
|
---|
| 119 | glut_passive_motion_event(int xpos, int ypos)
|
---|
| 120 | : glut_event(PASSIVE_MOTION), x(xpos), y(ypos)
|
---|
| 121 | {}
|
---|
| 122 | virtual void dispatch() { glut_passive_motion_function(x,y); }
|
---|
| 123 | int x, y;
|
---|
| 124 | };
|
---|
| 125 |
|
---|
| 126 | struct glut_reshape_event : public glut_event
|
---|
| 127 | {
|
---|
| 128 | glut_reshape_event(int width, int height)
|
---|
| 129 | : glut_event(RESHAPE), w(width), h(height)
|
---|
| 130 | {}
|
---|
| 131 | virtual void dispatch() { glut_reshape_function(w,h); }
|
---|
| 132 | int w, h;
|
---|
| 133 | };
|
---|
| 134 |
|
---|
| 135 | struct glut_special_event : public glut_event
|
---|
| 136 | {
|
---|
| 137 | glut_special_event(int key, int xpos, int ypos)
|
---|
| 138 | : glut_event(SPECIAL), k(key), x(xpos), y(ypos)
|
---|
| 139 | {}
|
---|
| 140 | virtual void dispatch() { glut_special_function(k,x,y); }
|
---|
| 141 | int k, x, y;
|
---|
| 142 | };
|
---|
| 143 |
|
---|
| 144 | struct glut_timer_event : public glut_event
|
---|
| 145 | {
|
---|
| 146 | glut_timer_event(int value)
|
---|
| 147 | : glut_event(TIMER), v(value)
|
---|
| 148 | {}
|
---|
| 149 | virtual void dispatch() { glut_timer_function(v); }
|
---|
| 150 | int v;
|
---|
| 151 | };
|
---|
| 152 |
|
---|
| 153 | struct glut_visibility_event : public glut_event
|
---|
| 154 | {
|
---|
| 155 | glut_visibility_event(int visibility)
|
---|
| 156 | : glut_event(VISIBILITY), v(visibility)
|
---|
| 157 | {}
|
---|
| 158 | virtual void dispatch() { glut_visibility_function(v); }
|
---|
| 159 | int v;
|
---|
| 160 | };
|
---|
| 161 |
|
---|
| 162 |
|
---|
| 163 |
|
---|
| 164 | struct glut_replay : public glut_interactor
|
---|
| 165 | {
|
---|
| 166 | enum recorder_mode
|
---|
| 167 | {
|
---|
| 168 | RECORD, PLAY, STOP
|
---|
| 169 | };
|
---|
| 170 |
|
---|
| 171 | glut_replay()
|
---|
| 172 | {
|
---|
| 173 | it = event_list.end();
|
---|
| 174 | mode = STOP;
|
---|
| 175 | paused = false;
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | virtual ~glut_replay()
|
---|
| 179 | { erase(); }
|
---|
| 180 |
|
---|
| 181 | virtual void display()
|
---|
| 182 | {
|
---|
| 183 | if(enabled && RECORD == mode && ! paused)
|
---|
| 184 | event_list.push_back(new glut_display_event());
|
---|
| 185 | }
|
---|
| 186 | virtual void idle()
|
---|
| 187 | {
|
---|
| 188 | if(enabled && RECORD == mode && ! paused)
|
---|
| 189 | event_list.push_back(new glut_idle_event());
|
---|
| 190 | }
|
---|
| 191 | virtual void keyboard(unsigned char key, int x, int y)
|
---|
| 192 | {
|
---|
| 193 | if(enabled && RECORD == mode && ! paused)
|
---|
| 194 | event_list.push_back(new glut_keyboard_event(key,x,y));
|
---|
| 195 | }
|
---|
| 196 | virtual void menu_status(int status, int x, int y)
|
---|
| 197 | {
|
---|
| 198 | if(enabled && RECORD == mode && ! paused)
|
---|
| 199 | event_list.push_back(new glut_menu_status_event(status,x,y));
|
---|
| 200 | }
|
---|
| 201 | virtual void motion(int x, int y)
|
---|
| 202 | {
|
---|
| 203 | if(enabled && RECORD == mode && ! paused)
|
---|
| 204 | event_list.push_back(new glut_motion_event(x,y));
|
---|
| 205 | }
|
---|
| 206 | virtual void mouse(int button, int state, int x, int y)
|
---|
| 207 | {
|
---|
| 208 | if(enabled && RECORD == mode && ! paused)
|
---|
| 209 | event_list.push_back(new glut_mouse_event(button,state,x,y));
|
---|
| 210 | }
|
---|
| 211 | virtual void passive_motion(int x, int y)
|
---|
| 212 | {
|
---|
| 213 | if(enabled && RECORD == mode && ! paused)
|
---|
| 214 | event_list.push_back(new glut_passive_motion_event(x,y));
|
---|
| 215 | }
|
---|
| 216 | virtual void reshape(int w, int h)
|
---|
| 217 | {
|
---|
| 218 | if(enabled && RECORD == mode && ! paused)
|
---|
| 219 | event_list.push_back(new glut_reshape_event(w,h));
|
---|
| 220 | }
|
---|
| 221 | virtual void special(int key, int x, int y)
|
---|
| 222 | {
|
---|
| 223 | if(enabled)
|
---|
| 224 | {
|
---|
| 225 | if (key == GLUT_KEY_F6)
|
---|
| 226 | { mode = RECORD; glut_event_processed(); erase(); }
|
---|
| 227 | else if(key == GLUT_KEY_F7)
|
---|
| 228 | { mode = PLAY; glut_event_processed(); glutPostRedisplay(); }
|
---|
| 229 | else if(key == GLUT_KEY_F8)
|
---|
| 230 | { mode = STOP; glut_event_processed(); }
|
---|
| 231 | else if(key == GLUT_KEY_F9)
|
---|
| 232 | { paused = !paused; glut_event_processed(); glutPostRedisplay(); }
|
---|
| 233 | else if(RECORD == mode)
|
---|
| 234 | { event_list.push_back(new glut_special_event(key,x,y)); }
|
---|
| 235 | }
|
---|
| 236 | }
|
---|
| 237 | virtual void timer(int value)
|
---|
| 238 | {
|
---|
| 239 | if(enabled && RECORD == mode && ! paused)
|
---|
| 240 | event_list.push_back(new glut_timer_event(value));
|
---|
| 241 | }
|
---|
| 242 | virtual void visibility(int v)
|
---|
| 243 | {
|
---|
| 244 | if(enabled && RECORD == mode && ! paused)
|
---|
| 245 | event_list.push_back(new glut_visibility_event(v));
|
---|
| 246 | }
|
---|
| 247 |
|
---|
| 248 |
|
---|
| 249 | // other methods
|
---|
| 250 |
|
---|
| 251 | bool playing() { return mode == PLAY; }
|
---|
| 252 |
|
---|
| 253 | void dispatch_accumulated_events()
|
---|
| 254 | {
|
---|
| 255 | if(mode == PLAY && ! paused)
|
---|
| 256 | {
|
---|
| 257 | while(it != event_list.end() && (*it)->type != glut_event::DISPLAY)
|
---|
| 258 | {
|
---|
| 259 | (*it)->dispatch();
|
---|
| 260 | it++;
|
---|
| 261 | }
|
---|
| 262 | if(it == event_list.end())
|
---|
| 263 | {
|
---|
| 264 | mode = STOP;
|
---|
| 265 | it = event_list.begin();
|
---|
| 266 | }
|
---|
| 267 | else if ((*it)->type == glut_event::DISPLAY)
|
---|
| 268 | {
|
---|
| 269 | it++;
|
---|
| 270 | }
|
---|
| 271 | }
|
---|
| 272 | }
|
---|
| 273 |
|
---|
| 274 | void erase()
|
---|
| 275 | {
|
---|
| 276 | while(event_list.begin() != event_list.end())
|
---|
| 277 | {
|
---|
| 278 | glut_event * e = event_list.back();
|
---|
| 279 | event_list.pop_back();
|
---|
| 280 | delete e;
|
---|
| 281 | }
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | std::list<glut_event *> event_list;
|
---|
| 285 | std::list<glut_event *>::iterator it;
|
---|
| 286 | recorder_mode mode;
|
---|
| 287 | bool paused;
|
---|
| 288 | };
|
---|
| 289 |
|
---|
| 290 | }
|
---|
| 291 |
|
---|
| 292 | #endif
|
---|