summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2017-05-11 20:50:45 -0400
committerPaul Duncan <pabs@pablotron.org>2017-05-11 20:50:45 -0400
commitbb1babd424c9e4430bea95642e06e31de00ec082 (patch)
tree953ccaab0ca4f09db93400b53aa6828b1244ba27
parent3ad598cad5f26b4d833af11931352de19db10fe9 (diff)
downloadcompute-test-bb1babd424c9e4430bea95642e06e31de00ec082.tar.bz2
compute-test-bb1babd424c9e4430bea95642e06e31de00ec082.zip
add context_t and handle_events()
-rw-r--r--main.c262
1 files changed, 115 insertions, 147 deletions
diff --git a/main.c b/main.c
index e02ab55..b26de0d 100644
--- a/main.c
+++ b/main.c
@@ -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;