diff --git a/shaders/frag0.glsl b/shaders/frag0.glsl index c289c07..3aabb93 100644 --- a/shaders/frag0.glsl +++ b/shaders/frag0.glsl @@ -725,6 +725,70 @@ float char_at(vec2 uv, vec2 pos, int code) return char(uv - pos, code) ? 1 : 0; } +float write_5(vec2 uv, vec2 pos, int str[5]) +{ + float d = 0; + int i; + + for (i = 0; i < 5; i++) { + if (str[i] == 0) { + return d; + } + + d += char_at(uv, pos + vec2(i, 0), str[i]); + } + + return d; +} + +float write_10(vec2 uv, vec2 pos, int str[10]) +{ + float d = 0; + int i; + + for (i = 0; i < 10; i++) { + if (str[i] == 0) { + return d; + } + + d += char_at(uv, pos + vec2(i, 0), str[i]); + } + + return d; +} + +float write_20(vec2 uv, vec2 pos, int str[20]) +{ + float d = 0; + int i; + + for (i = 0; i < 20; i++) { + if (str[i] == 0) { + return d; + } + + d += char_at(uv, pos + vec2(i, 0), str[i]); + } + + return d; +} + +float write_int(vec2 uv, vec2 pos, int value, int magnitude) +{ + int i; + int m = 1; + float d = 0; + for (i = 0; i < magnitude; i++) { + if (i == 0 || value >= m) { + d += char_at(uv, pos + vec2(magnitude - i - 1, 0), int(0x30 + (value % (m * 10)) / m)); + m *= 10; + } else { + break; + } + } + return d; +} + int read(sampler2D frame, vec2 uv, float k, int d, float t) { float inv_k = 1 / k; @@ -789,9 +853,70 @@ int guess_char(sampler2D frame, vec2 uv, float k, float t) // 5. generators // ------------- -// TODO +subroutine vec3 src_stage_sub(vec2 vUV); + +subroutine uniform src_stage_sub src_stage; + +subroutine(src_stage_sub) vec3 src_0(vec2 vUV) +{ + // TODO tmp + return vec3(vUV, 0.0); +} + +subroutine(src_stage_sub) vec3 src_1(vec2 vUV) +{ + // TODO tmp + vec2 uv0 = vUV.st; + float ratio = iResolution.x / iResolution.y; + vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); + vec3 color = vec3(vUV, sin(iTime * 0.5) * 0.5 + 0.5); + color *= 1 - step(cos(iTime) * 0.1 + 0.4, length(uv1)); + return color + texture(frame0, vUV - 0.01).xyz * 0.5; +} + +subroutine(src_stage_sub) vec3 src_2(vec2 vUV) +{ + const int text[5] = {0x66, 0x70, 0x73, 0x00, 0x00}; + vec2 uv0 = vUV.st; + float ratio = iResolution.x / iResolution.y; + vec2 uv1 = uv0 * vec2(ratio, 1); + vec2 uv2 = uv1 * 20; + + float v = 0; + + v += write_int(uv2, vec2(0.5, 0.5), iFPS, 3); + + v += write_5(uv2, vec2(4.0, 0.5), text); + + return vec3(v); +} // 6. effects // ---------- +subroutine vec3 fx_stage_sub(vec2 vUV, sampler2D previous, sampler2D feedback); + +subroutine uniform fx_stage_sub fx_stage; + +subroutine(fx_stage_sub) vec3 fx_0(vec2 vUV, sampler2D previous, sampler2D feedback) +{ + // TODO tmp + return texture(previous, vUV).xyz; +} + +subroutine(fx_stage_sub) vec3 fx_1(vec2 vUV, sampler2D previous, sampler2D feedback) +{ + // TODO tmp + return gauss2(previous, vUV, 0.001); +} + +subroutine(fx_stage_sub) vec3 fx_2(vec2 vUV, sampler2D previous, sampler2D feedback) +{ + // TODO tmp + return gauss3(previous, vUV, 0.001); +} + +// 7. mix +// ---------- + // TODO \ No newline at end of file diff --git a/shaders/frag1.glsl b/shaders/frag1.glsl index 96c4c03..8f5f091 100644 --- a/shaders/frag1.glsl +++ b/shaders/frag1.glsl @@ -1,16 +1,12 @@ // SRC A -// --------- -// IN: 0 / 1 -// OUT: 3 +// ----------- +// IN: 0 (MFX) +// IN: 1 (IN A) +// OUT: 3 (FX A) in vec2 vUV; layout(location = 3) out vec3 fragColor; void main() { - vec2 uv0 = vUV.st; - float ratio = iResolution.x / iResolution.y; - vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); - vec3 color = vec3(vUV, sin(iTime * 0.5) * 0.5 + 0.5); - color *= 1 - step(cos(iTime) * 0.1 + 0.4, length(uv1)); - fragColor = color + texture(frame0, vUV - 0.01).xyz * 0.5; + fragColor = src_stage(vUV); } \ No newline at end of file diff --git a/shaders/frag2.glsl b/shaders/frag2.glsl index 581abc2..31eb125 100644 --- a/shaders/frag2.glsl +++ b/shaders/frag2.glsl @@ -1,27 +1,12 @@ // SRC B -// --------- -// IN: 0 / 2 -// OUT: 4 +// ----------- +// IN: 0 (MFX) +// IN: 2 (IN B) +// OUT: 4 (FX B) in vec2 vUV; layout(location = 4) out vec3 fragColor; void main() { - vec2 uv0 = vUV.st; - float ratio = iResolution.x / iResolution.y; - vec2 uv1 = uv0 * vec2(ratio, 1); - vec2 uv2 = uv1 * 20; - - // uv2 = mod(uv2, 1); - - bool v = false; - - v = v || iFPS > 99 && char(uv2 - vec2(0.5, 0.5), 0x30 + (iFPS % 1000) / 100); - v = v || iFPS > 9 && char(uv2 - vec2(1.5, 0.5), 0x30 + (iFPS % 100) / 10); - v = v || char(uv2 - vec2(2.5, 0.5), 0x30 + (iFPS % 10)); - v = v || char(uv2 - vec2(4.0, 0.5), 0x66); - v = v || char(uv2 - vec2(5.0, 0.5), 0x70); - v = v || char(uv2 - vec2(6.0, 0.5), 0x73); - - fragColor = vec3(v ? 1 : 0); + fragColor = src_stage(vUV); } \ No newline at end of file diff --git a/shaders/frag3.glsl b/shaders/frag3.glsl index 057cb5a..08e061f 100644 --- a/shaders/frag3.glsl +++ b/shaders/frag3.glsl @@ -1,11 +1,12 @@ // FX A -// --------- -// IN: 3 / 5 -// OUT: 5 +// ------------- +// IN: 3 (SRC A) +// IN: 5 (FX A) +// OUT: 5 (A+B) in vec2 vUV; layout(location = 5) out vec3 fragColor; void main() { - fragColor = gauss2(frame3, vUV, 0.001); //texture(frame3, vUV).xyz; + fragColor = fx_stage(vUV, frame3, frame5); } \ No newline at end of file diff --git a/shaders/frag4.glsl b/shaders/frag4.glsl index c5ae4e8..3094979 100644 --- a/shaders/frag4.glsl +++ b/shaders/frag4.glsl @@ -1,11 +1,12 @@ // FX B -// --------- -// IN: 4 / 6 -// OUT: 6 +// ------------- +// IN: 4 (SRC B) +// IN: 6 (FX B) +// OUT: 6 (A+B) in vec2 vUV; layout(location = 6) out vec3 fragColor; void main() { - fragColor = texture(frame4, vUV).xyz; + fragColor = fx_stage(vUV, frame4, frame6); } \ No newline at end of file diff --git a/shaders/frag5.glsl b/shaders/frag5.glsl index e54a200..3576ce3 100644 --- a/shaders/frag5.glsl +++ b/shaders/frag5.glsl @@ -1,11 +1,13 @@ // A+B -// --------- -// IN: 5 / 6 -// OUT: 7 +// ------------ +// IN: 5 (FX A) +// IN: 6 (FX B) +// OUT: 7 (MFX) in vec2 vUV; layout(location = 7) out vec3 fragColor; void main() { + // TODO subroutine fragColor = texture(frame5, vUV).xyz + texture(frame6, vUV).xyz; } \ No newline at end of file diff --git a/shaders/frag6.glsl b/shaders/frag6.glsl index d494e80..7db7242 100644 --- a/shaders/frag6.glsl +++ b/shaders/frag6.glsl @@ -1,11 +1,12 @@ // MFX -// --------- -// IN: 7 / 0 -// OUT: 0 +// ------------ +// IN: 7 (A+B) +// IN: 0 (OUT) +// OUT: 0 (OUT) in vec2 vUV; layout(location = 0) out vec3 fragColor; void main() { - fragColor = texture(frame7, vUV).xyz; + fragColor = fx_stage(vUV, frame7, frame0); } \ No newline at end of file diff --git a/src/config.h b/src/config.h index e81abb5..67c6acb 100644 --- a/src/config.h +++ b/src/config.h @@ -17,4 +17,8 @@ #define TEX_COUNT 8 #endif +#ifndef SUB_COUNT +#define SUB_COUNT 3 // TODO 16 +#endif + #endif \ No newline at end of file diff --git a/src/shaders.c b/src/shaders.c index 592f338..3467b6d 100644 --- a/src/shaders.c +++ b/src/shaders.c @@ -117,12 +117,16 @@ void init_shaders(ShaderProgram *program, File *fragment_shaders) { program->error |= !compile_shader(program->fragment_shaders[i], fragment_shaders[i].path, fragment_shaders[i].content); + + if (program->error) { + return; + } } } void init_single_program(ShaderProgram *program, int i, bool output) { int j; - char uniform_name[32]; + char name[32]; program->programs[i] = glCreateProgram(); @@ -146,13 +150,28 @@ void init_single_program(ShaderProgram *program, int i, bool output) { glGetUniformLocation(program->programs[i], "iFPS"); program->ires_locations[i] = glGetUniformLocation(program->programs[i], "iResolution"); + + program->sub_src_locations[i] = glGetSubroutineUniformLocation( + program->programs[i], GL_FRAGMENT_SHADER, "src_stage"); + program->sub_fx_locations[i] = glGetSubroutineUniformLocation( + program->programs[i], GL_FRAGMENT_SHADER, "fx_stage"); + + for (j = 0; j < SUB_COUNT; j++) { + sprintf(name, "src_%d", j); + program->sub_src_indexes[i][j] = + glGetSubroutineIndex(program->programs[i], GL_FRAGMENT_SHADER, name); + log_debug("%s %d", name, program->sub_src_indexes[i][j]); + sprintf(name, "fx_%d", j); + program->sub_fx_indexes[i][j] = + glGetSubroutineIndex(program->programs[i], GL_FRAGMENT_SHADER, name); + } } // create frameX uniforms pointer for (j = 0; j < TEX_COUNT; j++) { - sprintf(uniform_name, "frame%d", j); + sprintf(name, "frame%d", j); program->frames_locations[i][j] = - glGetUniformLocation(program->programs[i], uniform_name); + glGetUniformLocation(program->programs[i], name); } // create attribute pointer @@ -214,6 +233,7 @@ void update_program(ShaderProgram program, File *fragment_shaders, int i) { void apply_program(ShaderProgram program, Context context) { int i, j; + GLuint subroutines[2]; // viewport changed if (context.width != program.last_width || @@ -251,6 +271,12 @@ void apply_program(ShaderProgram program, Context context) { (const GLfloat)120.0f); // TODO TMP glUniform1i(program.ifps_locations[i], (const GLint)context.fps); glUniform2fv(program.ires_locations[i], 1, (const GLfloat *)&resolution); + + // TODO tmp + subroutines[0] = program.sub_src_indexes[i][i == 0 ? 1 : 2]; + subroutines[1] = program.sub_fx_indexes[i][i == 2 ? 1 : 0]; + + glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 2, subroutines); } // set GL_TEXTURE(X) to uniform sampler2D frameX diff --git a/src/types.h b/src/types.h index 5d4da04..d0194f2 100644 --- a/src/types.h +++ b/src/types.h @@ -44,7 +44,14 @@ typedef struct ShaderProgram { GLuint itempo_locations[FRAG_COUNT]; GLuint ifps_locations[FRAG_COUNT]; GLuint ires_locations[FRAG_COUNT]; + GLuint frames_locations[FRAG_COUNT + 1][TEX_COUNT]; + + GLuint sub_src_locations[FRAG_COUNT]; + GLuint sub_src_indexes[FRAG_COUNT][SUB_COUNT]; + GLuint sub_fx_locations[FRAG_COUNT]; + GLuint sub_fx_indexes[FRAG_COUNT][SUB_COUNT]; + GLuint vpos_locations[FRAG_COUNT + 1]; GLuint vertex_buffer;