diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | glslview.c | 149 |
3 files changed, 152 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3acbfea --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +glslview diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aa6d2b1 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +glslview : glslview.c + gcc -o glslview glslview.c -lSDL2 -lGL -lGLEW -Wall diff --git a/glslview.c b/glslview.c new file mode 100644 index 0000000..843319f --- /dev/null +++ b/glslview.c @@ -0,0 +1,149 @@ +#include <stdbool.h> +#include <stdio.h> +#include <unistd.h> + +#include <GL/glew.h> + +#include <SDL2/SDL.h> +#include <SDL2/SDL_opengl.h> + + + +static GLint time; +static GLint res; + + +char * readfile(const char *filename) { + FILE *f = fopen(filename, "r"); + if (!f) + return NULL; + + size_t size = 1024; + char *buffer = malloc(size+1); + size_t count = 0, r; + + do { + if (count == size) { + size *= 2; + buffer = realloc(buffer, size+1); + } + + r = fread(buffer+count, 1, size-count, f); + count += r; + } while (r); + + fclose(f); + + buffer[count] = 0; + + return buffer; +} + +void printShaderInfoLog(GLuint obj) { + GLint length = 0; + + glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &length); + + if(length > 0) { + char log[length]; + + glGetShaderInfoLog(obj, sizeof(log), NULL, log); + fprintf(stderr, "%s\n", log); + } +} + +void printProgramInfoLog(GLuint obj) { + GLint length = 0; + + glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &length); + + if(length > 0) { + char log[length]; + + glGetProgramInfoLog(obj, sizeof(log), NULL, log); + fprintf(stderr, "%s\n", log); + } +} + +void init(char *filename) { + glewInit(); + + glDisable(GL_DEPTH_TEST); + + char *shader = readfile(filename); + if (!shader) { + fprintf(stderr, "Error: unable to read '%s'\n", filename); + exit(1); + } + + GLuint frag = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(frag, 1, (const GLchar **)&shader, NULL); + glCompileShader(frag); + printShaderInfoLog(frag); + + GLuint program = glCreateProgram(); + glAttachShader(program, frag); + + glLinkProgram(program); + printProgramInfoLog(program); + + glBindFragDataLocation(program, 0, "fragColor"); + time = glGetUniformLocation(program, "time"); + res = glGetUniformLocation(program, "res"); + + glUseProgram(program); + + +} + +void render(SDL_Window *window) { + int width, height; + SDL_GetWindowSize(window, &width, &height); + + glViewport(0, 0, (GLsizei)width, (GLsizei)height); + + glUniform1f(time, SDL_GetTicks()); + glUniform2f(res, width, height); + + glBegin(GL_QUADS); + glVertex2f(-1, -1); + glVertex2f(1, -1); + glVertex2f(1, 1); + glVertex2f(-1, 1); + glEnd(); + + SDL_GL_SwapWindow(window); +} + + +int main(int argc, char *argv[]) { + bool running = true; + + if (argc != 2) { + fprintf(stderr, "Usage: glslview <shader>\n"); + exit(1); + } + + SDL_Init(SDL_INIT_VIDEO); + + SDL_Window *window = SDL_CreateWindow("glslview", 0, 0, 800, 800, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + SDL_GL_CreateContext(window); + + init(argv[1]); + + while (running) { + SDL_Event e; + + while( SDL_PollEvent(&e)) { + if(e.type == SDL_QUIT) { + running = false; + break; + } + } + + render(window); + //usleep(1); + } + + return 0; +} |