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