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
|
---|