diff options
-rw-r--r-- | main.c | 262 |
1 files changed, 115 insertions, 147 deletions
@@ -1,5 +1,4 @@ #include <stdbool.h> -#include <stdio.h> #include <stdlib.h> #include <GL/glew.h> @@ -18,6 +17,20 @@ typedef struct { const char *src; } shader_t; +typedef struct { + SDL_Window *win; + + // times ring buffer + struct { + uint32_t draw_start, + draw_end; + } times[MAX_TIMES]; + uint32_t times_ofs; + + bool done, + fullscreen; +} context_t; + static const float verts[] = { -0.5, 0.5, 0, @@ -71,7 +84,7 @@ compile_shader( if (!ok) { GLchar log[1024]; glGetShaderInfoLog(r, sizeof(log), NULL, log); - fprintf(stderr, "Shader Compile Error: %s\n", log); + SDL_Log("glCompileShader() failed: %s", log); exit(EXIT_FAILURE); } @@ -88,7 +101,10 @@ link_program( GLuint r = glCreateProgram(); // compile shaders + // (FIXME: check num_shaders < 128) GLuint ids[128]; + if (num_shaders >= 128) { + } for (size_t i = 0; i < num_shaders; i++) { // compile shader ids[i] = compile_shader(shaders[i].type, shaders[i].src); @@ -106,7 +122,7 @@ link_program( if (!ok) { GLchar log[1024]; glGetProgramInfoLog(r, sizeof(log), NULL, log); - fprintf(stderr, "Program Link Error: %s\n", log); + SDL_Log("glLinkProgram() failed: %s", log); exit(EXIT_FAILURE); } @@ -119,56 +135,6 @@ link_program( return r; } -#if 0 -static GLuint -link_render_program( - const char * const vs_src, - const char * const fs_src -) { - // create program - GLuint r = glCreateProgram(); - - // compile shaders - GLuint vs = compile_shader(GL_VERTEX_SHADER, vs_src), - fs = compile_shader(GL_FRAGMENT_SHADER, fs_src); - - // attach shaders - glAttachShader(r, vs); - glAttachShader(r, fs); - - // link program - glLinkProgram(r); - - // check link status - GLint ok; - glGetProgramiv(r, GL_LINK_STATUS, &ok); - if (!ok) { - GLchar log[1024]; - glGetProgramInfoLog(r, sizeof(log), NULL, log); - fprintf(stderr, "Program Link Error: %s\n", log); - exit(EXIT_FAILURE); - } - - // delete shaders - glDeleteShader(vs); - glDeleteShader(fs); - - // return result - return r; -} -#endif /* 0 */ - -#if 0 -static GLuint -link_compute_program( - const char * const cs_src -) { - // create program - GLuint r = glCreateProgram(); - -} -#endif /* 0 */ - static void update_viewport( SDL_Window *win @@ -182,8 +148,8 @@ update_viewport( glViewport(0, 0, w, h); } -static SDL_Window * -init(void) { +static void +ctx_init(context_t * const ctx) { // init sdl if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { SDL_Log("SDL_Init() failed: %s", SDL_GetError()); @@ -191,7 +157,7 @@ init(void) { } // create window - SDL_Window *win = SDL_CreateWindow( + ctx->win = SDL_CreateWindow( "Compute Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, @@ -201,7 +167,7 @@ init(void) { ); // check for error - if (!win) { + if (!ctx->win) { SDL_Log("SDL_CreateWindow() failed: %s", SDL_GetError()); exit(EXIT_FAILURE); } @@ -228,7 +194,7 @@ init(void) { } // create GL context - SDL_GLContext context = SDL_GL_CreateContext(win); + SDL_GLContext context = SDL_GL_CreateContext(ctx->win); if (!context) { SDL_Log("SDL_GL_CreateContext() failed: %s", SDL_GetError()); exit(EXIT_FAILURE); @@ -246,7 +212,7 @@ init(void) { // set viewport size // (after GLEW init) - update_viewport(win); + update_viewport(ctx->win); // set swap interval // (after context init) @@ -255,8 +221,85 @@ init(void) { exit(EXIT_FAILURE); } - // return window - return win; + // init times ring buffer + memset(ctx->times, 0, MAX_TIMES * sizeof(uint32_t) * 2); + ctx->times_ofs = 0; + + // init flags + ctx->done = false; + ctx->fullscreen = false; +} + +static void +handle_events( + context_t * const ctx +) { + SDL_Event ev; + + while (SDL_PollEvent(&ev)) { + switch (ev.type) { + case SDL_QUIT: + ctx->done = true; + break; + case SDL_KEYDOWN: + switch (ev.key.keysym.sym) { + case SDLK_q: + case SDLK_ESCAPE: + ctx->done = true; + + break; + case SDLK_F11: + // toggle fullscreen + ctx->fullscreen = !ctx->fullscreen; + + if (SDL_SetWindowFullscreen( + ctx->win, + ctx->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0 + ) < 0) { + // log warning + SDL_Log("SDL_SetWindowFullscreen() failed: %s", SDL_GetError()); + ctx->fullscreen = !ctx->fullscreen; + } + + break; + } + + break; + case SDL_WINDOWEVENT: + switch (ev.window.event) { + case SDL_WINDOWEVENT_SIZE_CHANGED: + { + // map event to window + SDL_Window *ev_win = SDL_GetWindowFromID(ev.window.windowID); + + if (ev_win == ctx->win) { + // update viewport + update_viewport(ctx->win); + } else { + SDL_Log("ignoring SIZE_CHANGED event from unknown window"); + } + } + + break; + } + + break; + case SDL_USEREVENT: + if (ev.user.code == EVENT_CODE_TIMER) { + uint32_t sum = 0; + + #pragma omp parallel for reduction(+:sum) + for (int i = 0; i < MAX_TIMES; i++) { + sum += ctx->times[i].draw_end - ctx->times[i].draw_start; + } + + // print fps + SDL_Log("fps: %f", sum * 1.0 / MAX_TIMES); + } + + break; + } + } } static Uint32 timer_cb( @@ -284,15 +327,9 @@ int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); - // init SDL - SDL_Window *win = init(); - - // init times ring buffer - struct { - uint32_t draw_start, - draw_end; - } times[MAX_TIMES] = { { 0, 0 } }; - uint32_t times_ofs = 0; + // init context + context_t ctx; + ctx_init(&ctx); // init timer (5 seconds) SDL_TimerID timer_id = SDL_AddTimer(5000, timer_cb, NULL); @@ -314,20 +351,17 @@ int main(int argc, char *argv[]) { // unbind vao glBindVertexArray(0); - // link program + // link program, get uniforms GLuint prog = link_program(2, RENDER_SHADERS); GLint u_time = glGetUniformLocation(prog, "time"); - // init flags - bool done = false, fullscreen = false; - // main loop - while (!done) { + while (!ctx.done) { // get start time uint32_t now = SDL_GetTicks(); // save start time - times[times_ofs].draw_start = now; + ctx.times[ctx.times_ofs].draw_start = now; // clear screen glClearColor(0, 0, 0, 1); @@ -343,80 +377,14 @@ int main(int argc, char *argv[]) { glBindVertexArray(0); // swap buffer - SDL_GL_SwapWindow(win); + SDL_GL_SwapWindow(ctx.win); // save end time - times[times_ofs].draw_end = SDL_GetTicks(); - times_ofs = (times_ofs + 1) & MAX_TIMES; + ctx.times[ctx.times_ofs].draw_end = SDL_GetTicks(); + ctx.times_ofs = (ctx.times_ofs + 1) & MAX_TIMES; // handle events - { - SDL_Event ev; - - while (SDL_PollEvent(&ev)) { - switch (ev.type) { - case SDL_QUIT: - done = true; - break; - case SDL_KEYDOWN: - switch (ev.key.keysym.sym) { - case SDLK_q: - case SDLK_ESCAPE: - done = true; - - break; - case SDLK_F11: - // toggle fullscreen - fullscreen = !fullscreen; - - if (SDL_SetWindowFullscreen( - win, - fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0 - ) < 0) { - SDL_Log("SDL_SetWindowFullscreen() failed: %s", SDL_GetError()); - fullscreen = !fullscreen; - } - - break; - } - - break; - case SDL_WINDOWEVENT: - switch (ev.window.event) { - case SDL_WINDOWEVENT_SIZE_CHANGED: - { - // map event to window - SDL_Window *win = SDL_GetWindowFromID(ev.window.windowID); - - if (win) { - // update viewport - update_viewport(win); - } else { - SDL_Log("ignoring SIZE_CHANGED event from unknown window"); - } - } - - break; - } - - break; - case SDL_USEREVENT: - if (ev.user.code == EVENT_CODE_TIMER) { - uint32_t sum = 0; - - #pragma omp parallel for reduction(+:sum) - for (int i = 0; i < MAX_TIMES; i++) { - sum += times[i].draw_end - times[i].draw_start; - } - - // print fps - SDL_Log("fps: %f", sum * 1.0 / MAX_TIMES); - } - - break; - } - } - } + handle_events(&ctx); } // remove timer @@ -431,7 +399,7 @@ int main(int argc, char *argv[]) { } // destroy window - SDL_DestroyWindow(win); + SDL_DestroyWindow(ctx.win); // return success return EXIT_SUCCESS; |