Compare commits
10 commits
85cf184935
...
76a70a787b
Author | SHA1 | Date | |
---|---|---|---|
76a70a787b | |||
ce381dec2a | |||
38e77ee6f7 | |||
53d2f9369a | |||
3a2d45fb93 | |||
ee22df9211 | |||
1ec5502d46 | |||
b65b742403 | |||
d521cc0e83 | |||
05e2f21d27 |
17 changed files with 326 additions and 64 deletions
13
Makefile
13
Makefile
|
@ -1,12 +1,17 @@
|
||||||
all : glslview glslwrite
|
all : glslview glslwrite
|
||||||
|
|
||||||
USE_INOTIFY = -DUSE_INOTIFY
|
ifeq ($(shell uname -s),Linux)
|
||||||
|
USE_INOTIFY ?= -DUSE_INOTIFY
|
||||||
|
endif
|
||||||
|
|
||||||
CFLAGS = -O3 -Wall $(USE_INOTIFY)
|
CFLAGS ?= -O3 -Wall
|
||||||
LIBS = -lSDL2 -lGL -lGLEW -lm
|
LIBS := -lSDL2 -lGL -lGLEW -lm
|
||||||
|
|
||||||
glslview : glslview.c common.c common.h
|
glslview : glslview.c common.c common.h
|
||||||
$(CC) $(CFLAGS) -o $@ glslview.c common.c $(LIBS)
|
$(CC) $(CFLAGS) $(USE_INOTIFY) -o $@ glslview.c common.c $(LIBS)
|
||||||
|
|
||||||
glslwrite : glslwrite.c common.c common.h
|
glslwrite : glslwrite.c common.c common.h
|
||||||
$(CC) $(CFLAGS) -o $@ glslwrite.c common.c $(LIBS) -lpng
|
$(CC) $(CFLAGS) -o $@ glslwrite.c common.c $(LIBS) -lpng
|
||||||
|
|
||||||
|
clean :
|
||||||
|
rm -f glslview glslwrite
|
||||||
|
|
129
README.txt
Normal file
129
README.txt
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
glslview
|
||||||
|
========
|
||||||
|
|
||||||
|
glslview is a simple program to run GLSL fragment shaders and interact with them.
|
||||||
|
|
||||||
|
glslview will render a simple fullscreen rectangle, the shader will determine each
|
||||||
|
pixel's color.
|
||||||
|
|
||||||
|
The glslwrite tool can be used to write the generated frames to PNG files
|
||||||
|
(with transparency support!).
|
||||||
|
|
||||||
|
You will need a graphics adapter and drivers with modern OpenGL/GLSL support.
|
||||||
|
|
||||||
|
Building
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
glslview has been tested on Linux only, but it should work on other systems as well.
|
||||||
|
If it doesn't, I'm happy to take patches.
|
||||||
|
|
||||||
|
glslview has the following dependencies:
|
||||||
|
|
||||||
|
* SDL2
|
||||||
|
* libGL
|
||||||
|
* libGLEW
|
||||||
|
|
||||||
|
glslwrite additionally depends on libpng.
|
||||||
|
|
||||||
|
On Linux, glslview will use inotify to watch the loaded shader file for changes.
|
||||||
|
|
||||||
|
|
||||||
|
Running
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
Shader
|
||||||
|
------
|
||||||
|
|
||||||
|
glslview will supply the following uniform parameters to the shader:
|
||||||
|
|
||||||
|
vec2 res
|
||||||
|
The current resolution of the window
|
||||||
|
|
||||||
|
float time
|
||||||
|
Current time in milliseconds (by default since start of the program)
|
||||||
|
|
||||||
|
int param0, param1, param2
|
||||||
|
Modifiable parameters, 0 by default
|
||||||
|
|
||||||
|
The shader must define an output vec4 called "fragColor" into which the fragment color
|
||||||
|
is to be written.
|
||||||
|
|
||||||
|
See the examples provided with the source for more information. The "symmetry"
|
||||||
|
example makes use of all parameters.
|
||||||
|
|
||||||
|
|
||||||
|
Command line
|
||||||
|
------------
|
||||||
|
|
||||||
|
glslview <options> <shader>
|
||||||
|
glslwrite <options> <shader> <output directory>
|
||||||
|
|
||||||
|
|
||||||
|
Common options:
|
||||||
|
|
||||||
|
-w <width>
|
||||||
|
Initial window width (default: 800)
|
||||||
|
|
||||||
|
-h <height>
|
||||||
|
Initial window height (default: 800)
|
||||||
|
|
||||||
|
-0, -1, -2 <param>
|
||||||
|
Initial value for the shader parameters
|
||||||
|
|
||||||
|
|
||||||
|
glslview options:
|
||||||
|
|
||||||
|
-s <speed>
|
||||||
|
Initial speed factor (default: 1.0, negative values make time run backwards)
|
||||||
|
|
||||||
|
-t <time>
|
||||||
|
Initial time value (default: 0.0)
|
||||||
|
|
||||||
|
|
||||||
|
glslwrite options:
|
||||||
|
|
||||||
|
-s <step>
|
||||||
|
Time step between frames (default: 20.0)
|
||||||
|
|
||||||
|
-f <frame>
|
||||||
|
Number of frames to generate (default: run forever)
|
||||||
|
|
||||||
|
|
||||||
|
glslview control
|
||||||
|
----------------
|
||||||
|
|
||||||
|
+/-, scroll wheel
|
||||||
|
Change speed
|
||||||
|
|
||||||
|
=
|
||||||
|
Reset speed
|
||||||
|
|
||||||
|
<
|
||||||
|
Run backwards
|
||||||
|
|
||||||
|
>
|
||||||
|
Run forwards
|
||||||
|
|
||||||
|
r
|
||||||
|
Reset time
|
||||||
|
|
||||||
|
R
|
||||||
|
Reset parameters
|
||||||
|
|
||||||
|
l
|
||||||
|
Reload shader (if you're using a system without inotify, or inotify fails)
|
||||||
|
|
||||||
|
Space
|
||||||
|
Pause/continue
|
||||||
|
|
||||||
|
Page up/down
|
||||||
|
Modify param0
|
||||||
|
|
||||||
|
Left/right
|
||||||
|
Modify param1
|
||||||
|
|
||||||
|
Up/down
|
||||||
|
Modify param2
|
||||||
|
|
||||||
|
Escape
|
||||||
|
Quit
|
6
common.c
6
common.c
|
@ -36,9 +36,9 @@
|
||||||
char *filename;
|
char *filename;
|
||||||
float current_time = 0;
|
float current_time = 0;
|
||||||
|
|
||||||
GLint param0 = 0;
|
int param0 = 0;
|
||||||
GLint param1 = 0;
|
int param1 = 0;
|
||||||
GLint param2 = 0;
|
int param2 = 0;
|
||||||
|
|
||||||
|
|
||||||
static GLint time_loc;
|
static GLint time_loc;
|
||||||
|
|
11
common.h
11
common.h
|
@ -25,18 +25,13 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <GL/glew.h>
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
#include <SDL2/SDL_opengl.h>
|
|
||||||
|
|
||||||
|
|
||||||
extern char *filename;
|
extern char *filename;
|
||||||
extern float current_time;
|
extern float current_time;
|
||||||
|
|
||||||
extern GLint param0;
|
extern int param0;
|
||||||
extern GLint param1;
|
extern int param1;
|
||||||
extern GLint param2;
|
extern int param2;
|
||||||
|
|
||||||
|
|
||||||
void load(void);
|
void load(void);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
@ -56,13 +56,13 @@ void main(void) {
|
||||||
float k = param1;
|
float k = param1;
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
mat3 t = scale(0.3 + 0.02 * param2)
|
mat3 t = scale(1 + 0.03 * param2)
|
||||||
* rot(-PI/2*(k*i/n + time/1500))
|
* rot(-2*PI*i/n)
|
||||||
* trans(0.5, 0.0)
|
* trans(-0.5, 0.0)
|
||||||
* rot(2*PI*i/n)
|
* rot(PI/2*(k*i/n + time/1500))
|
||||||
* scale(1 / (1 + 0.03 * param2));
|
* scale(1 / (0.3 + 0.02 * param2));
|
||||||
|
|
||||||
float c = square(p * inverse(t));
|
float c = square(p * t);
|
||||||
scene = abs(scene - c);
|
scene = abs(scene - c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 330
|
#version 130
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
|
127
glslview.c
127
glslview.c
|
@ -25,14 +25,20 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_opengl.h>
|
||||||
|
|
||||||
#ifdef USE_INOTIFY
|
#ifdef USE_INOTIFY
|
||||||
# include <sys/inotify.h>
|
# include <sys/inotify.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
|
@ -40,6 +46,13 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int init_param0 = 0;
|
||||||
|
static int init_param1 = 0;
|
||||||
|
static int init_param2 = 0;
|
||||||
|
static float init_time = 0;
|
||||||
|
static float init_speed = 1.0;
|
||||||
|
|
||||||
|
static bool paused = false;
|
||||||
static float speed = 1.0;
|
static float speed = 1.0;
|
||||||
static unsigned previous_ticks = 0;
|
static unsigned previous_ticks = 0;
|
||||||
|
|
||||||
|
@ -53,22 +66,20 @@ static int inotify_watch = -1;
|
||||||
static void reset_watch(void) {
|
static void reset_watch(void) {
|
||||||
if (inotify_watch >= 0) {
|
if (inotify_watch >= 0) {
|
||||||
if (inotify_rm_watch(inotify_fd, inotify_watch)) {
|
if (inotify_rm_watch(inotify_fd, inotify_watch)) {
|
||||||
fprintf(stderr, "unable to remove watch\n");
|
fprintf(stderr, "unable to remove watch: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inotify_watch = inotify_add_watch(inotify_fd, filename, IN_CLOSE_WRITE);
|
inotify_watch = inotify_add_watch(inotify_fd, filename, IN_CLOSE_WRITE);
|
||||||
if (inotify_watch < 0) {
|
if (inotify_watch < 0)
|
||||||
fprintf(stderr, "unable to watch '%s' for changes\n", filename);
|
fprintf(stderr, "unable to watch '%s' for changes: %s\n", filename, strerror(errno));
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_watch(void) {
|
static void init_watch(void) {
|
||||||
inotify_fd = inotify_init();
|
inotify_fd = inotify_init();
|
||||||
if (inotify_fd < 0) {
|
if (inotify_fd < 0) {
|
||||||
fprintf(stderr, "unable to initialize inotify\n");
|
fprintf(stderr, "unable to initialize inotify: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,9 +105,20 @@ static void check_reload(void) {}
|
||||||
|
|
||||||
static void update(void) {
|
static void update(void) {
|
||||||
unsigned ticks = SDL_GetTicks();
|
unsigned ticks = SDL_GetTicks();
|
||||||
current_time += speed * (ticks - previous_ticks);
|
|
||||||
previous_ticks = ticks;
|
|
||||||
|
|
||||||
|
if (!paused)
|
||||||
|
current_time += speed * (ticks - previous_ticks);
|
||||||
|
|
||||||
|
previous_ticks = ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_speed(float v) {
|
||||||
|
speed = v;
|
||||||
|
printf("speed: %f\n", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_params(void) {
|
||||||
|
printf("params: %i %i %i\n", (int)param0, (int)param1, (int)param2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_input(const char *input) {
|
static void handle_input(const char *input) {
|
||||||
|
@ -108,45 +130,98 @@ static void handle_input(const char *input) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
current_time = 0;
|
current_time = init_time;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R':
|
case 'R':
|
||||||
param0 = param1 = param2 = 0;
|
param0 = init_param0;
|
||||||
|
param1 = init_param1;
|
||||||
|
param2 = init_param2;
|
||||||
|
print_params();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '+':
|
case '+':
|
||||||
speed *= 1.1;
|
set_speed(speed * 1.1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
speed /= 1.1;
|
set_speed(speed / 1.1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
if (speed < 0)
|
if (speed < 0)
|
||||||
speed = -1.0;
|
set_speed(-init_speed);
|
||||||
else
|
else
|
||||||
speed = 1.0;
|
set_speed(init_speed);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
if (speed > 0)
|
if (speed > 0)
|
||||||
speed = -speed;
|
set_speed(-speed);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
if (speed < 0)
|
if (speed < 0)
|
||||||
speed = -speed;
|
set_speed(-speed);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
paused = !paused;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
static void usage(void) {
|
||||||
if (argc != 2) {
|
fprintf(stderr, "Usage: glslview [-w <width>] [-h <height>] [-t <time>] [-s <speed>] [-0 <param0>] [-1 <param1>] [-2 <param2>] <shader>\n");
|
||||||
fprintf(stderr, "Usage: glslview <shader>\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int width = 800, height = 800;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int c = getopt(argc, argv, "w:h:t:s:0:1:2:");
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'w':
|
||||||
|
width = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
height = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
current_time = init_time = atof(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
speed = atof(optarg);
|
||||||
|
init_speed = fabsf(speed);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '0':
|
||||||
|
param0 = init_param0 = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '1':
|
||||||
|
param1 = init_param1 = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '2':
|
||||||
|
param2 = init_param2 = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Invalid option '%c'\n", optopt);
|
||||||
|
usage();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc - optind != 1)
|
||||||
|
usage();
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
|
||||||
|
@ -155,10 +230,10 @@ int main(int argc, char *argv[]) {
|
||||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
||||||
|
|
||||||
SDL_Window *window = SDL_CreateWindow("glslview", 0, 0, 800, 800, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
|
SDL_Window *window = SDL_CreateWindow("glslview", 0, 0, width, height, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
|
||||||
SDL_GLContext ctx = SDL_GL_CreateContext(window);
|
SDL_GLContext ctx = SDL_GL_CreateContext(window);
|
||||||
|
|
||||||
filename = argv[1];
|
filename = argv[optind];
|
||||||
|
|
||||||
init_watch();
|
init_watch();
|
||||||
init();
|
init();
|
||||||
|
@ -175,26 +250,32 @@ int main(int argc, char *argv[]) {
|
||||||
switch (e.key.keysym.sym) {
|
switch (e.key.keysym.sym) {
|
||||||
case SDLK_PAGEDOWN:
|
case SDLK_PAGEDOWN:
|
||||||
param0++;
|
param0++;
|
||||||
|
print_params();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_PAGEUP:
|
case SDLK_PAGEUP:
|
||||||
param0--;
|
param0--;
|
||||||
|
print_params();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_RIGHT:
|
case SDLK_RIGHT:
|
||||||
param1++;
|
param1++;
|
||||||
|
print_params();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_LEFT:
|
case SDLK_LEFT:
|
||||||
param1--;
|
param1--;
|
||||||
|
print_params();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_DOWN:
|
case SDLK_DOWN:
|
||||||
param2++;
|
param2++;
|
||||||
|
print_params();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_UP:
|
case SDLK_UP:
|
||||||
param2--;
|
param2--;
|
||||||
|
print_params();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_ESCAPE:
|
case SDLK_ESCAPE:
|
||||||
|
@ -207,7 +288,7 @@ int main(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_MOUSEWHEEL:
|
case SDL_MOUSEWHEEL:
|
||||||
speed /= pow(1.1, e.wheel.y);
|
set_speed(speed / pow(1.1, e.wheel.y));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
|
|
70
glslwrite.c
70
glslwrite.c
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
|
||||||
|
@ -36,12 +37,17 @@
|
||||||
#include <SDL2/SDL_opengl.h>
|
#include <SDL2/SDL_opengl.h>
|
||||||
|
|
||||||
|
|
||||||
|
static float step = 20;
|
||||||
|
static unsigned frame = 0;
|
||||||
|
static unsigned max_frame = 0;
|
||||||
|
|
||||||
|
|
||||||
static void savePNG(int width, int height, const char *output_dir) {
|
static void savePNG(int width, int height, const char *output_dir) {
|
||||||
uint8_t pixels[width*height*4];
|
uint8_t pixels[width*height*4];
|
||||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, pixels);
|
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, pixels);
|
||||||
|
|
||||||
char filename[strlen(output_dir) + 20];
|
char filename[strlen(output_dir) + 20];
|
||||||
snprintf(filename, sizeof(filename), "%s/%010u.png", output_dir, (unsigned)current_time);
|
snprintf(filename, sizeof(filename), "%s/%010u.png", output_dir, frame);
|
||||||
|
|
||||||
FILE *f = fopen(filename, "wb");
|
FILE *f = fopen(filename, "wb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
|
@ -84,11 +90,56 @@ static void savePNG(int width, int height, const char *output_dir) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
static void usage(void) {
|
||||||
if (argc != 3) {
|
fprintf(stderr, "Usage: glslwrite [-w <width>] [-h <height>] [-s <step>] [-f <frames>] [-0 <param0>] [-1 <param1>] [-2 <param2>] <shader>\n");
|
||||||
fprintf(stderr, "Usage: glslwrite <shader> <output directory>\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int width = 800, height = 800;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int c = getopt(argc, argv, "w:h:s:f:0:1:2:");
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'w':
|
||||||
|
width = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
height = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
step = atof(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
max_frame = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '0':
|
||||||
|
param0 = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '1':
|
||||||
|
param1 = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '2':
|
||||||
|
param2 = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Invalid option '%c'\n", optopt);
|
||||||
|
usage();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc - optind != 2)
|
||||||
|
usage();
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
|
||||||
|
@ -97,14 +148,14 @@ int main(int argc, char *argv[]) {
|
||||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
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_Window *window = SDL_CreateWindow("glslwrite", 0, 0, width, height, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
|
||||||
SDL_GLContext ctx = SDL_GL_CreateContext(window);
|
SDL_GLContext ctx = SDL_GL_CreateContext(window);
|
||||||
|
|
||||||
filename = argv[1];
|
filename = argv[optind];
|
||||||
init();
|
init();
|
||||||
load();
|
load();
|
||||||
|
|
||||||
while (true) {
|
while (!max_frame || frame < max_frame) {
|
||||||
SDL_Event e;
|
SDL_Event e;
|
||||||
|
|
||||||
while (SDL_PollEvent(&e)) {
|
while (SDL_PollEvent(&e)) {
|
||||||
|
@ -128,8 +179,9 @@ int main(int argc, char *argv[]) {
|
||||||
render(width, height);
|
render(width, height);
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
|
|
||||||
savePNG(width, height, argv[2]);
|
savePNG(width, height, argv[optind+1]);
|
||||||
current_time += 20;
|
current_time += step;
|
||||||
|
frame++;
|
||||||
}
|
}
|
||||||
|
|
||||||
quit:
|
quit:
|
||||||
|
|
Reference in a new issue