diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | glslview.c | 111 |
2 files changed, 99 insertions, 20 deletions
@@ -1,7 +1,11 @@ all : glslview glslwrite +USE_INOTIFY = -DUSE_INOTIFY + +CFLAGS = -O3 -Wall $(USE_INOTIFY) + glslview : glslview.c - $(CC) -o $@ $^ -lSDL2 -lGL -lGLEW -Wall + $(CC) $(CFLAGS) -o $@ $^ -lSDL2 -lGL -lGLEW glslwrite : glslview.c - $(CC) -o $@ $^ -DGLSLWRITE -lSDL2 -lpng -lGL -lGLEW -Wall + $(CC) $(CFLAGS) -o $@ $^ -DGLSLWRITE -lSDL2 -lpng -lGL -lGLEW @@ -1,8 +1,16 @@ +#include <fcntl.h> +#include <limits.h> #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <unistd.h> +#ifdef USE_INOTIFY +# include <sys/inotify.h> +# include <sys/stat.h> +# include <sys/types.h> +#endif + #ifdef GLSLWRITE # include <png.h> #endif @@ -14,16 +22,27 @@ #ifdef GLSLWRITE + static unsigned frame_time = 0; + +#else + +static unsigned time_orig = 0; + +#ifdef USE_INOTIFY +static int inotify_fd = -1; #endif +#endif + +static char *filename; static GLint time_loc; static GLint res_loc; -static char * readfile(const char *filename) { - FILE *f = fopen(filename, "r"); +static char * readfile(const char *name) { + FILE *f = fopen(name, "r"); if (!f) return NULL; @@ -74,15 +93,11 @@ static void printProgramInfoLog(GLuint obj) { } } -static void init(char *filename) { - glewInit(); - - glDisable(GL_DEPTH_TEST); - +static void load(void) { char *shader = readfile(filename); if (!shader) { fprintf(stderr, "Error: unable to read '%s'\n", filename); - exit(1); + return; } GLuint frag = glCreateShader(GL_FRAGMENT_SHADER); @@ -101,6 +116,43 @@ static void init(char *filename) { res_loc = glGetUniformLocation(program, "res"); glUseProgram(program); + + free(shader); + glDeleteShader(frag); + glDeleteProgram(program); +} + +static void init(void) { +#if defined(USE_INOTIFY) && !defined(GLSLWRITE) + inotify_fd = inotify_init(); + if (inotify_fd < 0) { + fprintf(stderr, "unable to initialize inotify\n"); + exit(1); + } + + int watch = inotify_add_watch(inotify_fd, filename, IN_CLOSE_WRITE); + if (watch < 0) { + fprintf(stderr, "unable to watch '%s' for changes\n", filename); + exit(1); + } + + fcntl(inotify_fd, F_SETFL, fcntl(inotify_fd, F_GETFL)|O_NONBLOCK); + +#endif + + glewInit(); + glDisable(GL_DEPTH_TEST); + glColor4f(0, 0, 0, 0); + + load(); +} + +static void check_reload(void) { +#if defined(USE_INOTIFY) && !defined(GLSLWRITE) + char buf[sizeof(struct inotify_event) + NAME_MAX + 1]; + if (read(inotify_fd, buf, sizeof(buf)) > 0) + load(); +#endif } #ifdef GLSLWRITE @@ -159,7 +211,7 @@ static void render(int width, int height) { #ifdef GLSLWRITE glUniform1f(time_loc, frame_time); #else - glUniform1f(time_loc, SDL_GetTicks()); + glUniform1f(time_loc, SDL_GetTicks() - time_orig); #endif glUniform2f(res_loc, width, height); @@ -177,8 +229,6 @@ static void render(int width, int height) { int main(int argc, char *argv[]) { - bool running = true; - #ifdef GLSLWRITE if (argc != 3) { fprintf(stderr, "Usage: glslwrite <shader> <output directory>\n"); @@ -186,7 +236,7 @@ int main(int argc, char *argv[]) { } #else if (argc != 2) { - fprintf(stderr, "Usage: glslview <shader> <output directory>\n"); + fprintf(stderr, "Usage: glslview <shader>\n"); exit(1); } #endif @@ -199,20 +249,40 @@ int main(int argc, char *argv[]) { SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_Window *window = SDL_CreateWindow("glslwrite", 0, 0, 800, 800, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); - SDL_GL_CreateContext(window); + SDL_GLContext ctx = SDL_GL_CreateContext(window); - init(argv[1]); + filename = argv[1]; + init(); - while (running) { + while (true) { SDL_Event e; - while( SDL_PollEvent(&e)) { - if(e.type == SDL_QUIT) { - running = false; + while (SDL_PollEvent(&e)) { + switch (e.type) { + case SDL_KEYDOWN: + switch (e.key.keysym.sym) { + case SDLK_ESCAPE: + goto quit; + +#ifndef GLSLWRITE + case SDLK_l: + load(); + break; + + case SDLK_r: + time_orig = SDL_GetTicks(); + break; +#endif + } break; + + case SDL_QUIT: + goto quit; } } + check_reload(); + int width, height; SDL_GetWindowSize(window, &width, &height); @@ -224,5 +294,10 @@ int main(int argc, char *argv[]) { #endif } + quit: + SDL_GL_DeleteContext(ctx); + SDL_DestroyWindow(window); + SDL_Quit(); + return 0; } |