sgltk 0.6
Simple OpenGL Tool Kit
Loading...
Searching...
No Matches
window.cpp
1#include "window.h"
2
3using namespace sgltk;
4
5unsigned int Window::cnt = 0;
6std::map<unsigned int, std::shared_ptr<Gamepad> > Window::gamepad_instance_id_map;
7std::map<unsigned int, std::shared_ptr<Joystick> > Window::joystick_instance_id_map;
8
9Window::Window(const std::string& title, int res_x, int res_y, int offset_x, int offset_y, unsigned int flags) {
10
11 cnt++;
12 running = true;
13 mouse_relative = false;
14 keys = SDL_GetKeyboardState(nullptr);
15 delta_time = 0;
16
17 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
18
19 width = res_x;
20 height = res_y;
21 window = SDL_CreateWindow(title.c_str(), offset_x, offset_y,
22 res_x, res_y,
23 SDL_WINDOW_OPENGL |
24 SDL_WINDOW_RESIZABLE |
25 flags);
26 if(!window) {
27 std::string error = std::string("Error opening window: ") + SDL_GetError();
28 App::error_string.push_back(error);
29 throw std::runtime_error(error);
30 }
32 SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &gl_maj);
33 SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &gl_min);
34 context = SDL_GL_CreateContext(window);
35 } else {
36 for(gl_maj = 4; gl_maj > 2; gl_maj--) {
37 for(gl_min = 6; gl_min >= 0; gl_min--) {
38 if(gl_maj == 3 && gl_min > 3) {
39 continue;
40 }
41 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, gl_maj);
42 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, gl_min);
43 context = SDL_GL_CreateContext(window);
44 if(context) {
45 goto endloop;
46 }
47 }
48 }
49 }
50endloop:
51 if(!context) {
52 SDL_DestroyWindow(window);
53 std::string error = std::string("Error creating OpenGL context: ") +
54 SDL_GetError();
55 App::error_string.push_back(error);
56 throw std::runtime_error(error);
57 }
58
59 glGetIntegerv(GL_MAX_PATCH_VERTICES, &App::sys_info.max_patch_vertices);
60 glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &App::sys_info.max_tess_level);
61
63 glViewport(0, 0, (GLsizei)width, (GLsizei)height);
64}
65
66Window::~Window() {
67 cnt--;
68 SDL_GL_DeleteContext(context);
69 SDL_DestroyWindow(window);
70 keys_pressed.clear();
71 if(cnt == 0) {
72 gamepad_instance_id_map.clear();
73 joystick_instance_id_map.clear();
74 }
75}
76
77void Window::set_icon(const std::string& filename) {
78 Image img(filename.c_str());
79 SDL_SetWindowIcon(window, img.image);
80}
81
82void Window::set_icon(const Image& icon) {
83 SDL_SetWindowIcon(window, icon.image);
84}
85
86void Window::set_title(const std::string& title) {
87 SDL_SetWindowTitle(window, title.c_str());
88}
89
90void Window::set_resizable(bool on) {
91 SDL_SetWindowResizable(window, (SDL_bool)on);
92}
93
95 std::unique_ptr<char[]> buf = std::make_unique<char[]>(4 * width * height);
96 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buf.get());
97 image.load(width, height, 4, buf.get());
98 image.vertical_flip();
99}
100
101void Window::grab_mouse(bool on) {
102 SDL_SetWindowGrab(window, (SDL_bool)on);
103}
104
106 int ret = SDL_GetWindowDisplayIndex(window);
107 if(ret < 0) {
108 App::error_string.push_back(std::string("Error on acquiring the "
109 "display index: ") + SDL_GetError());
110 }
111 return ret;
112}
113
114bool Window::set_display_mode(const SDL_DisplayMode& mode) {
115 if(SDL_SetWindowDisplayMode(window, &mode)) {
116 App::error_string.push_back(std::string("Error on changing "
117 "window display mode: ") + SDL_GetError());
118 return false;
119 }
120 return true;
121}
122
123bool Window::fullscreen_mode(WINDOW_MODE mode) {
124 if(SDL_SetWindowFullscreen(window, static_cast<unsigned int>(mode)) < 0) {
125 App::error_string.push_back(std::string("Error on changing "
126 "window fullscreen state: ") + SDL_GetError());
127 return false;
128 }
129 return true;
130}
131
133 mouse_relative = on;
134 SDL_SetRelativeMouseMode((SDL_bool)on);
135}
136
137void Window::set_mouse_position(int x, int y) {
138 SDL_WarpMouseInWindow(window, x, y);
139}
140
142 int toggle = SDL_DISABLE;
143 if(show)
144 toggle = SDL_ENABLE;
145
146 SDL_ShowCursor(toggle);
147}
148
150 int ret = SDL_ShowCursor(SDL_QUERY);
151 if(ret == SDL_ENABLE)
152 return true;
153
154 return false;
155}
156
158 int value;
159 SDL_Event event;
160 std::shared_ptr<Gamepad> gamepad;
161 std::shared_ptr<Joystick> joystick;
162 std::map<unsigned int, std::shared_ptr<Gamepad> >::iterator gamepad_it;
163 std::map<unsigned int, std::shared_ptr<Joystick> >::iterator joystick_it;
164 std::vector<int>::iterator button;
165
166 while(SDL_PollEvent(&event)) {
167 switch(event.type) {
168 case SDL_QUIT:
169 handle_exit();
170 break;
171 case SDL_WINDOWEVENT:
172 switch(event.window.event) {
173 case SDL_WINDOWEVENT_CLOSE:
174 handle_exit();
175 break;
176 case SDL_WINDOWEVENT_RESIZED:
177 width = event.window.data1;
178 height = event.window.data2;
180 break;
181 }
182 break;
183 case SDL_KEYDOWN:
184 if(event.key.repeat == 0) {
185 keys_pressed.push_back(SDL_GetKeyName(event.key.keysym.sym));
186 handle_key_press(SDL_GetKeyName(event.key.keysym.sym), true);
187 }
188 break;
189 case SDL_KEYUP:
190 {
191 std::string key_name = SDL_GetKeyName(event.key.keysym.sym);
192 auto it = std::find(keys_pressed.begin(), keys_pressed.end(), key_name);
193 if(it != keys_pressed.end()) {
194 keys_pressed.erase(it);
195 }
196 handle_key_press(key_name, false);
197 }
198 break;
199 case SDL_MOUSEWHEEL:
200 handle_mouse_wheel(event.wheel.x, event.wheel.y);
201 break;
202 case SDL_MOUSEBUTTONDOWN:
203 case SDL_MOUSEBUTTONUP:
204 if(mouse_relative)
205 handle_mouse_button(0, 0, event.button.button,
206 (event.button.state == SDL_PRESSED),
207 event.button.clicks);
208 else
209 handle_mouse_button(event.button.x, event.button.y,
210 event.button.button,
211 (event.button.state == SDL_PRESSED),
212 event.button.clicks);
213 break;
214 case SDL_MOUSEMOTION:
215 if(mouse_relative)
216 handle_mouse_motion(event.motion.xrel,
217 event.motion.yrel);
218 else
219 handle_mouse_motion(event.motion.x,
220 event.motion.y);
221 break;
222 case SDL_CONTROLLERDEVICEADDED:
223 gamepad = std::make_shared<Gamepad>(event.cdevice.which);
224 gamepad_instance_id_map[gamepad->instance_id] = gamepad;
225 handle_gamepad_added(gamepad);
226 break;
227 case SDL_CONTROLLERDEVICEREMOVED:
228 gamepad_it = gamepad_instance_id_map.find(event.cdevice.which);
229 if(gamepad_it != gamepad_instance_id_map.end()) {
230 gamepad = gamepad_it->second;
231 handle_gamepad_removed(gamepad->id);
232 gamepad_instance_id_map.erase(gamepad->instance_id);
233 }
234 break;
235 case SDL_CONTROLLERBUTTONDOWN:
236 gamepad_it = gamepad_instance_id_map.find(event.cdevice.which);
237 if(gamepad_it != gamepad_instance_id_map.end()) {
238 gamepad = gamepad_it->second;
239 gamepad->set_button_state(event.cbutton.button, true);
240 handle_gamepad_button_press(gamepad, event.cbutton.button, true);
241 }
242 break;
243 case SDL_CONTROLLERBUTTONUP:
244 gamepad_it = gamepad_instance_id_map.find(event.cdevice.which);
245 if(gamepad_it != gamepad_instance_id_map.end()) {
246 gamepad = gamepad_it->second;
247 gamepad->set_button_state(event.cbutton.button, false);
248 handle_gamepad_button_press(gamepad, event.cbutton.button, false);
249 }
250 break;
251 case SDL_CONTROLLERAXISMOTION:
252 gamepad_it = gamepad_instance_id_map.find(event.cdevice.which);
253 if(gamepad_it != gamepad_instance_id_map.end()) {
254 gamepad = gamepad_it->second;
256 event.caxis.axis,
257 gamepad->get_axis_value(event.caxis.axis));
258 }
259 break;
260 case SDL_JOYDEVICEADDED:
261 if(!SDL_IsGameController(event.jdevice.which)) {
262 joystick = std::make_shared<Joystick>(event.jdevice.which);
263 joystick_instance_id_map[joystick->instance_id] = joystick;
264 handle_joystick_added(joystick);
265 }
266 break;
267 case SDL_JOYDEVICEREMOVED:
268 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
269 if(joystick_it != joystick_instance_id_map.end()) {
270 joystick = joystick_it->second;
271 handle_joystick_removed(joystick->id);
272 joystick_instance_id_map.erase(joystick->instance_id);
273 }
274 break;
275 case SDL_JOYBUTTONDOWN:
276 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
277 if(joystick_it != joystick_instance_id_map.end()) {
278 joystick = joystick_it->second;
279 joystick->set_button_state(event.jbutton.button, true);
281 event.jbutton.button, true);
282 }
283 break;
284 case SDL_JOYBUTTONUP:
285 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
286 if(joystick_it != joystick_instance_id_map.end()) {
287 joystick = joystick_it->second;
288 joystick->set_button_state(event.jbutton.button, false);
290 event.jbutton.button, false);
291 }
292 break;
293 case SDL_JOYAXISMOTION:
294 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
295 if(joystick_it != joystick_instance_id_map.end()) {
296 joystick = joystick_it->second;
298 event.jaxis.axis,
299 joystick->get_axis_value(event.jaxis.axis));
300 }
301 break;
302 case SDL_JOYHATMOTION:
303 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
304 if(joystick_it != joystick_instance_id_map.end()) {
305 joystick = joystick_it->second;
307 event.jhat.hat,
308 event.jhat.value);
309 }
310 break;
311 case SDL_JOYBALLMOTION:
312 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
313 if(joystick_it != joystick_instance_id_map.end()) {
314 joystick = joystick_it->second;
316 event.jball.ball,
317 event.jball.xrel,
318 event.jball.yrel);
319 }
320 break;
321 }
322 }
323
324 for(std::string key : keys_pressed) {
325 handle_keyboard(key);
326 }
327
328 for(const auto& device : gamepad_instance_id_map) {
329 if(!device.second)
330 continue;
331 for(unsigned int axis = 0; axis < device.second->num_axes; axis++) {
332 value = device.second->get_axis_value(axis);
333 handle_gamepad_axis(device.second, axis, value);
334 }
335 for(unsigned int button = 0; button < device.second->buttons_pressed.size(); button++) {
336 handle_gamepad_button(device.second, device.second->buttons_pressed[button]);
337 }
338 }
339
340 for(const auto& device : joystick_instance_id_map) {
341 if(!device.second)
342 continue;
343 for(unsigned int axis = 0; axis < device.second->num_axes; axis++) {
344 value = device.second->get_axis_value(axis);
345 handle_joystick_axis(device.second, axis, value);
346 }
347 for(unsigned int button = 0; button < device.second->buttons_pressed.size(); button++) {
348 handle_joystick_button(device.second, device.second->buttons_pressed[button]);
349 }
350 for(unsigned int hat = 0; hat < device.second->num_hats; hat++) {
351 handle_joystick_hat(device.second, hat, device.second->get_hat_value(hat));
352 }
353 }
354}
355
356void Window::handle_gamepad_added(std::shared_ptr<Gamepad> gamepad) {
357}
358
359void Window::handle_gamepad_removed(unsigned int gamepad_id) {
360}
361
362void Window::handle_gamepad_button(std::shared_ptr<Gamepad> gamepad, int button) {
363}
364
365void Window::handle_gamepad_button_press(std::shared_ptr<Gamepad> gamepad, int button, bool pressed) {
366}
367
368void Window::handle_gamepad_axis(std::shared_ptr<Gamepad> gamepad, unsigned int axis, int value) {
369}
370
371void Window::handle_gamepad_axis_change(std::shared_ptr<Gamepad> gamepad, unsigned int axis, int value) {
372}
373
374void Window::handle_joystick_added(std::shared_ptr<Joystick> joystick) {
375}
376
377void Window::handle_joystick_removed(unsigned int joystick_id) {
378}
379
380void Window::handle_joystick_button(std::shared_ptr<Joystick> joystick, int button) {
381}
382
383void Window::handle_joystick_button_press(std::shared_ptr<Joystick> joystick, int button, bool pressed) {
384}
385
386void Window::handle_joystick_axis(std::shared_ptr<Joystick> joystick, unsigned int axis, int value) {
387}
388
389void Window::handle_joystick_axis_change(std::shared_ptr<Joystick> joystick, unsigned int axis, int value) {
390}
391
392void Window::handle_joystick_hat(std::shared_ptr<Joystick> joystick, unsigned int hat, unsigned int value) {
393}
394
395void Window::handle_joystick_hat_change(std::shared_ptr<Joystick> joystick, unsigned int hat, unsigned int value) {
396}
397
398void Window::handle_joystick_ball_motion(std::shared_ptr<Joystick> joystick, unsigned int ball, int xrel, int yrel) {
399}
400
401void Window::handle_keyboard(const std::string& key) {
402}
403
404void Window::handle_key_press(const std::string& key, bool pressed) {
405}
406
407void Window::handle_mouse_motion(int x, int y) {
408}
409
410void Window::handle_mouse_wheel(int x, int y) {
411}
412
414 int button,
415 bool down,
416 int clicks) {
417}
418
421
423 stop();
424}
425
427 glClearColor(0.0, 0.0, 0.0, 1.0);
428 glClear(GL_COLOR_BUFFER_BIT);
429}
430
431void Window::run(unsigned int fps) {
432 double frame_time;
433 double time_to_wait;
434 Timer frame_timer;
435 if(fps < 1)
436 frame_time = 0;
437 else
438 frame_time = 1000.0 / fps;
439 running = true;
440
441 display();
442
443 while(running) {
444 poll_events();
445 if(!window) {
446 break;
447 }
448 frame_timer.start();
449 display();
450 if(fps > 0) {
451 time_to_wait = std::max(frame_time - frame_timer.get_time_ms(), 0.0);
452 if(time_to_wait > 0) {
453 std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(time_to_wait));
454 }
455 }
456 delta_time = frame_timer.get_time_s();
457 SDL_GL_SwapWindow(window);
458 }
459}
460
462 running = false;
463}
static std::vector< std::string > error_string
A list of all error strings.
Definition app.h:151
static bool gl_version_manual
True if set_gl_version was called, false otherwise.
Definition app.h:143
static struct SYS_INFO sys_info
System information.
Definition app.h:147
static bool init_glew()
Initializes GLEW.
Definition app.cpp:10
Manages images.
Definition image.h:12
SDL_Surface * image
The image surface.
Definition image.h:44
void vertical_flip()
Flips the image along its x-axis.
Definition image.cpp:330
bool load(const std::string &filename)
Loads a new image file.
Definition image.cpp:97
Provides a simple timer.
Definition timer.h:12
void start()
Starts the timer.
Definition timer.cpp:12
double get_time_s()
Returns the time in seconds since the timer was started.
Definition timer.cpp:16
double get_time_ms()
Returns the time in milliseconds since the timer was started.
Definition timer.cpp:24
virtual void handle_joystick_added(std::shared_ptr< sgltk::Joystick > joystick)
This function is called by poll_events() to handle the addition of new joysticks. This function shoul...
Definition window.cpp:374
virtual void handle_gamepad_axis_change(std::shared_ptr< sgltk::Gamepad > gamepad, unsigned int axis, int value)
This function is called by poll_events() for every axis value change. This function should be overrid...
Definition window.cpp:371
double delta_time
The time it took to draw the last frame.
Definition window.h:64
int get_display_index()
Returns the index of the display that currently contains the window. This index corresponds to the in...
Definition window.cpp:105
virtual void handle_key_press(const std::string &key, bool pressed)
This function is called by poll_events() once for every key pressed or released. This function should...
Definition window.cpp:404
void set_relative_mode(bool on)
Activates the relative mouse motion mode In the relative mouse motion mode the cursor is invisible an...
Definition window.cpp:132
virtual void handle_mouse_motion(int x, int y)
This function is called by poll_events() to handle mouse motion. This function should be overridden.
Definition window.cpp:407
void set_mouse_position(int x, int y)
Sets the mouse position inside the window.
Definition window.cpp:137
void poll_events()
Polls all events and calls the handlers. Called by the run function.
Definition window.cpp:157
virtual void handle_mouse_button(int x, int y, int button, bool down, int clicks)
This function is called by poll_events() to handle mouse button presses. This function should be over...
Definition window.cpp:413
virtual void handle_mouse_wheel(int x, int y)
This function is called by poll_events() to handle mouse wheel movements. This function should be ove...
Definition window.cpp:410
virtual void handle_joystick_hat(std::shared_ptr< sgltk::Joystick > joystick, unsigned int hat, unsigned int value)
This function is called by poll_events() every frame for every hat of every joystick....
Definition window.cpp:392
void set_title(const std::string &title)
Set window title.
Definition window.cpp:86
bool set_display_mode(const SDL_DisplayMode &mode)
Changes the window display mode when in fullscreen mode.
Definition window.cpp:114
void stop()
Stops the main loop.
Definition window.cpp:461
int gl_min
The minor OpenGL version number.
Definition window.h:52
void set_cursor_visibility(bool show)
Sets mouse cursor visibility.
Definition window.cpp:141
virtual void handle_gamepad_removed(unsigned int gamepad_id)
This function is called by poll_events() to handle the removal of gamepads. This function should be o...
Definition window.cpp:359
virtual void handle_joystick_hat_change(std::shared_ptr< sgltk::Joystick > joystick, unsigned int hat, unsigned int value)
This function is called by poll_events() for every hat value change. This function should be overridd...
Definition window.cpp:395
Window(const std::string &title, int res_x, int res_y, int offset_x, int offset_y, unsigned int flags=0)
Definition window.cpp:9
int height
The height of the window surface.
Definition window.h:60
int width
The width of the window surface.
Definition window.h:56
virtual void handle_exit()
This function is called by run when the window is being closed. This function should be overridden.
Definition window.cpp:422
virtual void handle_joystick_axis_change(std::shared_ptr< sgltk::Joystick > joystick, unsigned int axis, int value)
This function is called by poll_events() for every axis value change. This function should be overrid...
Definition window.cpp:389
void run(unsigned int fps=0)
Starts the main loop. This function calls poll_events() and display()
Definition window.cpp:431
bool fullscreen_mode(sgltk::WINDOW_MODE mode)
Changes the window mode.
Definition window.cpp:123
virtual void handle_joystick_removed(unsigned int joystick_id)
This function is called by poll_events() to handle the removal of joysticks. This function should be ...
Definition window.cpp:377
virtual void handle_gamepad_button_press(std::shared_ptr< sgltk::Gamepad > gamepad, int button, bool pressed)
This function is called by poll_events() once for every gamepad button press or release....
Definition window.cpp:365
virtual void handle_gamepad_axis(std::shared_ptr< sgltk::Gamepad > gamepad, unsigned int axis, int value)
This function is called by poll_events() every frame for every axis of every gamepad....
Definition window.cpp:368
virtual void handle_joystick_ball_motion(std::shared_ptr< sgltk::Joystick > joystick, unsigned int ball, int xrel, int yrel)
This function is called by poll_events() for every ball that has changed value change....
Definition window.cpp:398
virtual void handle_gamepad_added(std::shared_ptr< sgltk::Gamepad > gamepad)
This function is called by poll_events() to handle the addition of new gamepads. This function should...
Definition window.cpp:356
void set_resizable(bool on)
Sets or removes the ability to resize the window.
Definition window.cpp:90
void take_screenshot(sgltk::Image &image)
Takes a screenshot of the window.
Definition window.cpp:94
bool get_cursor_visibility()
Returns mouse cursor visibility status.
Definition window.cpp:149
virtual void handle_gamepad_button(std::shared_ptr< sgltk::Gamepad > gamepad, int button)
This function is called by poll_events() every frame for every gamepad button currently being pressed...
Definition window.cpp:362
void grab_mouse(bool on)
Sets the window to grab the mouse When activate the mouse can not leave the window boundaries.
Definition window.cpp:101
virtual void handle_joystick_button_press(std::shared_ptr< sgltk::Joystick > joystick, int button, bool pressed)
This function is called by poll_events() once for every joystick button pressed or released....
Definition window.cpp:383
int gl_maj
The manjor OpenGL version number.
Definition window.h:48
virtual void handle_joystick_axis(std::shared_ptr< sgltk::Joystick > joystick, unsigned int axis, int value)
This function is called by poll_events() every frame for every axis of every joystick....
Definition window.cpp:386
virtual void handle_joystick_button(std::shared_ptr< sgltk::Joystick > joystick, int button)
This function is called by poll_events() every frame for every joystick button currently being presse...
Definition window.cpp:380
virtual void handle_keyboard(const std::string &key)
This function is called by poll_events() every frame for every key currently being pressed....
Definition window.cpp:401
virtual void handle_resize()
This function is called by run when the window is resized. This function should be overridden.
Definition window.cpp:419
SDL_Window * window
The window surface.
Definition window.h:68
virtual void display()
This function is called by run() to draw a frame. This function should be overridden.
Definition window.cpp:426
void set_icon(const std::string &filename)
Sets the window icon.
Definition window.cpp:77