summary refs log tree commit diff
diff options
context:
space:
mode:
-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);