summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c140
1 files changed, 74 insertions, 66 deletions
diff --git a/sv.c b/sv.c
index 77957a2..4475271 100644
--- a/sv.c
+++ b/sv.c
@@ -4,9 +4,12 @@
#include <stdio.h>
#include <string.h>
#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#define STB_IMAGE_IMPLEMENTATION
-#include "std/stb_image.h"
+#include "stb_image.h"
int width = 1920;
int height = 1080;
@@ -17,7 +20,9 @@ GLuint shaderProgram;
typedef struct Shad {
GLuint id;
- char path[40];
+ char vertex[40];
+ char fragment[40];
+ time_t mtime;
int new;
} Shader;
@@ -33,12 +38,12 @@ typedef struct Img {
Image images[4];
typedef struct Param {
- char name[3];
+ //char name[3];
float value;
int new;
} Parameter;
-Parameter parameters[16];
+Parameter parameters[32];
static void error_callback(int error, const char* description) { fputs(description, stderr); }
@@ -47,14 +52,8 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
}
const char * readShader(char * path) {
- fputs(path,stderr);
- fputs("\n",stderr);
FILE *file = fopen(path, "r");
- if (!file) {
- fputs("Cannot read ",stderr);
- fputs(path,stderr);
- exit(EXIT_FAILURE);
- }
+ if (!file) { fprintf(stderr,"Cannot read %s\n",path); }
char source[2000];
int res = fread(source,1,2000-1,file);
source[res] = 0;
@@ -72,9 +71,7 @@ GLuint compileShader(const char * source, GLenum type) {
if (!success) {
char infoLog[512];
glGetShaderInfoLog(sh, 512, NULL, infoLog);
- fputs("Shader compilation failed:\n",stderr);
- fputs(infoLog,stderr);
- exit(EXIT_FAILURE);
+ fprintf(stderr,"Shader compilation failed: %s\n",infoLog);
}
else { return sh; }
}
@@ -87,12 +84,11 @@ GLuint linkShader(GLuint vertex, GLuint fragment) {
glAttachShader(shader.id, fragment);
glLinkProgram(shader.id);
int success;
- char infoLog[512];
glGetProgramiv(shader.id, GL_LINK_STATUS, &success);
if (!success) {
+ char infoLog[512];
glGetProgramInfoLog(shader.id, 512, NULL, infoLog);
- fputs("Shader linking failed:\n",stderr);
- fputs(infoLog,stderr);
+ fprintf(stderr,"Shader linking failed: %s\n",infoLog);
}
glDetachShader(shader.id, vertex);
glDetachShader(shader.id, fragment);
@@ -100,6 +96,16 @@ GLuint linkShader(GLuint vertex, GLuint fragment) {
glDeleteShader(fragment);
}
+void createShader() {
+ vertex = compileShader(readShader(shader.vertex), GL_VERTEX_SHADER);
+ fragment = compileShader(readShader(shader.fragment),GL_FRAGMENT_SHADER);
+ linkShader(vertex,fragment);
+ struct stat file_stat;
+ stat(shader.fragment, &file_stat);
+ shader.mtime = file_stat.st_mtime;
+ glUseProgram(shader.id);
+};
+
void createWindow() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
@@ -110,14 +116,6 @@ void createWindow() {
glewInit();
}
-void createShader(char *vert, char *frag) {
- vertex = compileShader(readShader(vert), GL_VERTEX_SHADER);
- fragment = compileShader(readShader(frag),GL_FRAGMENT_SHADER);
- linkShader(vertex,fragment);
- printf("%i\n",shader.id);
- glUseProgram(shader.id);
-};
-
void uniform1f(char * var, float f) {
int v = glGetUniformLocation(shader.id, var);
glUniform1f(v, f);
@@ -129,13 +127,13 @@ void uniform2f(char * var, float f0, float f1) {
}
void imageUniforms(int i) {
- Image image = images[i];
- char name[2];
- sprintf(name,"i%i",i);
- glUniform1i(glGetUniformLocation(shader.id, name), i);
- char ratioName[7];
- sprintf(ratioName,"%sratio",name);
- uniform1f(ratioName,images[i].ratio);
+ //Image image = images[i];
+ //char name[2];
+ //sprintf(name,"i%i",i);
+ glUniform1i(glGetUniformLocation(shader.id, "images")+i,i);
+ //char ratioName[7];
+ //sprintf(ratioName,"%sratio",name);
+ glUniform1f(glGetUniformLocation(shader.id, "ratios")+i,images[i].ratio);
}
void readImage(int i) {
@@ -160,26 +158,42 @@ void readImage(int i) {
stbi_image_free(pixels);
}
-void *readStdin() {
+void updateImages(int force) {
+ for (int i = 0; i<4; i++) {
+ if (images[i].new || force) {
+ readImage(i);
+ printf("%s\n",images[i].path);
+ images[i].new = 0;
+ }
+ }
+}
+
+void updateParams(int force) {
+ for (int i = 0; i<32; i++) {
+ if (parameters[i].new || force) {
+ glUniform1f(glGetUniformLocation(shader.id, "params")+i, parameters[i].value);
+ parameters[i].new = 0;
+ }
+ }
+}
+void *readStdin() {
while (1) {
char * str;
size_t l = 80;
getline(&str,&l,stdin);
char *n = strtok(str," ");
-
if (n[0] == 'i') {
- int i = n[1]-'0';
+ int i = atoi(strtok(NULL," "));
strncpy(images[i].path, strtok(NULL,"\n"),40);
images[i].new = 1;
}
else if (n[0] == 'f') {
- strncpy(shader.path, strtok(NULL,"\n"),40);
+ strncpy(shader.fragment, strtok(NULL,"\n"),40);
shader.new = 1;
}
else if (n[0] == 'p') {
- int i = n[1]-'0';
- strncpy(parameters[i].name,n,3);
+ int i = atoi(strtok(NULL," "));
parameters[i].value = atof(strtok (NULL,"\n"));
parameters[i].new = 1;
}
@@ -189,58 +203,52 @@ void *readStdin() {
}
}
-void updateImages(int force) {
- for (int i = 0; i<4; i++) {
- if (images[i].new || force) {
- readImage(i);
- printf("%s\n",images[i].path);
- images[i].new = 0;
- }
- }
-}
-
-void updateUniforms(int force) {
- for (int i = 0; i<16; i++) {
- if (parameters[i].new || force) {
- uniform1f(parameters[i].name,parameters[i].value);
- parameters[i].new = 0;
- }
+void *watchShader() {
+ while (1) {
+ sleep(0.2);
+ struct stat file_stat;
+ stat(shader.fragment, &file_stat);
+ if (file_stat.st_mtime > shader.mtime) shader.new = 1;
}
}
int main(int argc, char **argv) {
createWindow();
- createShader("shader.vert","shader.frag");
+ strncpy(shader.vertex,"shader.vert",40);
+ strncpy(shader.fragment,"shader.frag",40);
+ shader.new = 1;
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
- for (int i = 0; i<4; i++) {
- strncpy(images[i].path, argv[i+1],40);
- images[i].new = 1;
+ for (int i = 1; i<argc; i++) {
+ strncpy(images[i-1].path, argv[i],40);
+ images[i-1].new = 1;
}
- uniform2f("resolution", width,height);
- pthread_t tid;
- pthread_create(&tid, NULL, readStdin, NULL);
+ pthread_t stdin_t;
+ pthread_create(&stdin_t, NULL, readStdin, NULL);
+ pthread_t frag_t;
+ pthread_create(&frag_t, NULL, watchShader, NULL);
while (!glfwWindowShouldClose(window)) {
- uniform1f("time",glfwGetTime());
+ glUniform1f(glGetUniformLocation(shader.id, "time"),glfwGetTime());
if (shader.new) {
- createShader("shader.vert",shader.path);
+ createShader();
uniform2f("resolution", width,height); // important!!
for (int i = 0; i<4; i++) { imageUniforms(i); }
- updateUniforms(1);
+ updateParams(1);
shader.new = 0;
}
updateImages(0);
- updateUniforms(0);
+ updateParams(0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glfwSwapBuffers(window);
glfwPollEvents();
}
- pthread_cancel(tid);
+ pthread_cancel(stdin_t);
+ pthread_cancel(frag_t);
glfwDestroyWindow(window);
glfwTerminate();