2 /*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
3 **] All rights reserved.
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.
8 *****************************************************************************/
17 #include "dispatcher.hh"
20 #include "settings.hh"
27 video::video(const std::string
& caption
)
29 video::caption(caption
);
33 video::video(const class attributes
& attribs
) :
39 video::video(const std::string
& caption
,
40 const class attributes
& attribs
) :
43 video::caption(caption
);
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
);
59 if (!current_
) make_current();
64 void video::recreate_context()
66 SDL_FreeSurface(context_
);
68 mode(attributes_
.mode
);
71 void video::set_opengl_attributes()
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 attributes_
.multisample_buffers
);
101 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES
,
102 attributes_
.multisample_samples
);
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
);
111 SDL_FreeSurface(context_
);
112 if (current_
== this) current_
= 0;
115 class video::attributes
video::attributes() const
120 void video::mode(const int mode
[3])
122 if (mode
!= attributes_
.mode
|| !context_
)
124 if (context_
) SDL_FreeSurface(context_
);
126 context_
= SDL_SetVideoMode(mode
[0], mode
[1], mode
[2],
131 attributes_
.mode
[0] = mode
[0];
132 attributes_
.mode
[1] = mode
[1];
133 attributes_
.mode
[2] = mode
[2];
136 log_info("video context recreated");
137 dispatcher::global().dispatch("video.newcontext");
142 throw std::runtime_error("bad video mode attempted");
147 void video::resize(int width
, int height
)
149 int mode
[] = {width
, height
, attributes_
.mode
[2]};
153 bool video::iconify()
155 return SDL_WM_IconifyWindow();
158 void video::caption(const std::string
& caption
)
161 SDL_WM_SetCaption(caption
.c_str(), 0);
164 const std::string
& video::caption() const
169 void video::fullscreen(bool full
)
171 if (full
!= fullscreen() || !context_
)
175 flags_
^= SDL_FULLSCREEN
;
178 if (SDL_WM_ToggleFullScreen(context_
) == 0)
184 if (full
) flags_
|= SDL_FULLSCREEN
;
185 else flags_
&= ~SDL_FULLSCREEN
;
190 bool video::fullscreen() const
192 return flags_
& SDL_FULLSCREEN
;
195 void video::toggle_fullscreen()
197 fullscreen(!fullscreen());
200 void video::resizable(bool is_resizable
)
202 if (is_resizable
!= resizable() || !context_
)
206 flags_
^= SDL_RESIZABLE
;
211 if (is_resizable
) flags_
|= SDL_RESIZABLE
;
212 else flags_
&= ~SDL_RESIZABLE
;
217 bool video::resizable() const
219 return flags_
& SDL_RESIZABLE
;
222 void video::toggle_resizable()
224 resizable(!resizable());
227 void video::cursor_visible(bool is_cursor_visible
)
229 SDL_ShowCursor(is_cursor_visible
? SDL_ENABLE
: SDL_DISABLE
);
232 bool video::cursor_visible() const
234 return (SDL_ShowCursor(SDL_QUERY
) == SDL_ENABLE
);
237 void video::toggle_cursor_visible()
239 cursor_visible(!cursor_visible());
242 bool video::cursor_captured() const
244 return (SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
);
247 void video::cursor_captured(bool is_cursor_captured
)
249 SDL_WM_GrabInput(is_cursor_captured
? SDL_GRAB_ON
: SDL_GRAB_OFF
);
252 void video::toggle_cursor_captured()
254 cursor_captured(!cursor_captured());
257 void video::swap(scalar t
)
261 scalar dt
= t
- last_swap_
;
264 fps_accumulator_
+= dt
;
265 if (SCALAR(1.0) <= fps_accumulator_
)
267 std::ostringstream stream
;
268 stream
<< caption_
<< " - " << fps_counter_
<< " fps";
269 SDL_WM_SetCaption(stream
.str().c_str(), 0);
271 fps_accumulator_
-= SCALAR(1.0);
277 SDL_GL_SwapBuffers();
280 int video::width() const
285 int video::height() const
290 void video::make_current() const
292 current_
= const_cast<video
*>(this);
296 video::attributes::attributes()
301 video::attributes::attributes(const settings
& settings
)
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];
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
);
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];
324 settings
.get("stereo", is_stereo
);
325 settings
.get("multiesamplebuffers", multisample_buffers
);
326 settings
.get("multiesamplesamples", multisample_samples
);
327 settings
.get("swapcontrol", is_swap_control
);
328 settings
.get("hardwareonly", is_hardware_only
);
330 settings
.get("fullscreen", is_fullscreen
);
331 settings
.get("resizable", is_resizable
);
332 settings
.get("showcursor", is_cursor_visible
);
333 settings
.get("capturecursor", is_cursor_captured
);
335 std::vector
<int> dimensions
;
336 settings
.get("videomode", dimensions
);
337 if (dimensions
.size() > 1)
339 mode
[0] = dimensions
[0];
340 mode
[1] = dimensions
[1];
342 else if (is_fullscreen
&& backend::is_initialized())
344 SDL_Rect
** modes
= SDL_ListModes(NULL
, SDL_FULLSCREEN
| SDL_HWSURFACE
);
346 if (modes
== (SDL_Rect
**)0)
348 throw std::runtime_error("can't find appropriate video mode");
350 else if (modes
== (SDL_Rect
**)-1)
352 log_warning("any resolution allowed; choosing default 800x600");
358 mode
[0] = (*modes
)->w
;
359 mode
[1] = (*modes
)->h
;
360 log_info
<< "choosing native resolution: "
361 << mode
[0] << "x" << mode
[1] << std::endl
;
364 if (dimensions
.size() > 2) mode
[2] = dimensions
[2];
367 void video::attributes::init()
369 // set some sane GL and window defaults (see SDL_video.c:217)
375 is_double_buffer
= true;
378 accumulator_buffer
[0] = 0;
379 accumulator_buffer
[1] = 0;
380 accumulator_buffer
[2] = 0;
381 accumulator_buffer
[3] = 0;
383 multisample_buffers
= 0;
384 multisample_samples
= 0;
385 is_swap_control
= false;
386 is_hardware_only
= false;
390 is_fullscreen
= false;
391 is_resizable
= false;
392 is_cursor_visible
= true;
393 is_cursor_captured
= false;
397 video
* video::current_
= 0; // most recently instantiated instance