summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2018-02-23 15:31:53 +0100
committerChristoph Helma <helma@in-silico.ch>2018-02-23 15:31:53 +0100
commitcc569501de2559624cf4ee39d064881fbc6e8c25 (patch)
tree30ab41cf2c747017af361fdfe10482864d21165f
parentcbe481d6cb93cc87188d1f791296ba7e74a21b9b (diff)
initial video recording
-rw-r--r--shader.frag66
-rw-r--r--sv.c193
2 files changed, 114 insertions, 145 deletions
diff --git a/shader.frag b/shader.frag
index 07b7a28..f76c968 100644
--- a/shader.frag
+++ b/shader.frag
@@ -4,14 +4,12 @@ precision mediump float;
#endif
uniform vec2 resolution;
+uniform float time;
uniform float ticks;
uniform int program;
uniform sampler2D images[8];
layout (binding = 0,rgba32f) uniform image2D backbuffer;
-uniform float ratios[4];
-uniform int idx[2];
-uniform float vel[2];
uniform float params[4];
out vec4 fragColor;
@@ -20,19 +18,63 @@ float random (in float x) {
return fract(sin(x)*43758.5453123)-0.5;
}
-vec2 coordinates(int i) {
- vec2 st = gl_FragCoord.xy/resolution.xy;
+vec2 st() {
+ return gl_FragCoord.xy/resolution.xy;
+}
+ivec2 ist() {
+ return ivec2(gl_FragCoord.xy/resolution.xy*resolution);
+}
+
+vec2 zoom(vec2 st, float amount) {
+ st -= 0.5;
+ st *= amount;
+ st += 0.5;
+ return st;
+}
+
+vec2 translate(vec2 st, vec2 amount) {
+ st -= 0.5;
+ st += amount;
+ st += 0.5;
return st;
}
+mat2 rotate2d(float _angle){
+ return mat2(cos(_angle),-sin(_angle), sin(_angle),cos(_angle));
+}
+
void main (void) {
- vec4 img;
- vec2 st = coordinates(idx[0]);
- img = texture2D(images[idx[0]],st);
- st = coordinates(idx[1]);
- img = pow(img, texture2D(images[idx[1]],st));
- if (program != 0) {
- img.rgb = img.rgb*params[0];
+ vec4 img;
+ vec2 coord;
+ if (program == 0) {
+ //coord = zoom(st(),0.5*(1.0-params[0]));
+ coord = zoom(st(),sin(time));
+ img = texture2D(images[0],coord);
+ img -= params[1]*(1.0-texture2D(images[1],st()));
+ }
+ else if (program == 1) {
+ coord = zoom(st(),(1.0-1.5*params[0]));
+ img = texture2D(images[3],coord);
+ coord = zoom(st(),0.5*(1.0-0.5*params[2]));
+ vec3 i2 = texture2D(images[2],coord).rgb;
+ img.rgb = pow(img.rgb,5*i2);
}
+ else if (program == 2) {
+ coord = zoom(st(),(1.0-1.5*params[0]));
+ img = texture2D(images[3],coord);
+ coord = zoom(st(),0.5*(1.0-0.5*params[2]));
+ coord *= rotate2d(ticks);
+ vec3 i2 = texture2D(images[2],coord).rgb;
+ img.rgb = pow(img.rgb,5*i2);
+ }
+ vec4 feedback = imageLoad(backbuffer,ist());
+ img = mix(img,feedback,0.5);
+ imageStore(backbuffer,ist(),img);
fragColor = img;
+ /*
+ fragColor = vec4(params[1]);
+ feedback.b += 0.01*cos(time/4.);
+ color.r = max(i.r,feedback.r);
+ */
}
+
diff --git a/sv.c b/sv.c
index 93a822d..2c48620 100644
--- a/sv.c
+++ b/sv.c
@@ -16,14 +16,13 @@
#define MIDICHK(stmt, msg) if((stmt) < 0) {puts("ERROR: "#msg); exit(1);}
-int width = 1920;
-int height = 1080;
+int width = 1918;
+int height = 1078;
GLFWwindow* window;
GLuint vertex;
GLuint fragment;
GLuint shaderProgram;
GLuint backbuffer;
-int bars;
typedef struct Shad {
GLuint id;
@@ -37,26 +36,22 @@ Shader shader;
typedef struct Img {
GLuint id;
char path[40];
- float ratio;
int new;
} Image;
Image images[8];
-typedef struct Param {
- float value;
- int new;
-} Parameter;
+float params[4];
-Parameter params[4];
+int recording = 1;
static snd_seq_t *seq_handle;
static int in_port;
void midi_open(void) {
MIDICHK(snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0), "Could not open sequencer");
- MIDICHK(snd_seq_set_client_name(seq_handle, "Midi Listener"), "Could not set client name");
- MIDICHK(in_port = snd_seq_create_simple_port(seq_handle, "listen:in", SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION), "Could not open port");
+ MIDICHK(snd_seq_set_client_name(seq_handle, "SV"), "Could not set client name");
+ MIDICHK(in_port = snd_seq_create_simple_port(seq_handle, "sv:in", SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION), "Could not open port");
}
void screenshot() {
@@ -149,21 +144,30 @@ void createShader() {
glUseProgram(shader.id);
};
+void imageUniforms(int i) {
+ glUniform1i(glGetUniformLocation(shader.id, "images")+i,i);
+ //glUniform1f(glGetUniformLocation(shader.id, "ratios")+i,images[i].ratio);
+}
+
+void resize_callback(GLFWwindow* window, int w, int h) {
+ width = w;
+ height = h;
+ glUniform2f(glGetUniformLocation(shader.id, "resolution"),width,height);
+}
+
void createWindow() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
- window = glfwCreateWindow(width,height, "", glfwGetPrimaryMonitor(), NULL);
+ //glfwWindowHint(GLFW_DECORATED, GL_FALSE);
+ window = glfwCreateWindow(width,height, "sv", NULL, NULL);
+ //window = glfwCreateWindow(width,height, "", glfwGetPrimaryMonitor(), NULL);
+ //glfwSetWindowSizeCallback(window, resize_callback);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwSetErrorCallback(error_callback);
glewInit();
}
-void imageUniforms(int i) {
- glUniform1i(glGetUniformLocation(shader.id, "images")+i,i);
- glUniform1f(glGetUniformLocation(shader.id, "ratios")+i,images[i].ratio);
-}
-
void readImage(int i) {
images[i].new = 1;
@@ -172,7 +176,7 @@ void readImage(int i) {
stbi_set_flip_vertically_on_load(1);
unsigned char* pixels = stbi_load(images[i].path, &w, &h, &comp, STBI_rgb_alpha);
- images[i].ratio = (float) w/h;
+ //images[i].ratio = (float) w/h;
imageUniforms(i);
glActiveTexture(GL_TEXTURE0+i);
@@ -184,6 +188,8 @@ void readImage(int i) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
stbi_image_free(pixels);
}
@@ -192,27 +198,20 @@ void updateImages(int force) {
for (int i = 0; i<8; i++) {
if (images[i].new || force) {
readImage(i);
- printf("%s\n",images[i].path);
images[i].new = 0;
}
}
}
-void updateParams(int force) {
- glUniform1i(glGetUniformLocation(shader.id, "bars"), bars);
+void updateParams() {
for (int i = 0; i<4; i++) {
- if (params[i].new || force) {
- glUniform1f(glGetUniformLocation(shader.id, "params")+i, params[i].value);
- params[i].new = 0;
- }
+ glUniform1f(glGetUniformLocation(shader.id, "params")+i, params[i]);
}
}
int ticks =0;
int running = 0;
-int idx[2] = {0,1};
-float vel[2] = {0,0};
-int program;
+int program=0;
void *readMidi() {
midi_open();
@@ -221,113 +220,23 @@ void *readMidi() {
snd_seq_event_input(seq_handle, &ev);
if (ev->type == SND_SEQ_EVENT_NOTEON) {
int note = ev->data.note.note;
- int v = ev->data.note.velocity;
- int i,j;
- if (note < 48) {
- i = 0;
- j = note-36;
- }
- else {
- i = 1;
- j = note-48;
- }
- // only white keys
- if (j == 0) {
- idx[i] = 0; vel[i] = (float)v/127.0;
- }
- else if (j == 2) {
- idx[i] = 1; vel[i] = (float)v/127.0;
- }
- else if (j == 4) {
- idx[i] = 2; vel[i] = (float)v/127.0;
- }
- else if (j == 5) {
- idx[i] = 3; vel[i] = (float)v/127.0;
- }
- else if (j == 7) {
- idx[i] = 4; vel[i] = (float)v/127.0;
- }
- else if (j == 9) {
- idx[i] = 5; vel[i] = (float)v/127.0;
- }
- else if (j == 11) {
- idx[i] = 6; vel[i] = (float)v/127.0;
- }
- else if (j == 12) {
- idx[i] = 7; vel[i] = (float)v/127.0;
- }
-
- }
- else if (ev->type == SND_SEQ_EVENT_NOTEOFF) {
- int note = ev->data.note.note;
- int i,j;
- if (note < 48) {
- i = 0;
- j = note-36;
- }
- else {
- i = 1;
- j = note-48;
- }
- // only white keys
- if (j == 0) {
- idx[i] = 0; vel[i] = 0;
- }
- else if (j == 2) {
- idx[i] = 1; vel[i] = 0;
- }
- else if (j == 4) {
- idx[i] = 2; vel[i] = 0;
- }
- else if (j == 5) {
- idx[i] = 3; vel[i] = 0;
- }
- else if (j == 7) {
- idx[i] = 4; vel[i] = 0;
- }
- else if (j == 9) {
- idx[i] = 5; vel[i] = 0;
- }
- else if (j == 11) {
- idx[i] = 6; vel[i] = 0;
- }
- else if (j == 12) {
- idx[i] = 7; vel[i] = 0;
- }
+ if (note >= 36) program = note-36;
}
else if(ev->type == SND_SEQ_EVENT_CONTROLLER) {
int p = ev->data.control.param;
int v = ev->data.control.value;
- if (p < 4) {
- params[p].value = (float)v/127;
- params[p].new = 1;
- }
- /*
- printf("[%d] Control: %2x val(%2x)\n", ev->time.tick,
- ev->data.control.param,
- ev->data.control.value);
- */
+ if (p < 4) params[p] = (float)v/127.0;
}
- else if(ev->type == SND_SEQ_EVENT_PGMCHANGE) {
- program = ev->data.control.value;
- }
- else if(ev->type == SND_SEQ_EVENT_SONGPOS) {
+ else if(ev->type == SND_SEQ_EVENT_SONGPOS)
ticks = ev->data.control.value*24;
- printf("[%d] SPP: %i val(%i)\n", ev->time.tick,
- ev->data.control.param,
- ev->data.control.value);
- }
else if(ev->type == SND_SEQ_EVENT_START)
running = 1;
else if(ev->type == SND_SEQ_EVENT_STOP)
running = 0;
else if(ev->type == SND_SEQ_EVENT_CONTINUE)
running = 1;
- else if(ev->type == SND_SEQ_EVENT_CLOCK) {
+ else if(ev->type == SND_SEQ_EVENT_CLOCK)
if (running == 1) ticks++;
- }
- //else
- //printf("[%d] Unknown: Unhandled Event Received\n", ev->time.tick);
}
}
@@ -355,36 +264,54 @@ int main(int argc, char **argv) {
glCreateTextures(GL_TEXTURE_2D,1,&backbuffer);
glTextureStorage2D(backbuffer,1,GL_RGBA32F,width,height);
glBindImageTexture(0,backbuffer, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
+ updateImages(0);
pthread_t midiin_t;
pthread_create(&midiin_t, NULL, readMidi, NULL);
pthread_t frag_t;
pthread_create(&frag_t, NULL, watchShader, NULL);
+ FILE* ffmpeg;
+ if (recording) {
+ //char* cmd;
+ printf("%ix%i\n",width,height);
+ time_t current_time = time(NULL);
+ char output_file[25];
+ strftime(output_file, 25, "%Y-%m-%d_%H%M%S.mp4", localtime(&current_time));
+ //printf(output_file);
+ const char* cmd = "ffmpeg -r 24 -f rawvideo -pix_fmt rgba -s 1918x1078 -i - "
+ "-threads 0 -preset veryfast -y -pix_fmt yuv420p -c:v libx264 -crf 18 -vf vflip output.mp4";
+
+ printf(cmd);
+ ffmpeg = popen(cmd, "w");
+ /*
+ sprintf(cmd,"ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %ix%i -i - -threads 0 -preset fast -y -pix_fmt yuv420p -crf 21 -vf vflip %s",width,height,output_file);
+ */
+ }
+
while (!glfwWindowShouldClose(window)) {
- //glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
- //glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
+ glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
glUniform1f(glGetUniformLocation(shader.id, "ticks"),(float)ticks);
glUniform1i(glGetUniformLocation(shader.id, "program"),program);
- for (int i = 0; i<2; i++) {
- glUniform1i(glGetUniformLocation(shader.id, "idx")+i,idx[i]);
- glUniform1f(glGetUniformLocation(shader.id, "vel")+i,vel[i]);
- }
if (shader.new) {
createShader();
glUniform2f(glGetUniformLocation(shader.id, "resolution"),width,height); // important!!
- for (int i = 0; i<4; i++) { imageUniforms(i); }
- updateParams(1);
+ for (int i = 0; i<8; i++) { imageUniforms(i); }
+ updateParams();
shader.new = 0;
}
- updateImages(0);
- updateParams(0);
+ updateParams();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glfwSwapBuffers(window);
+ if (recording) {
+ unsigned char buffer[width*height*4];
+ glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ fwrite(buffer, sizeof(int)*width*height, 1, ffmpeg);
+ }
glfwPollEvents();
}
- //pthread_cancel(stdin_t);
+ if (recording) pclose(ffmpeg);
pthread_cancel(midiin_t);
pthread_cancel(frag_t);
glfwDestroyWindow(window);