21 static float aspect= 1;
37 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &n);
41 static std::vector<unsigned char> key_states;
44 SDL_Scancode code= SDL_GetScancodeFromKey(key);
45 assert((
size_t) code < key_states.size());
46 return (
int) key_states[code];
50 SDL_Scancode code= SDL_GetScancodeFromKey(key);
51 assert((
size_t) code < key_states.size());
55 static SDL_KeyboardEvent last_key;
63 last_key.keysym.sym= 0;
66 static SDL_TextInputEvent last_text;
76 static std::vector<std::string> last_drops;
84 if(last_drops.empty())
87 return last_drops.back().c_str();
101 static SDL_MouseButtonEvent last_button;
108 last_button.state= 0;
111 static SDL_MouseWheelEvent last_wheel;
124 static std::chrono::high_resolution_clock::time_point app_start= {};
125 static std::chrono::high_resolution_clock::time_point last_time= {};
126 static float last_delta= 0;
130 std::chrono::high_resolution_clock::time_point now= std::chrono::high_resolution_clock::now();
131 last_delta= float(std::chrono::duration_cast<std::chrono::microseconds>(now - last_time).count()) / float(1000);
134 return float(std::chrono::duration_cast<std::chrono::microseconds>(now - app_start).count()) / float(1000);
147 int run( Window window,
int (*draw)() )
150 glViewport(0, 0, width, height);
160 SDL_GL_SwapWindow(window);
166 static int event_count= 0;
167 int last_event_count( ) {
return event_count; }
172 bool resize_event=
false;
176 while(SDL_PollEvent(&event))
180 case SDL_WINDOWEVENT:
182 if(event.window.event == SDL_WINDOWEVENT_RESIZED)
188 width=
event.window.data1;
189 height=
event.window.data2;
195 last_drops.push_back(std::string(event.drop.file));
196 SDL_free(event.drop.file);
201 last_text=
event.text;
206 if((
size_t) event.key.keysym.scancode < key_states.size())
208 key_states[
event.key.keysym.scancode]= 1;
213 if(event.key.keysym.sym == SDLK_ESCAPE)
219 if((
size_t) event.key.keysym.scancode < key_states.size())
221 key_states[
event.key.keysym.scancode]= 0;
226 case SDL_MOUSEBUTTONDOWN:
227 case SDL_MOUSEBUTTONUP:
228 last_button=
event.button;
232 last_wheel=
event.wheel;
243 int w= std::floor(height * aspect);
245 SDL_SetWindowSize(window, w, h);
246 glViewport(0, 0, w, h);
259 Window
create_window(
const int w,
const int h,
const int major,
const int minor,
const int samples )
262 if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0)
264 printf(
"[error] SDL_Init() failed:\n%s\n", SDL_GetError());
273 printf(
"creating window(%d, %d) openGL %d.%d, %d MSAA samples...\n", w, h, major, minor, samples);
275 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
276 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
278 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
280 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
282 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
283 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
287 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
288 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples);
292 printf(
"creating window(%d, %d) openGL ES 3.0...\n", w, h);
294 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
295 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
296 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
297 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
301 Window window= SDL_CreateWindow(
"gKit",
302 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h,
303 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
304 if(window ==
nullptr)
306 printf(
"[error] SDL_CreateWindow() failed.\n");
312 const unsigned char *state= SDL_GetKeyboardState(&keys);
313 key_states.assign(state, state + keys);
315 SDL_SetWindowDisplayMode(window,
nullptr);
316 SDL_StartTextInput();
319 SDL_GetWindowSize(window, &width, &height);
320 aspect= float(width) / float(height);
328 SDL_DestroyWindow(window);
337 void DEBUGCALLBACK debug_print( GLenum source, GLenum type,
unsigned int id, GLenum severity, GLsizei
length,
338 const char *message,
const void *userParam )
340 static std::set<std::string> log;
341 if(log.insert(message).second ==
false)
345 if(severity == GL_DEBUG_SEVERITY_HIGH)
346 printf(
"[openGL error]\n%s\n", message);
347 else if(severity == GL_DEBUG_SEVERITY_MEDIUM)
348 printf(
"[openGL warning]\n%s\n", message);
350 printf(
"[openGL message]\n%s\n", message);
358 if(window ==
nullptr)
361 Context context= SDL_GL_CreateContext(window);
362 if(context ==
nullptr)
364 printf(
"[error] creating openGL context.\n");
368 if(SDL_GL_SetSwapInterval(-1) != 0)
369 printf(
"[warning] can't set adaptive vsync...\n");
371 if(SDL_GL_GetSwapInterval() != -1)
374 SDL_GL_SetSwapInterval(1);
377 printf(
"adaptive vsync ON\n");
381 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &n);
383 printf(
"MSAA %d samples\n", n);
387 app_start= std::chrono::high_resolution_clock::now();
392 GLenum err= glewInit();
395 printf(
"[error] loading extensions\n%s\n", glewGetErrorString(err));
396 SDL_GL_DeleteContext(context);
401 while(glGetError() != GL_NO_ERROR) {;}
405 if(GLEW_ARB_debug_output)
407 printf(
"debug output enabled...\n");
409 glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
411 glDebugMessageControlARB(GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);
413 glDebugMessageCallbackARB(debug_print, NULL);
414 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
424 SDL_GL_DeleteContext(context);
428 static std::string smartpath;
429 static std::string path;
439 const char *envbase= std::getenv(
"GKIT_BASE_PATH");
440 if(envbase !=
nullptr)
442 path= std::string(envbase);
443 if(!path.empty() && path[path.size() -1] !=
'/')
446 printf(
"[base path] %s\n", path.c_str());
453 char *base= SDL_GetBasePath();
454 printf(
"[base path] %s\n", base);
459 smartpath= path + filename;
460 if(exists(smartpath.c_str()))
461 return smartpath.c_str();
463 smartpath= path +
"../" + filename;
464 if(exists(smartpath.c_str()))
465 return smartpath.c_str();
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.
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.
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 std::vector< std::string > & drop_events()
drag/drop. recupere tous les fichiers.
Window create_window(const int w, const int h, const int major, const int minor, const int samples)
creation d'une fenetre pour l'application.
void clear_drop_event()
desactive drag/drop.
void clear_text_event()
desactive l'evenement.
void release_context(Context context)
detruit le contexte openGL.
void clear_wheel_event()
desactive l'evenement.
const char * drop_event()
drag/drop, renvoie le dernier fichier.
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.
const char * smart_path(const char *filename)
renvoie le chemin(path) vers le fichier 'filename' apres l'avoir cherche dans un repertoire standard....
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.
float length(const Vector &v)
renvoie la longueur d'un vecteur.
int run(Window window, int(*draw)())
boucle de gestion des evenements de l'application.