diff --git a/README.md b/README.md index 0df239c..443903a 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ make -f Makefile.dev release-arch - [x] Select screen as argument / config - [x] fps in window title - [x] Clean code -- [ ] Multi-stage shaders +- [x] Multi-stage shaders - [x] Test 2 stages with render to texture - [x] 2 in 2 fx 1 mix 1 fx layout - [x] Include common code @@ -117,8 +117,8 @@ make -f Makefile.dev release-arch - [x] internal texture size for speed - [x] pass state as uniform - [x] debug shader (and in monitor) - - [ ] random mode / demo mode with R/D key - - [ ] Clean code and fix things + - [x] random mode / demo mode with R/D key + - [x] Clean code and fix things - [ ] Midi - [ ] Read Midi events - [ ] Read midi mapping config file diff --git a/shaders/frag0.glsl b/shaders/frag0.glsl index c6fe1d3..731cfd5 100644 --- a/shaders/frag0.glsl +++ b/shaders/frag0.glsl @@ -1257,7 +1257,7 @@ subroutine(src_stage_sub) vec4 src_16(vec2 vUV, int seed) {0x54, 0x45, 0x4D, 0x50, 0x4F}, // TEMPO {0x54, 0x49, 0x4D, 0x45, 0x00}, // TIME {0x44, 0x45, 0x4D, 0x4F, 0x00}, // DEMO - {0x4E, 0x49, 0x56, 0x45, 0x00}, // LIVE + {0x4C, 0x49, 0x56, 0x45, 0x00}, // LIVE }; vec2 uv2 = uv1; diff --git a/shaders/frag8.glsl b/shaders/frag8.glsl index 6a60789..0a4307c 100644 --- a/shaders/frag8.glsl +++ b/shaders/frag8.glsl @@ -40,16 +40,25 @@ void main() { c += s(uv2,1,0) * texture(tex5, uv2); c += s(uv2,2,0) * texture(tex6, uv2); + float f = 0; float t = 0; + f += rect(uv3, vec2(-51, 28.5), vec2(2.1, 0.7)); t += write_5(uv3, vec2(-53,28), texts[0]); + f += rect(uv3, vec2(-51, -11.5), vec2(2.1, 0.7)); t += write_5(uv3, vec2(-53,-12), texts[1]); + f += rect(uv3, vec2(-14.5, 28.5), vec2(2.6, 0.7)); t += write_5(uv3, vec2(-17,28), texts[2]); + f += rect(uv3, vec2(-14.5, -11.5), vec2(2.6, 0.7)); t += write_5(uv3, vec2(-17,-12), texts[3]); + f += rect(uv3, vec2(21, 28.5), vec2(2.1, 0.7)); t += write_5(uv3, vec2(19,28), texts[4]); + f += rect(uv3, vec2(21, -11.5), vec2(2.1, 0.7)); t += write_5(uv3, vec2(19,-12), texts[5]); + f += rect(uv3, vec2(-15.5, 8.5), vec2(1.6, 0.7)); t += write_5(uv3, vec2(-17,8), texts[6]); + f += rect(uv3, vec2(20.5, 8.5), vec2(1.6, 0.7)); t += write_5(uv3, vec2(19,8), texts[7]); - fragColor = mix(c, 1 - c, t); + fragColor = mix(c, vec4(f - t), f); } \ No newline at end of file diff --git a/src/forge.c b/src/forge.c index 5bfa2e4..0ba1b1d 100644 --- a/src/forge.c +++ b/src/forge.c @@ -14,20 +14,8 @@ #include "types.h" #include "window.h" -static void error_callback(int error, const char *description) { - log_error("[GLFW] %d: %s", error, description); - window_close(0, true); - exit(EXIT_FAILURE); -} - -static void key_callback(Window *window, int key, - __attribute__((unused)) int scancode, int action, - __attribute__((unused)) int mods) { - // close window on escape key - if (window_escape_key(key, action)) { - window_close(window, false); - } -} +static Context context; +static ShaderProgram program; static unsigned int compute_fps(Window *window, Timer *timer) { static double fps; @@ -42,37 +30,45 @@ static unsigned int compute_fps(Window *window, Timer *timer) { return (unsigned int)round(fps); } -static void init_context(ShaderProgram program, Context *context, - Parameters params) { +static void randomize_context_state() { + unsigned int i; + + for (i = 0; i < program.frag_count * program.sub_type_count; i++) { + context.sub_state[i] = rand_uint(program.sub_variant_count); + } +} +static void init_context(Parameters params) { int size; int i; - context->tempo = params.base_tempo; - context->demo = params.demo; - context->monitor = params.monitor; + context.tempo = params.base_tempo; + context.demo = params.demo; + context.monitor = params.monitor; size = program.frag_count * program.sub_type_count; - context->sub_state = malloc(size * sizeof(unsigned int)); + context.sub_state = malloc(size * sizeof(unsigned int)); for (i = 0; i < size; i++) { - context->sub_state[i] = - params.demo ? rand_uint(program.sub_variant_count) : 0; + context.sub_state[i] = 0; } - context->seeds = malloc(program.frag_count * sizeof(unsigned int)); + if (params.demo) { + randomize_context_state(); + } + + context.seeds = malloc(program.frag_count * sizeof(unsigned int)); for (i = 0; i < (int)program.frag_count; i++) { - context->seeds[i] = rand_uint(1000); + context.seeds[i] = rand_uint(1000); } } -static void free_context(Context context) { +static void free_context() { free(context.sub_state); free(context.seeds); } -static void hot_reload(ShaderProgram program, File *common_shader_code, - File *fragment_shaders) { +static void hot_reload(File *common_shader_code, File *fragment_shaders) { unsigned int i; bool force_update; @@ -92,19 +88,18 @@ static void hot_reload(ShaderProgram program, File *common_shader_code, } } -static void loop(Window *window, ShaderProgram program, bool hr, - File *common_shader_code, File *fragment_shaders, Timer *timer, - Context *context) { +static void loop(Window *window, bool hr, File *common_shader_code, + File *fragment_shaders, Timer *timer) { if (hr) { - hot_reload(program, common_shader_code, fragment_shaders); + hot_reload(common_shader_code, fragment_shaders); } - window_get_context(window, context); + window_get_context(window, &context); - context->fps = compute_fps(window, timer); + context.fps = compute_fps(window, timer); - shaders_apply(program, *context); + shaders_apply(program, context); window_refresh(window); } @@ -150,14 +145,34 @@ static void free_files(File *common_shader_code, File *fragment_shaders, file_free(common_shader_code, true); } +static void error_callback(int error, const char *description) { + log_error("[GLFW] %d: %s", error, description); + window_close(0, true); + exit(EXIT_FAILURE); +} + +static void key_callback(Window *window, int key, + __attribute__((unused)) int scancode, int action, + __attribute__((unused)) int mods) { + if (window_escape_key(key, action)) { + // close window on escape key + window_close(window, false); + } else if (window_char_key(key, action, 82)) { + // R: randomize + log_debug("R"); + randomize_context_state(); + } else if (window_char_key(key, action, 68)) { + // D: demo on/off + context.demo = !context.demo; + } +} + void forge_run(Parameters params) { unsigned int frag_count; File *fragment_shaders; File common_shader_code; - ShaderProgram program; Window *window; Timer timer; - Context context; ConfigFile shader_config; shader_config = config_file_read(params.frag_config_path, false); @@ -178,7 +193,7 @@ void forge_run(Parameters params) { program = shaders_init(fragment_shaders, shader_config, context); - init_context(program, &context, params); + init_context(params); if (program.error) { window_close(window, true); @@ -190,8 +205,8 @@ void forge_run(Parameters params) { log_success("Initialized"); while (!window_should_close(window)) { - loop(window, program, params.hot_reload, &common_shader_code, - fragment_shaders, &timer, &context); + loop(window, params.hot_reload, &common_shader_code, fragment_shaders, + &timer); } free_files(&common_shader_code, fragment_shaders, frag_count); @@ -200,5 +215,5 @@ void forge_run(Parameters params) { window_close(window, true); - free_context(context); + free_context(); } \ No newline at end of file diff --git a/src/window.c b/src/window.c index 74c6a0e..a5789a1 100644 --- a/src/window.c +++ b/src/window.c @@ -143,4 +143,8 @@ bool window_should_close(Window *window) { bool window_escape_key(int key, int action) { return key == GLFW_KEY_ESCAPE && action == GLFW_PRESS; +} + +bool window_char_key(int key, int action, const int char_code) { + return key == char_code && action == GLFW_PRESS; } \ No newline at end of file diff --git a/src/window.h b/src/window.h index 6c9f185..4ccc139 100644 --- a/src/window.h +++ b/src/window.h @@ -19,4 +19,6 @@ bool window_should_close(Window *window); bool window_escape_key(int key, int action); +bool window_char_key(int key, int action, const int char_code); + #endif /* WINDOW_H */ \ No newline at end of file