]> Dogcows Code - chaz/yoink/blob - src/moof/video.cc
further implementing runloop support
[chaz/yoink] / src / moof / video.cc
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #include <sstream>
13 #include <stdexcept>
14
15 #include "dispatcher.hh"
16 #include "image.hh"
17 #include "log.hh"
18 #include "settings.hh"
19 #include "video.hh"
20
21
22 namespace moof {
23
24
25 video::video(const std::string& caption)
26 {
27 video::caption(caption);
28 init();
29 }
30
31 video::video(const class attributes& attribs) :
32 attributes_(attribs)
33 {
34 init();
35 }
36
37 video::video(const std::string& caption,
38 const class attributes& attribs) :
39 attributes_(attribs)
40 {
41 video::caption(caption);
42 init();
43 }
44
45 void video::init()
46 {
47 context_ = 0;
48 flags_ = 0;
49
50 fullscreen(attributes_.is_fullscreen);
51 resizable(attributes_.is_resizable);
52 set_opengl_attributes();
53 cursor_visible(attributes_.is_cursor_visible);
54 cursor_captured(attributes_.is_cursor_captured);
55 mode(attributes_.mode);
56
57 if (!current_) make_current();
58
59 show_fps(false);
60 }
61
62 void video::recreate_context()
63 {
64 SDL_FreeSurface(context_);
65 context_ = 0;
66 mode(attributes_.mode);
67 }
68
69 void video::set_opengl_attributes()
70 {
71 SDL_GL_SetAttribute(SDL_GL_RED_SIZE,
72 attributes_.color_buffer[0]);
73 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,
74 attributes_.color_buffer[1]);
75 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,
76 attributes_.color_buffer[2]);
77 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,
78 attributes_.color_buffer[3]);
79 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,
80 attributes_.frame_buffer);
81 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,
82 attributes_.is_double_buffer);
83 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,
84 attributes_.depth_buffer);
85 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,
86 attributes_.stencil_buffer);
87 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE,
88 attributes_.accumulator_buffer[0]);
89 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE,
90 attributes_.accumulator_buffer[1]);
91 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,
92 attributes_.accumulator_buffer[2]);
93 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE,
94 attributes_.accumulator_buffer[3]);
95 SDL_GL_SetAttribute(SDL_GL_STEREO,
96 attributes_.is_stereo);
97 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,
98 attributes_.multisample_buffers);
99 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,
100 attributes_.multisample_samples);
101 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL,
102 attributes_.is_swap_control);
103 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
104 attributes_.is_hardware_only);
105 }
106
107
108 video::~video()
109 {
110 SDL_FreeSurface(context_);
111
112 if (current_ == this) current_ = 0;
113 }
114
115
116 class video::attributes video::attributes() const
117 {
118 return attributes_;
119 }
120
121
122 void video::mode(const int mode[3])
123 {
124 if (mode != attributes_.mode || !context_)
125 {
126 if (context_) SDL_FreeSurface(context_);
127
128 context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2],
129 SDL_OPENGL | flags_);
130
131 if (context_)
132 {
133 attributes_.mode[0] = mode[0];
134 attributes_.mode[1] = mode[1];
135 attributes_.mode[2] = mode[2];
136
137 #if !defined(linux) && !defined(__linux) && !defined(__linux__)
138 log_info("video context recreated");
139 dispatcher::global().dispatch("video.newcontext");
140 #endif
141 }
142 else
143 {
144 throw std::runtime_error("bad video mode attempted");
145 }
146 }
147 }
148
149
150 void video::resize(int width, int height)
151 {
152 int mode[] = {width, height, attributes_.mode[2]};
153 video::mode(mode);
154 }
155
156 bool video::iconify()
157 {
158 return SDL_WM_IconifyWindow();
159 }
160
161
162 void video::caption(const std::string& caption)
163 {
164 caption_ = caption;
165 SDL_WM_SetCaption(caption.c_str(), 0);
166 }
167
168 const std::string& video::caption() const
169 {
170 return caption_;
171 //char* caption;
172 //SDL_WM_GetCaption(&caption, 0);
173 //return std::string(caption);
174 }
175
176
177 void video::fullscreen(bool full)
178 {
179 if (full != fullscreen() || !context_)
180 {
181 if (context_)
182 {
183 flags_ ^= SDL_FULLSCREEN;
184
185 #if defined(linux) || defined(__linux) || defined(__linux__)
186 if (SDL_WM_ToggleFullScreen(context_) == 0)
187 #endif
188 recreate_context();
189 }
190 else
191 {
192 if (full) flags_ |= SDL_FULLSCREEN;
193 else flags_ &= ~SDL_FULLSCREEN;
194 }
195 }
196 }
197
198 bool video::fullscreen() const
199 {
200 return flags_ & SDL_FULLSCREEN;
201 }
202
203 void video::toggle_fullscreen()
204 {
205 fullscreen(!fullscreen());
206 }
207
208
209 void video::resizable(bool is_resizable)
210 {
211 if (is_resizable != resizable() || !context_)
212 {
213 if (context_)
214 {
215 flags_ ^= SDL_RESIZABLE;
216 recreate_context();
217 }
218 else
219 {
220 if (is_resizable) flags_ |= SDL_RESIZABLE;
221 else flags_ &= ~SDL_RESIZABLE;
222 }
223 }
224 }
225
226 bool video::resizable() const
227 {
228 return flags_ & SDL_RESIZABLE;
229 }
230
231 void video::toggle_resizable()
232 {
233 resizable(!resizable());
234 }
235
236
237 void video::cursor_visible(bool is_cursor_visible)
238 {
239 SDL_ShowCursor(is_cursor_visible? SDL_ENABLE : SDL_DISABLE);
240 }
241
242 bool video::cursor_visible() const
243 {
244 return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE);
245 }
246
247 void video::toggle_cursor_visible()
248 {
249 cursor_visible(!cursor_visible());
250 }
251
252
253 bool video::cursor_captured() const
254 {
255 return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
256 }
257
258 void video::cursor_captured(bool is_cursor_captured)
259 {
260 SDL_WM_GrabInput(is_cursor_captured? SDL_GRAB_ON : SDL_GRAB_OFF);
261 }
262
263 void video::toggle_cursor_captured()
264 {
265 cursor_captured(!cursor_captured());
266 }
267
268
269 void video::swap(scalar t)
270 {
271 if (show_fps_)
272 {
273 scalar dt = t - last_swap_;
274 last_swap_ = t;
275
276 fps_accumulator_ += dt;
277 if (SCALAR(1.0) <= fps_accumulator_)
278 {
279 std::ostringstream stream;
280 stream << caption_ << " - " << fps_counter_ << " fps";
281 SDL_WM_SetCaption(stream.str().c_str(), 0);
282
283 fps_accumulator_ -= SCALAR(1.0);
284 fps_counter_ = 0;
285 }
286
287 ++fps_counter_;
288 }
289
290 SDL_GL_SwapBuffers();
291 }
292
293
294 int video::width() const
295 {
296 return context_->w;
297 }
298
299 int video::height() const
300 {
301 return context_->h;
302 }
303
304
305 void video::make_current() const
306 {
307 current_ = const_cast<video*>(this);
308 }
309
310
311 video::attributes::attributes()
312 {
313 init();
314 }
315
316 video::attributes::attributes(const settings& settings)
317 {
318 init();
319
320 std::vector<int> colors;
321 settings.get("colorbuffers", colors);
322 if (colors.size() > 0) color_buffer[0] = colors[0];
323 if (colors.size() > 1) color_buffer[1] = colors[1];
324 if (colors.size() > 2) color_buffer[2] = colors[2];
325 if (colors.size() > 3) color_buffer[3] = colors[3];
326
327 settings.get("framebuffer", frame_buffer);
328 settings.get("doublebuffer", is_double_buffer);
329 settings.get("depthbuffer", depth_buffer);
330 settings.get("stencilbuffer", stencil_buffer);
331
332 std::vector<int> accum;
333 settings.get("accumbuffers", accum);
334 if (accum.size() > 0) accumulator_buffer[0] = accum[0];
335 if (accum.size() > 1) accumulator_buffer[1] = accum[1];
336 if (accum.size() > 2) accumulator_buffer[2] = accum[2];
337 if (accum.size() > 3) accumulator_buffer[3] = accum[3];
338
339 settings.get("stereo", is_stereo);
340 settings.get("multiesamplebuffers", multisample_buffers);
341 settings.get("multiesamplesamples", multisample_samples);
342 settings.get("swapcontrol", is_swap_control);
343 settings.get("hardwareonly", is_hardware_only);
344
345 settings.get("fullscreen", is_fullscreen);
346 settings.get("resizable", is_resizable);
347 settings.get("showcursor", is_cursor_visible);
348 settings.get("capturecursor", is_cursor_captured);
349
350 std::vector<int> dimensions;
351 settings.get("videomode", dimensions);
352 if (dimensions.size() > 1)
353 {
354 mode[0] = dimensions[0];
355 mode[1] = dimensions[1];
356 }
357 else if (is_fullscreen && backend::is_initialized())
358 {
359 SDL_Rect** modes = SDL_ListModes(NULL,
360 SDL_FULLSCREEN | SDL_HWSURFACE);
361
362 if (modes == (SDL_Rect**)0)
363 {
364 throw std::runtime_error("can't find appropriate video mode");
365 }
366 else if (modes == (SDL_Rect**)-1)
367 {
368 log_warning("any resolution allowed; choosing default 800x600");
369 mode[0] = 800;
370 mode[1] = 600;
371 }
372 else
373 {
374 mode[0] = (*modes)->w;
375 mode[1] = (*modes)->h;
376 log_info << "choosing native resolution: "
377 << mode[0] << "x" << mode[1] << std::endl;
378 }
379 }
380 if (dimensions.size() > 2) mode[2] = dimensions[2];
381 }
382
383 void video::attributes::init()
384 {
385 // set some sane GL and window defaults (see SDL_video.c:217)
386 color_buffer[0] = 3;
387 color_buffer[1] = 3;
388 color_buffer[2] = 2;
389 color_buffer[3] = 0;
390 frame_buffer = 0;
391 is_double_buffer = true;
392 depth_buffer = 16;
393 stencil_buffer = 0;
394 accumulator_buffer[0] = 0;
395 accumulator_buffer[1] = 0;
396 accumulator_buffer[2] = 0;
397 accumulator_buffer[3] = 0;
398 is_stereo = false;
399 multisample_buffers = 0;
400 multisample_samples = 0;
401 is_swap_control = false;
402 is_hardware_only = false;
403 mode[0] = 640;
404 mode[1] = 480;
405 mode[2] = 0;
406 is_fullscreen = false;
407 is_resizable = false;
408 is_cursor_visible = true;
409 is_cursor_captured = false;
410 }
411
412
413 video* video::current_ = 0; // most recently instantiated instance
414
415
416 } // namespace moof
417
This page took 0.052047 seconds and 4 git commands to generate.