gKit2 light
window.cpp
1 
2 #include <cassert>
3 #include <cstdio>
4 #include <vector>
5 #include <set>
6 #include <string>
7 
8 #include "glcore.h"
9 #include "window.h"
10 
11 
12 static int width= 0;
13 static int height= 0;
15 {
16  return width;
17 }
19 {
20  return height;
21 }
22 
23 static std::vector<unsigned char> key_states;
24 int key_state( const SDL_Keycode key )
25 {
26  SDL_Scancode code= SDL_GetScancodeFromKey(key);
27  assert((size_t) code < key_states.size());
28  return (int) key_states[code];
29 }
30 void clear_key_state( const SDL_Keycode key )
31 {
32  SDL_Scancode code= SDL_GetScancodeFromKey(key);
33  assert((size_t) code < key_states.size());
34  key_states[code]= 0;
35 }
36 
37 static SDL_KeyboardEvent last_key;
38 SDL_KeyboardEvent key_event( )
39 {
40  return last_key;
41 }
43 {
44  last_key.type= 0;
45  last_key.keysym.sym= 0;
46 }
47 
48 static SDL_TextInputEvent last_text;
49 SDL_TextInputEvent text_event( )
50 {
51  return last_text;
52 }
54 {
55  last_text.text[0]= 0;
56 }
57 
58 static std::string last_drop;
59 const char *drop_event( )
60 {
61  return last_drop.c_str();
62 }
63 void clear_drop_event( )
64 {
65  last_drop.clear();
66 }
67 
68 static SDL_MouseButtonEvent last_button;
69 SDL_MouseButtonEvent button_event( )
70 {
71  return last_button;
72 }
74 {
75  last_button.state= 0;
76 }
77 
78 static SDL_MouseWheelEvent last_wheel;
79 SDL_MouseWheelEvent wheel_event( )
80 {
81  return last_wheel;
82 }
84 {
85  last_wheel.x= 0;
86  last_wheel.y= 0;
87 }
88 
89 
90 // etat de l'application.
91 static int stop= 0;
93 int run( Window window, int (*draw)() )
94 {
95  // configure openGL
96  glViewport(0, 0, width, height);
97 
98  // run
99  while(events(window))
100  {
101  // dessiner
102  if(draw() < 1)
103  stop= 1; // fermer l'application si draw() renvoie 0 ou -1...
104 
105  // presenter le resultat
106  SDL_GL_SwapWindow(window);
107  }
108 
109  return 0;
110 }
111 
112 int events( Window window )
113 {
114  // gestion des evenements
115  SDL_Event event;
116  while(SDL_PollEvent(&event))
117  {
118  switch(event.type)
119  {
120  case SDL_WINDOWEVENT:
121  // redimensionner la fenetre...
122  if(event.window.event == SDL_WINDOWEVENT_RESIZED)
123  {
124  // conserve les dimensions de la fenetre
125  width= event.window.data1;
126  height= event.window.data2;
127  SDL_SetWindowSize(window, width, height);
128 
129  // ... et le viewport opengl
130  glViewport(0, 0, width, height);
131  }
132  break;
133 
134  case SDL_DROPFILE:
135  last_drop.assign(event.drop.file);
136  SDL_free(event.drop.file);
137  break;
138 
139  case SDL_TEXTINPUT:
140  // conserver le dernier caractere
141  last_text= event.text;
142  break;
143 
144  case SDL_KEYDOWN:
145  // modifier l'etat du clavier
146  if((size_t) event.key.keysym.scancode < key_states.size())
147  {
148  key_states[event.key.keysym.scancode]= 1;
149  last_key= event.key; // conserver le dernier evenement
150  }
151 
152  // fermer l'application
153  if(event.key.keysym.sym == SDLK_ESCAPE)
154  stop= 1;
155  break;
156 
157  case SDL_KEYUP:
158  // modifier l'etat du clavier
159  if((size_t) event.key.keysym.scancode < key_states.size())
160  {
161  key_states[event.key.keysym.scancode]= 0;
162  last_key= event.key; // conserver le dernier evenement
163  }
164  break;
165 
166  case SDL_MOUSEBUTTONDOWN:
167  case SDL_MOUSEBUTTONUP:
168  last_button= event.button;
169  break;
170 
171  case SDL_MOUSEWHEEL:
172  last_wheel= event.wheel;
173  break;
174 
175  case SDL_QUIT:
176  stop= 1; // fermer l'application
177  break;
178  }
179  }
180 
181  return 1 - stop;
182 }
183 
184 
186 Window create_window( const int w, const int h )
187 {
188  // init sdl
189  if(SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_NOPARACHUTE ) < 0)
190  {
191  printf("[error] SDL_Init() failed:\n%s\n", SDL_GetError());
192  return NULL;
193  }
194 
195  // enregistre le destructeur de sdl
196  atexit(SDL_Quit);
197 
198  // creer la fenetre
199  Window window= SDL_CreateWindow("gKit",
200  SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h,
201  SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
202  if(window == NULL)
203  {
204  printf("[error] SDL_CreateWindow() failed.\n");
205  return NULL;
206  }
207 
208  // recupere l'etat du clavier
209  int keys;
210  const unsigned char *state= SDL_GetKeyboardState(&keys);
211  key_states.assign(state, state + keys);
212 
213  SDL_SetWindowDisplayMode(window, NULL);
214  SDL_StartTextInput();
215 
216  // conserve les dimensions de la fenetre
217  SDL_GetWindowSize(window, &width, &height);
218 
219  return window;
220 }
221 
222 void release_window( Window window )
223 {
224  SDL_StopTextInput();
225  SDL_DestroyWindow(window);
226 }
227 
228 
229 #ifndef NO_GLEW
230 #ifndef GK_RELEASE
231 static
233 void GLAPIENTRY debug( GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length,
234  const char *message, const void *userParam )
235 {
236  static std::set<std::string> log;
237  if(log.insert(message).second == false)
238  // le message a deja ete affiche, pas la peine de recommencer 60 fois par seconde.
239  return;
240 
241  if(severity == GL_DEBUG_SEVERITY_HIGH)
242  printf("[openGL error]\n%s\n", message);
243  else if(severity == GL_DEBUG_SEVERITY_MEDIUM)
244  printf("[openGL warning]\n%s\n", message);
245  else
246  printf("[openGL message]\n%s\n", message);
247 }
248 #endif
249 #endif
250 
252 Context create_context( Window window, const int major, const int minor )
253 {
254  if(window == NULL)
255  return NULL;
256 
257  // configure la creation du contexte opengl core profile, debug profile
258  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
259  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
260 #ifndef GK_RELEASE
261  SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
262 #endif
263  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
264 
265  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 15);
266  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
267 
268  Context context= SDL_GL_CreateContext(window);
269  if(context == NULL)
270  {
271  printf("[error] creating openGL context.\n");
272  return NULL;
273  }
274 
275  SDL_GL_SetSwapInterval(1);
276 
277 #ifndef NO_GLEW
278  // initialise les extensions opengl
279  glewExperimental= 1;
280  GLenum err= glewInit();
281  if(err != GLEW_OK)
282  {
283  printf("[error] loading extensions\n%s\n", glewGetErrorString(err));
284  SDL_GL_DeleteContext(context);
285  return NULL;
286  }
287 
288  // purge les erreurs opengl generees par glew !
289  while(glGetError() != GL_NO_ERROR) {;}
290 
291 #ifndef GK_RELEASE
292  // configure l'affichage des messages d'erreurs opengl, si l'extension est disponible
293  if(GLEW_ARB_debug_output)
294  {
295  printf("debug output enabled...\n");
296  glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
297 // glDebugMessageCallbackARB(debug, NULL);
298  glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
299  }
300 #endif
301 #endif
302 
303  return context;
304 }
305 
306 void release_context( Context context )
307 {
308  SDL_GL_DeleteContext(context);
309 }
310 
Context create_context(Window window, const int major, const int minor)
cree et configure un contexte opengl
Definition: window.cpp:252
SDL_TextInputEvent text_event()
renvoie le dernier evenement. saisie de texte.
Definition: window.cpp:49
SDL_MouseButtonEvent button_event()
renvoie le dernier evenement. etat des boutons de la souris.
Definition: window.cpp:69
float length(const Vector &v)
renvoie la longueur d'un vecteur.
Definition: vec.cpp:98
int events(Window window)
fonction interne de gestion d'evenements.
Definition: window.cpp:112
void clear_wheel_event()
desactive l'evenement.
Definition: window.cpp:83
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition: window.cpp:30
void clear_key_event()
desactive l'evenement.
Definition: window.cpp:42
void draw(Mesh &m, const Transform &model, const Transform &view, const Transform &projection, const GLuint texture)
applique une texture a la surface de l'objet. ne fonctionne que si les coordonnees de textures sont f...
Definition: draw.cpp:6
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:14
Window create_window(const int w, const int h)
creation d'une fenetre pour l'application.
Definition: window.cpp:186
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
Definition: window.cpp:24
SDL_MouseWheelEvent wheel_event()
renvoie le dernier evenement. etat de la molette de la souris / glisser sur le pad.
Definition: window.cpp:79
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Definition: text.cpp:140
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition: window.cpp:18
void release_context(Context context)
detruit le contexte openGL.
Definition: window.cpp:306
void clear_button_event()
desactive l'evenement.
Definition: window.cpp:73
void clear_text_event()
desactive l'evenement.
Definition: window.cpp:53
SDL_KeyboardEvent key_event()
renvoie le dernier evenement. touche speciales.
Definition: window.cpp:38
void release_window(Window window)
destruction de la fenetre.
Definition: window.cpp:222
int run(Window window, int(*draw)(void))
fonction principale. gestion des evenements et appel de la fonction draw de l'application.