#include <stdlib.h>
#include <assert.h>
#include <GL/glew.h>
-#ifdef __APPLE__
-#include <GLUT/glut.h>
-#else
-#include <GL/glut.h>
-#endif
+#include <SDL2/SDL.h>
#include "app.h"
static bool init();
-static void display();
-static void idle();
-static void reshape(int x, int y);
-static void key_press(unsigned char key, int x, int y);
-static void key_release(unsigned char key, int x, int y);
-static void mouse(int bn, int st, int x, int y);
+static void process_event(SDL_Event *ev);
static void proc_modkeys();
+static SDL_Window *win;
+static SDL_GLContext ctx;
+static bool fullscreen, mouse_grabbed;
+static bool quit;
+
static unsigned int start_time;
static unsigned int modkeys;
+static int scale_factor = 1;
+
int main(int argc, char **argv)
{
- glutInitWindowSize(1024, 768);
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
- glutCreateWindow("demo");
-
- glutDisplayFunc(display);
- glutIdleFunc(idle);
- glutReshapeFunc(reshape);
- glutKeyboardFunc(key_press);
- glutKeyboardUpFunc(key_release);
- glutMouseFunc(mouse);
- glutMotionFunc(app_mouse_motion);
- glutPassiveMotionFunc(app_mouse_motion);
+ if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
+ fprintf(stderr, "failed to initialize SDL\n");
+ return 1;
+ }
+
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
+ SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
+
+ int defpos = SDL_WINDOWPOS_UNDEFINED;
+ unsigned int sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
+
+ if(!(win = SDL_CreateWindow("demo", defpos, defpos, 1024, 768, sdlflags))) {
+ // try again without sRGB capability
+ SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 0);
+ if(!(win = SDL_CreateWindow("demo", defpos, defpos, 1024, 768, sdlflags))) {
+ fprintf(stderr, "failed to create window\n");
+ SDL_Quit();
+ return 1;
+ }
+ }
+
+ if(!(ctx = SDL_GL_CreateContext(win))) {
+ fprintf(stderr, "failed to create OpenGL context\n");
+ SDL_Quit();
+ return 1;
+ }
+ SDL_GL_GetDrawableSize(win, &win_width, &win_height);
+ win_aspect = (float)win_width / (float)win_height;
if(!init()) {
+ SDL_Quit();
return 1;
}
- atexit(app_cleanup);
+ app_reshape(win_width, win_height);
- glutMainLoop();
+ while(!quit) {
+ SDL_Event ev;
+
+ time_msec = SDL_GetTicks() - start_time;
+ while(SDL_PollEvent(&ev)) {
+ process_event(&ev);
+ if(quit) goto break_evloop;
+ }
+
+ app_display();
+ }
+break_evloop:
+
+ app_cleanup();
+ SDL_Quit();
return 0;
}
void app_swap_buffers()
{
- glutSwapBuffers();
+ SDL_GL_SwapWindow(win);
}
void app_quit()
{
- exit(0);
+ quit = true;
}
unsigned int app_get_modifiers()
return false;
}
- start_time = glutGet(GLUT_ELAPSED_TIME);
+ start_time = SDL_GetTicks();
return true;
}
-static void display()
-{
- time_msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
- app_display();
-}
-
-static void idle()
-{
- glutPostRedisplay();
-}
-
-static void reshape(int x, int y)
-{
- win_width = x;
- win_height = y;
-
- app_reshape(x, y);
-}
-
-static void key_press(unsigned char key, int x, int y)
-{
- proc_modkeys();
- app_keyboard(key, true);
-}
-
-static void key_release(unsigned char key, int x, int y)
-{
- proc_modkeys();
- app_keyboard(key, false);
-}
-
-static void mouse(int bn, int st, int x, int y)
+static void process_event(SDL_Event *ev)
{
- int bidx = bn - GLUT_LEFT_BUTTON;
- bool down = st == GLUT_DOWN;
-
- proc_modkeys();
- app_mouse_button(bidx, down, x, y);
+ switch(ev->type) {
+ case SDL_QUIT:
+ quit = true;
+ break;
+
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ proc_modkeys();
+ app_keyboard(ev->key.keysym.sym, ev->key.state == SDL_PRESSED);
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ proc_modkeys();
+ app_mouse_button(ev->button.button - SDL_BUTTON_LEFT, ev->button.state == SDL_PRESSED,
+ ev->button.x * scale_factor, ev->button.y * scale_factor);
+ break;
+
+ case SDL_MOUSEMOTION:
+ if(mouse_grabbed) {
+ app_mouse_delta(ev->motion.xrel, ev->motion.yrel);
+ } else {
+ app_mouse_motion(ev->motion.x * scale_factor, ev->motion.y * scale_factor);
+ }
+ break;
+
+ case SDL_WINDOWEVENT:
+ if(ev->window.event == SDL_WINDOWEVENT_RESIZED) {
+ SDL_GL_GetDrawableSize(win, &win_width, &win_height);
+ win_aspect = (float)win_width / (float)win_height;
+ scale_factor = win_width / ev->window.data1;
+ app_reshape(win_width, win_height);
+ }
+ break;
+ }
}
static void proc_modkeys()
{
- int glutmod = glutGetModifiers();
-
modkeys = 0;
- if(glutmod & GLUT_ACTIVE_SHIFT) {
+ SDL_Keymod sdlmod = SDL_GetModState();
+ if(sdlmod & KMOD_SHIFT) {
modkeys |= MOD_SHIFT;
}
- if(glutmod & GLUT_ACTIVE_CTRL) {
- modkeys |= MOD_CTRL;
- }
- if(glutmod & GLUT_ACTIVE_ALT) {
+ if(sdlmod & KMOD_ALT) {
modkeys |= MOD_ALT;
}
+ if(sdlmod & KMOD_CTRL) {
+ modkeys |= MOD_CTRL;
+ }
}