52static std::vector<unsigned char> key_states;
55 SDL_Scancode code= SDL_GetScancodeFromKey(key);
56 assert((
size_t) code < key_states.size());
57 return (
int) key_states[code];
61 SDL_Scancode code= SDL_GetScancodeFromKey(key);
62 assert((
size_t) code < key_states.size());
66static SDL_KeyboardEvent last_key;
74 last_key.keysym.sym= 0;
77static SDL_TextInputEvent last_text;
87static std::vector<std::string> last_drops;
95 if(last_drops.empty())
98 return last_drops.back().c_str();
112static SDL_MouseButtonEvent last_button;
119 last_button.state= 0;
122static SDL_MouseWheelEvent last_wheel;
135static std::chrono::high_resolution_clock::time_point app_start= {};
136static std::chrono::high_resolution_clock::time_point last_time= {};
137static float last_delta= 0;
141 std::chrono::high_resolution_clock::time_point now= std::chrono::high_resolution_clock::now();
142 last_delta= float(std::chrono::duration_cast<std::chrono::microseconds>(now - last_time).count()) / float(1000);
145 return float(std::chrono::duration_cast<std::chrono::microseconds>(now - app_start).count()) / float(1000);
158int run( Window window,
int (*draw)() )
161 glViewport(0, 0, width, height);
171 SDL_GL_SwapWindow(window);
177static int event_count= 0;
178int last_event_count( ) {
return event_count; }
183 bool resize_event=
false;
187 while(SDL_PollEvent(&event))
191 case SDL_WINDOWEVENT:
193 if(event.window.event == SDL_WINDOWEVENT_RESIZED)
199 width=
event.window.data1;
200 height=
event.window.data2;
206 last_drops.push_back(std::string(event.drop.file));
207 SDL_free(event.drop.file);
212 last_text=
event.text;
217 if((
size_t) event.key.keysym.scancode < key_states.size())
219 key_states[
event.key.keysym.scancode]= 1;
224 if(event.key.keysym.sym == SDLK_ESCAPE)
230 if((
size_t) event.key.keysym.scancode < key_states.size())
232 key_states[
event.key.keysym.scancode]= 0;
237 case SDL_MOUSEBUTTONDOWN:
238 case SDL_MOUSEBUTTONUP:
239 last_button=
event.button;
243 last_wheel=
event.wheel;
254 glViewport(0, 0, width, height);
262Window
create_window(
const int w,
const int h,
const int major,
const int minor )
265 if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0)
267 printf(
"[error] SDL_Init() failed:\n%s\n", SDL_GetError());
276 printf(
"creating window(%d, %d) openGL %d.%d....\n", w, h, major, minor);
278 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
279 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
281 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
283 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
285 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
286 SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, srgb ? 1 : 0);
287 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
291 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
292 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa);
296 printf(
"creating window(%d, %d) openGL ES 3.0...\n", w, h);
298 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
299 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
300 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
301 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
305 Window window= SDL_CreateWindow(
"gKit",
306 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h,
307 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
308 if(window ==
nullptr)
310 printf(
"[error] SDL_CreateWindow() failed.\n");
316 const unsigned char *state= SDL_GetKeyboardState(&keys);
317 key_states.assign(state, state + keys);
319 SDL_SetWindowDisplayMode(window,
nullptr);
320 SDL_StartTextInput();
323 SDL_GetWindowSize(window, &width, &height);
331 SDL_DestroyWindow(window);
339void DEBUGCALLBACK debug_print( GLenum source, GLenum type,
unsigned int id, GLenum severity, GLsizei length,
340 const char *message,
const void *userParam )
342 static std::set<std::string> log;
343 if(log.insert(message).second ==
false)
347 if(severity == GL_DEBUG_SEVERITY_HIGH)
348 printf(
"[openGL error]\n%s\n", message);
349 else if(severity == GL_DEBUG_SEVERITY_MEDIUM)
350 printf(
"[openGL warning]\n%s\n", message);
352 printf(
"[openGL message]\n%s\n", message);
360 if(window ==
nullptr)
363 Context context= SDL_GL_CreateContext(window);
364 if(context ==
nullptr)
366 printf(
"[error] creating openGL context.\n");
370 if(SDL_GL_SetSwapInterval(-1) != 0)
371 printf(
"[warning] can't set adaptive vsync...\n");
373 if(SDL_GL_GetSwapInterval() != -1)
376 SDL_GL_SetSwapInterval(1);
379 printf(
"adaptive vsync ON\n");
383 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &n);
385 printf(
"MSAA %d samples\n", n);
391 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bits);
393 printf(
"Zbuffer %d bits\n", bits);
398 SDL_GL_GetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, &flag);
400 printf(
"sRGB framebuffer ON\n");
406 app_start= std::chrono::high_resolution_clock::now();
413 while(glGetError() != GL_NO_ERROR) {;}
418 if(GLAD_GL_ARB_debug_output)
420 printf(
"debug output enabled...\n");
422 glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
424 glDebugMessageControlARB(GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);
426 glDebugMessageCallbackARB(debug_print, NULL);
427 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
433 glEnable(GL_FRAMEBUFFER_SRGB);
441 SDL_GL_DeleteContext(context);
445static std::string smartpath;
446static std::string path;
456 const char *envbase= std::getenv(
"GKIT_BASE_PATH");
457 if(envbase !=
nullptr)
459 path= std::string(envbase);
460 if(!path.empty() && path[path.size() -1] !=
'/')
463 printf(
"[base path] %s\n", path.c_str());
470 char *base= SDL_GetBasePath();
471 printf(
"[base path] %s\n", base);
476 smartpath= path + filename;
477 if(exists(smartpath.c_str()))
478 return smartpath.c_str();
480 smartpath= path +
"../" + filename;
481 if(exists(smartpath.c_str()))
482 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.
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.