32static bool resize=
true;
62static std::vector<unsigned char> key_states;
65 SDL_Scancode code= SDL_GetScancodeFromKey(key);
66 assert((
size_t) code < key_states.size());
67 return (
int) key_states[code];
71 SDL_Scancode code= SDL_GetScancodeFromKey(key);
72 assert((
size_t) code < key_states.size());
76static SDL_KeyboardEvent last_key;
84 last_key.keysym.sym= 0;
87static SDL_TextInputEvent last_text;
97static std::vector<std::string> last_drops;
104 if(last_drops.empty())
107 return last_drops.back().c_str();
118static SDL_MouseButtonEvent last_button;
125 last_button.state= 0;
128static SDL_MouseWheelEvent last_wheel;
141static std::chrono::high_resolution_clock::time_point app_start= {};
142static std::chrono::high_resolution_clock::time_point last_time= {};
143static float last_delta= 0;
147 std::chrono::high_resolution_clock::time_point now= std::chrono::high_resolution_clock::now();
148 last_delta= float(std::chrono::duration_cast<std::chrono::microseconds>(now - last_time).count()) / float(1000);
151 return float(std::chrono::duration_cast<std::chrono::microseconds>(now - app_start).count()) / float(1000);
164int run( Window window,
int (*draw)() )
167 glViewport(0, 0, width, height);
177 SDL_GL_SwapWindow(window);
183static int event_count= 0;
184int last_event_count( )
191 bool resize_event=
false;
195 while(SDL_PollEvent(&event))
199 case SDL_WINDOWEVENT:
201 if(event.window.event == SDL_WINDOWEVENT_RESIZED)
207 width=
event.window.data1;
208 height=
event.window.data2;
214 last_drops.push_back(std::string(event.drop.file));
215 SDL_free(event.drop.file);
220 last_text=
event.text;
225 if((
size_t) event.key.keysym.scancode < key_states.size())
227 key_states[
event.key.keysym.scancode]= 1;
232 if(event.key.keysym.sym == SDLK_ESCAPE)
238 if((
size_t) event.key.keysym.scancode < key_states.size())
240 key_states[
event.key.keysym.scancode]= 0;
245 case SDL_MOUSEBUTTONDOWN:
246 case SDL_MOUSEBUTTONUP:
247 last_button=
event.button;
251 last_wheel=
event.wheel;
262 glViewport(0, 0, width, height);
270Window
create_window(
const int w,
const int h,
const int major,
const int minor )
273 if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0)
275 printf(
"[error] SDL_Init() failed:\n%s\n", SDL_GetError());
284 printf(
"creating window(%d, %d) openGL %d.%d....\n", w, h, major, minor);
286 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
287 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
289 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
291 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
293 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
294 SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, srgb ? 1 : 0);
295 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
299 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
300 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa);
304 printf(
"creating window(%d, %d) openGL ES 3.0...\n", w, h);
306 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
307 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
308 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
309 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
313 unsigned flags= SDL_WINDOW_OPENGL;
314 if(resize) flags|= SDL_WINDOW_RESIZABLE;
316 Window window= SDL_CreateWindow(
"gKit", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
317 if(window ==
nullptr)
319 printf(
"[error] SDL_CreateWindow() failed.\n");
325 const unsigned char *state= SDL_GetKeyboardState(&keys);
326 key_states.assign(state, state + keys);
328 SDL_SetWindowDisplayMode(window,
nullptr);
329 SDL_StartTextInput();
332 SDL_GetWindowSize(window, &width, &height);
340 SDL_DestroyWindow(window);
348void DEBUGCALLBACK debug_print( GLenum source, GLenum type,
unsigned int id, GLenum severity, GLsizei length,
349 const char *message,
const void *userParam )
351 static std::set<std::string> log;
352 if(log.insert(message).second ==
false)
356 if(severity == GL_DEBUG_SEVERITY_HIGH)
357 printf(
"[openGL error]\n%s\n", message);
358 else if(severity == GL_DEBUG_SEVERITY_MEDIUM)
359 printf(
"[openGL warning]\n%s\n", message);
361 printf(
"[openGL message]\n%s\n", message);
369 if(window ==
nullptr)
372 Context context= SDL_GL_CreateContext(window);
373 if(context ==
nullptr)
375 printf(
"[error] creating openGL context.\n");
379 if(SDL_GL_SetSwapInterval(-1) != 0)
380 printf(
"[warning] can't set adaptive vsync...\n");
382 if(SDL_GL_GetSwapInterval() != -1)
385 SDL_GL_SetSwapInterval(1);
388 printf(
"adaptive vsync ON\n");
392 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &n);
394 printf(
"MSAA %d samples\n", n);
400 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bits);
402 printf(
"Zbuffer %d bits\n", bits);
407 SDL_GL_GetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, &flag);
409 printf(
"sRGB framebuffer ON\n");
415 app_start= std::chrono::high_resolution_clock::now();
419 gladLoadGLLoader( GLADloadproc(SDL_GL_GetProcAddress) );
422 while(glGetError() != GL_NO_ERROR) {;}
427 if(GLAD_GL_ARB_debug_output)
429 printf(
"debug output enabled...\n");
431 glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
433 glDebugMessageControlARB(GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);
435 glDebugMessageCallbackARB(debug_print, NULL);
436 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
442 glEnable(GL_FRAMEBUFFER_SRGB);
449 SDL_GL_DeleteContext(context);
453static std::string smartpath;
454static std::string path;
464 const char *envbase= std::getenv(
"GKIT_BASE_PATH");
465 if(envbase !=
nullptr)
467 path= std::string(envbase);
468 if(!path.empty() && path[path.size() -1] !=
'/')
471 printf(
"[base path] %s\n", path.c_str());
478 char *base= SDL_GetBasePath();
479 printf(
"[base path] %s\n", base);
484 smartpath= path + filename;
485 if(exists(smartpath.c_str()))
486 return smartpath.c_str();
488 smartpath= path +
"../" + filename;
489 if(exists(smartpath.c_str()))
490 return smartpath.c_str();
const char * smart_path(const char *filename)
renvoie le chemin(path) vers le fichier 'filename' apres l'avoir cherche dans un repertoire standard....
bool window_srgb()
renvoie le mode srgb de la fenetre de l'application.
SDL_MouseButtonEvent button_event()
renvoie le dernier evenement. etat des boutons de la souris.
Context create_context(Window window)
cree et configure un contexte opengl
void clear_button_event()
desactive l'evenement.
bool window_resize()
renvoie vrai si la fenetre peut etre redimensionnee.
void clear_drop_events()
desactive drag/drop.
int events(Window window)
fonction interne de gestion d'evenements.
const std::vector< std::string > & drop_events()
drag/drop. recupere tous les fichiers.
int window_height()
renvoie la hauteur de la fenetre de l'application.
SDL_TextInputEvent text_event()
renvoie le dernier evenement. saisie de texte.
void release_window(Window window)
destruction de la fenetre.
int run(Window window, int(*draw)())
boucle de gestion des evenements de l'application.
void clear_key_event()
desactive l'evenement.
SDL_KeyboardEvent key_event()
renvoie le dernier evenement. touche speciales.
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
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().
const char * drop_event()
drag/drop, renvoie le dernier fichier.
void clear_drop_event()
desactive drag/drop.
void clear_text_event()
desactive l'evenement.
Window create_window(const int w, const int h, const int major, const int minor)
creation d'une fenetre pour l'application.
void release_context(Context context)
detruit le contexte openGL.
void clear_wheel_event()
desactive l'evenement.
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
int window_msaa()
renvoie le nombre de samples MSAA.
SDL_MouseWheelEvent wheel_event()
renvoie le dernier evenement. etat de la molette de la souris / glisser sur le pad.
int window_width()
renvoie la largeur de la fenetre de l'application.
float delta_time()
renvoie le temps ecoule depuis la derniere frame, en millisecondes.
float global_time()
renvoie le temps ecoule depuis le lancement de l'application, en millisecondes.