2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
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.
10 **************************************************************************/
15 #include "dispatcher.hh"
18 #include "settings.hh"
25 video::video(const std::string
& caption
)
27 video::caption(caption
);
31 video::video(const class attributes
& attribs
) :
37 video::video(const std::string
& caption
,
38 const class attributes
& attribs
) :
41 video::caption(caption
);
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
);
57 if (!current_
) make_current();
62 void video::recreate_context()
64 SDL_FreeSurface(context_
);
66 mode(attributes_
.mode
);
69 void video::set_opengl_attributes()
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
);
110 SDL_FreeSurface(context_
);
112 if (current_
== this) current_
= 0;
116 class video::attributes
video::attributes() const
122 void video::mode(const int mode
[3])
124 if (mode
!= attributes_
.mode
|| !context_
)
126 if (context_
) SDL_FreeSurface(context_
);
128 context_
= SDL_SetVideoMode(mode
[0], mode
[1], mode
[2],
129 SDL_OPENGL
| flags_
);
133 attributes_
.mode
[0] = mode
[0];
134 attributes_
.mode
[1] = mode
[1];
135 attributes_
.mode
[2] = mode
[2];
137 #if !defined(linux) && !defined(__linux) && !defined(__linux__)
138 log_info("video context recreated");
139 dispatcher::global().dispatch("video.newcontext");
144 throw std::runtime_error("bad video mode attempted");
150 void video::resize(int width
, int height
)
152 int mode
[] = {width
, height
, attributes_
.mode
[2]};
156 bool video::iconify()
158 return SDL_WM_IconifyWindow();
162 void video::caption(const std::string
& caption
)
165 SDL_WM_SetCaption(caption
.c_str(), 0);
168 const std::string
& video::caption() const
172 //SDL_WM_GetCaption(&caption, 0);
173 //return std::string(caption);
177 void video::fullscreen(bool full
)
179 if (full
!= fullscreen() || !context_
)
183 flags_
^= SDL_FULLSCREEN
;
185 #if defined(linux) || defined(__linux) || defined(__linux__)
186 if (SDL_WM_ToggleFullScreen(context_
) == 0)
192 if (full
) flags_
|= SDL_FULLSCREEN
;
193 else flags_
&= ~SDL_FULLSCREEN
;
198 bool video::fullscreen() const
200 return flags_
& SDL_FULLSCREEN
;
203 void video::toggle_fullscreen()
205 fullscreen(!fullscreen());
209 void video::resizable(bool is_resizable
)
211 if (is_resizable
!= resizable() || !context_
)
215 flags_
^= SDL_RESIZABLE
;
220 if (is_resizable
) flags_
|= SDL_RESIZABLE
;
221 else flags_
&= ~SDL_RESIZABLE
;
226 bool video::resizable() const
228 return flags_
& SDL_RESIZABLE
;
231 void video::toggle_resizable()
233 resizable(!resizable());
237 void video::cursor_visible(bool is_cursor_visible
)
239 SDL_ShowCursor(is_cursor_visible
? SDL_ENABLE
: SDL_DISABLE
);
242 bool video::cursor_visible() const
244 return (SDL_ShowCursor(SDL_QUERY
) == SDL_ENABLE
);
247 void video::toggle_cursor_visible()
249 cursor_visible(!cursor_visible());
253 bool video::cursor_captured() const
255 return (SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
);
258 void video::cursor_captured(bool is_cursor_captured
)
260 SDL_WM_GrabInput(is_cursor_captured
? SDL_GRAB_ON
: SDL_GRAB_OFF
);
263 void video::toggle_cursor_captured()
265 cursor_captured(!cursor_captured());
269 void video::swap(scalar t
)
273 scalar dt
= t
- last_swap_
;
276 fps_accumulator_
+= dt
;
277 if (SCALAR(1.0) <= fps_accumulator_
)
279 std::ostringstream stream
;
280 stream
<< caption_
<< " - " << fps_counter_
<< " fps";
281 SDL_WM_SetCaption(stream
.str().c_str(), 0);
283 fps_accumulator_
-= SCALAR(1.0);
290 SDL_GL_SwapBuffers();
294 int video::width() const
299 int video::height() const
305 void video::make_current() const
307 current_
= const_cast<video
*>(this);
311 video::attributes::attributes()
316 video::attributes::attributes(const settings
& settings
)
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];
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
);
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];
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
);
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
);
350 std::vector
<int> dimensions
;
351 settings
.get("videomode", dimensions
);
352 if (dimensions
.size() > 1)
354 mode
[0] = dimensions
[0];
355 mode
[1] = dimensions
[1];
357 else if (is_fullscreen
&& backend::is_initialized())
359 SDL_Rect
** modes
= SDL_ListModes(NULL
,
360 SDL_FULLSCREEN
| SDL_HWSURFACE
);
362 if (modes
== (SDL_Rect
**)0)
364 throw std::runtime_error("can't find appropriate video mode");
366 else if (modes
== (SDL_Rect
**)-1)
368 log_warning("any resolution allowed; choosing default 800x600");
374 mode
[0] = (*modes
)->w
;
375 mode
[1] = (*modes
)->h
;
376 log_info
<< "choosing native resolution: "
377 << mode
[0] << "x" << mode
[1] << std::endl
;
380 if (dimensions
.size() > 2) mode
[2] = dimensions
[2];
383 void video::attributes::init()
385 // set some sane GL and window defaults (see SDL_video.c:217)
391 is_double_buffer
= true;
394 accumulator_buffer
[0] = 0;
395 accumulator_buffer
[1] = 0;
396 accumulator_buffer
[2] = 0;
397 accumulator_buffer
[3] = 0;
399 multisample_buffers
= 0;
400 multisample_samples
= 0;
401 is_swap_control
= false;
402 is_hardware_only
= false;
406 is_fullscreen
= false;
407 is_resizable
= false;
408 is_cursor_visible
= true;
409 is_cursor_captured
= false;
413 video
* video::current_
= 0; // most recently instantiated instance