diff --git a/src/args.c b/src/args.c index 2801341..e2057a2 100644 --- a/src/args.c +++ b/src/args.c @@ -98,7 +98,7 @@ Parameters args_parse(int argc, char **argv) { params.base_tempo = 60.0f; params.demo = false; params.windowed = false; - params.video_in_count = 0; + params.video_in.length = 0; for (i = 1; i < argc; i++) { arg = argv[i]; @@ -122,12 +122,12 @@ Parameters args_parse(int argc, char **argv) { invalid_value(arg, value); } } else if (is_arg(arg, "-v") || is_arg(arg, "--video-in")) { - if (params.video_in_count == MAX_VIDEO) { + if (params.video_in.length == MAX_VIDEO) { log_error("maximum video input reached"); exit(EXIT_FAILURE); } - params.video_in[params.video_in_count++] = value; + params.video_in.values[params.video_in.length++] = value; } else if (is_arg(arg, "-vs") || is_arg(arg, "--video-size")) { params.video_size = parse_uint(arg, value); if (params.video_size == 0) { diff --git a/src/forge.c b/src/forge.c index c8cb8c1..834db2d 100644 --- a/src/forge.c +++ b/src/forge.c @@ -65,7 +65,8 @@ static void init_context(Parameters params, unsigned int in_count, context->demo = params.demo; context->monitor = params.monitor; - memset(context->state, 0, sizeof(context->state)); + context->state.length = frag_count; + memset(context->state.values, 0, sizeof(context->state.values)); if (params.demo) { state_randomize(context, state_config); @@ -83,15 +84,14 @@ static void init_context(Parameters params, unsigned int in_count, context->seeds[i] = rand_uint(1000); } - memset(context->input_widths, 0, sizeof(context->input_widths)); - memset(context->input_heights, 0, sizeof(context->input_heights)); + memset(context->input_resolutions, 0, sizeof(context->input_resolutions)); memset(context->input_formats, 0, sizeof(context->input_formats)); memset(context->input_fps, 0, sizeof(context->input_fps)); for (i = 0; i < in_count; i++) { if (!inputs.values[i].error) { - context->input_widths[i] = inputs.values[i].width; - context->input_heights[i] = inputs.values[i].height; + context->input_resolutions[i][0] = inputs.values[i].width; + context->input_resolutions[i][1] = inputs.values[i].height; context->input_formats[i] = inputs.values[i].pixelformat; } } @@ -161,14 +161,13 @@ static void free_files(unsigned int frag_count) { file_free(&common_shader_code, true); } -static void init_inputs(char *video_in[MAX_VIDEO], unsigned int input_count, - unsigned int video_size) { +static void init_inputs(StringArray video_in, unsigned int video_size) { unsigned int i; - inputs.length = input_count; + inputs.length = video_in.length; - for (i = 0; i < input_count; i++) { - inputs.values[i] = video_init(video_in[i], video_size); + for (i = 0; i < video_in.length; i++) { + inputs.values[i] = video_init(video_in.values[i], video_size); } } @@ -207,12 +206,15 @@ static void key_callback(Window *window, int key, __attribute__((unused)) int mods) { if (window_escape_key(key, action)) { // close window on escape key + log_info("[ESC] Closing..."); window_close(window); } else if (window_char_key(key, action, 82)) { // R: randomize + log_info("[R] Randomizing..."); state_randomize(context, state_config); } else if (window_char_key(key, action, 68)) { // D: demo on/off + log_info((context->demo ? "[D] Demo OFF" : "[D] Demo ON")); context->demo = !context->demo; } } @@ -265,11 +267,11 @@ void forge_run(Parameters params) { init_files(params.frag_path, frag_count); - init_inputs(params.video_in, params.video_in_count, params.video_size); + init_inputs(params.video_in, params.video_size); init_context(params, in_count, frag_count); - if (!start_video_captures(params.video_in_count)) { + if (!start_video_captures(params.video_in.length)) { return; } @@ -289,7 +291,7 @@ void forge_run(Parameters params) { window_startup(error_callback); - context->internal_height = params.internal_size; + context->tex_resolution[1] = params.internal_size; if (params.output) { window_output = window_init(PACKAGE " " VERSION, params.output_screen, @@ -348,7 +350,7 @@ void forge_run(Parameters params) { shaders_free_window(program, params.output); } - free_video_captures(params.video_in_count); + free_video_captures(params.video_in.length); free_context(); diff --git a/src/shaders.c b/src/shaders.c index e3283ae..258ecab 100644 --- a/src/shaders.c +++ b/src/shaders.c @@ -51,8 +51,8 @@ static void init_textures(ShaderProgram *program, SharedContext *context) { glDisable(GL_BLEND); // define texture image as empty - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, context->internal_width, - context->internal_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, context->tex_resolution[0], + context->tex_resolution[1], 0, GL_RGB, GL_UNSIGNED_BYTE, 0); // setup mipmap context glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -378,8 +378,8 @@ ShaderProgram shaders_init(FileArray fragment_shaders, ConfigFile config, if (previous == NULL) { program.error = false; - program.last_width = context->width; - program.last_height = context->height; + program.last_resolution[0] = context->resolution[0]; + program.last_resolution[1] = context->resolution[1]; program.tex_count = config_file_get_int(config, "TEX_COUNT", 9); program.frag_count = config_file_get_int(config, "FRAG_COUNT", 10); program.frag_output_index = @@ -446,13 +446,13 @@ static void update_viewport(ShaderProgram program, SharedContext *context) { unsigned int i; // viewport changed - if (context->width != program.last_width || - context->height != program.last_height) { + if (context->resolution[0] != program.last_resolution[0] || + context->resolution[1] != program.last_resolution[1]) { // clean and resize all textures for (i = 0; i < program.tex_count; i++) { glActiveTexture(GL_TEXTURE0 + i); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, context->internal_width, - context->internal_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, context->tex_resolution[0], + context->tex_resolution[1], 0, GL_RGB, GL_UNSIGNED_BYTE, 0); } } } @@ -486,19 +486,11 @@ static void use_program(ShaderProgram program, int i, bool output, SharedContext *context) { unsigned int j, k, offset; GLuint subroutines[ARRAY_SIZE]; - // TODO direct vec2 in context - vec2 resolution, tex_resolution, in_resolution; - - resolution[0] = (float)context->width; - resolution[1] = (float)context->height; - tex_resolution[0] = (float)context->internal_width; - tex_resolution[1] = (float)context->internal_height; - // use specific shader program glUseProgram(program.programs[i]); if (output) { - glViewport(0, 0, context->width, context->height); + glViewport(0, 0, context->resolution[0], context->resolution[1]); // use default framebuffer (output) glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -506,7 +498,7 @@ static void use_program(ShaderProgram program, int i, bool output, // clear buffer glClear(GL_COLOR_BUFFER_BIT); } else { - glViewport(0, 0, context->internal_width, context->internal_height); + glViewport(0, 0, context->tex_resolution[0], context->tex_resolution[1]); // use memory framebuffer glBindFramebuffer(GL_FRAMEBUFFER, program.frame_buffers[i]); @@ -519,8 +511,8 @@ static void use_program(ShaderProgram program, int i, bool output, write_uniform_1i(program.idemo_locations[i], context->demo ? 1 : 0); write_uniform_1i(program.ipage_locations[i], context->page); write_uniform_1i(program.iselected_locations[i], context->selected + 1); - write_uniform_2f(program.ires_locations[i], &resolution); - write_uniform_2f(program.itexres_locations[i], &tex_resolution); + write_uniform_2f(program.ires_locations[i], &context->resolution); + write_uniform_2f(program.itexres_locations[i], &context->tex_resolution); for (j = 0; j < program.active_count; j++) { write_uniform_1i(program.iactive_locations[i * program.active_count + j], @@ -528,11 +520,8 @@ static void use_program(ShaderProgram program, int i, bool output, } for (j = 0; j < program.in_count; j++) { - in_resolution[0] = context->input_widths[j]; - in_resolution[1] = context->input_heights[j]; - write_uniform_2f(program.iinres_locations[i * program.in_count + j], - &in_resolution); + &context->input_resolutions[j]); write_uniform_1i(program.iinfmt_locations[i * program.in_count + j], context->input_formats[j]); write_uniform_1i(program.iinfps_locations[i * program.in_count + j], @@ -547,7 +536,7 @@ static void use_program(ShaderProgram program, int i, bool output, for (j = 0; j < program.frag_count; j++) { write_uniform_1i(program.istate_locations[i * program.frag_count + j], - context->state[j]); + context->state.values[j]); } offset = 0; @@ -559,7 +548,7 @@ static void use_program(ShaderProgram program, int i, bool output, } // set subroutines for fragment and update state uniforms - k = context->state[i]; + k = context->state.values[i]; for (j = 0; j < program.sub_type_count; j++) { subroutines[j] = program.sub_locations[i * program.sub_type_count * program.sub_variant_count + diff --git a/src/state.c b/src/state.c index e4c816f..6a2e1d3 100644 --- a/src/state.c +++ b/src/state.c @@ -10,8 +10,7 @@ #include "types.h" StateConfig state_parse_config(ConfigFile config) { - unsigned int i, j, offset, total; - // TODO rename total var + unsigned int i, j, offset, count; StateConfig state_config; char name[256]; @@ -51,16 +50,16 @@ StateConfig state_parse_config(ConfigFile config) { state_config.values_offsets.length = config_file_get_int(config, "MIDI_COUNT", 0); - total = 0; + count = 0; for (i = 0; i < state_config.midi_active_counts.length; i++) { sprintf(name, "MIDI_%d_ACTIVE_COUNT", i + 1); state_config.midi_active_counts.values[i] = config_file_get_int(config, name, 1); - state_config.midi_active_offsets.values[i] = total; - total += state_config.midi_active_counts.values[i]; + state_config.midi_active_offsets.values[i] = count; + count += state_config.midi_active_counts.values[i]; } - state_config.midi_active_codes.length = total; + state_config.midi_active_codes.length = count; for (i = 0; i < state_config.midi_active_counts.length; i++) { for (j = 0; j < state_config.midi_active_counts.values[i]; j++) { @@ -71,19 +70,19 @@ StateConfig state_parse_config(ConfigFile config) { } } - total = 0; + count = 0; offset = 0; for (i = 0; i < state_config.midi_counts.length; i++) { sprintf(name, "MIDI_%d_COUNT", i + 1); state_config.midi_counts.values[i] = config_file_get_int(config, name, 0); - state_config.midi_offsets.values[i] = total; + state_config.midi_offsets.values[i] = count; state_config.values_offsets.values[i] = offset; offset += state_config.midi_counts.values[i] * state_config.midi_active_counts.values[i]; - total += state_config.midi_counts.values[i]; + count += state_config.midi_counts.values[i]; } - state_config.midi_codes.length = total * 3; + state_config.midi_codes.length = count * 3; for (i = 0; i < state_config.midi_counts.length; i++) { offset = state_config.midi_offsets.values[i]; @@ -137,11 +136,12 @@ static void update_page(SharedContext *context, StateConfig state_config, page_item_min = state_config.select_item_codes.length * context->page; page_item_max = page_item_min + state_config.select_item_codes.length; - if (context->state[context->selected] >= page_item_min && - context->state[context->selected] < page_item_max) { + if (context->state.values[context->selected] >= page_item_min && + context->state.values[context->selected] < page_item_max) { for (i = 0; i < state_config.select_item_codes.length; i++) { safe_midi_write(midi, state_config.select_item_codes.values[i], - i == context->state[context->selected] - page_item_min + i == context->state.values[context->selected] - + page_item_min ? MIDI_MAX : 0); } @@ -212,7 +212,7 @@ void state_apply_event(SharedContext *context, StateConfig state_config, if (i != ARRAY_NOT_FOUND) { found = true; if (value > 0) { - context->state[context->selected] = + context->state.values[context->selected] = context->page * state_config.select_item_codes.length + i; update_page(context, state_config, midi); } @@ -320,7 +320,7 @@ bool state_background_midi_write(SharedContext *context, void state_randomize(SharedContext *context, StateConfig state_config) { unsigned int i; - for (i = 0; i < state_config.select_frag_codes.length; i++) { - context->state[i] = rand_uint(state_config.state_max); + for (i = 0; i < context->state.length; i++) { + context->state.values[i] = rand_uint(state_config.state_max); } } \ No newline at end of file diff --git a/src/types.h b/src/types.h index ef7da5b..7f75777 100644 --- a/src/types.h +++ b/src/types.h @@ -38,9 +38,7 @@ typedef struct Parameters { float base_tempo; bool demo; bool windowed; - // TODO use array - char *video_in[MAX_VIDEO]; - unsigned int video_in_count; + StringArray video_in; } Parameters; typedef struct Vertex { @@ -59,8 +57,7 @@ typedef ARRAY(FileArray, File); typedef struct ShaderProgram { bool error; - int last_width; - int last_height; + vec2 last_resolution; GLuint vertex_shader; @@ -143,16 +140,14 @@ typedef struct Tempo { typedef struct SharedContext { int fd; - // TODO use arrays - int width; - int height; - unsigned int internal_width; - unsigned int internal_height; + vec2 resolution; + vec2 tex_resolution; + vec2 input_resolutions[MAX_VIDEO]; + double time; unsigned int fps; Tempo tempo; - // TODO use array - unsigned int state[MAX_FRAG]; + UintArray state; unsigned int page; unsigned int selected; unsigned int active[ARRAY_SIZE]; @@ -160,8 +155,7 @@ typedef struct SharedContext { bool demo; unsigned int seeds[MAX_FRAG]; bool monitor; - unsigned int input_widths[MAX_VIDEO]; - unsigned int input_heights[MAX_VIDEO]; + unsigned int input_formats[MAX_VIDEO]; unsigned int input_fps[MAX_VIDEO]; bool stop; diff --git a/src/window.c b/src/window.c index 8e8ab97..a001bce 100644 --- a/src/window.c +++ b/src/window.c @@ -120,10 +120,19 @@ void window_events() { glfwPollEvents(); } double window_get_time() { return glfwGetTime(); } void window_use(Window *window, SharedContext *context) { + int width, height; + glfwMakeContextCurrent(window); - glfwGetFramebufferSize(window, &context->width, &context->height); - context->internal_width = (int)(context->internal_height * - (float)context->width / (context->height)); + glfwGetFramebufferSize(window, &width, &height); + context->resolution[0] = width; + context->resolution[1] = height; + context->tex_resolution[0] = + (int)(context->tex_resolution[1] * context->resolution[0] / + context->resolution[1]); + + log_debug("Resolution %f %f", context->resolution[0], context->resolution[1]); + log_debug("Tex resolution %f %f", context->tex_resolution[0], + context->tex_resolution[1]); } void window_close(Window *window) {