diff --git a/README.md b/README.md index 665385f..e12d60b 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ make -f Makefile.dev release-arch - [ ] 16 input + 16 fx definition and selection (with const param) - [x] Feedback texture - [ ] Shaders config file - - [ ] uniform config + - [x] uniform config - [ ] fragment output config - [ ] subroutines config - [ ] Clean code diff --git a/src/config.h b/src/config.h index dc65c9a..437c3fd 100644 --- a/src/config.h +++ b/src/config.h @@ -9,10 +9,6 @@ #define VERSION "(dev)" #endif /* VERSION */ -#ifndef FRAG_COUNT -#define FRAG_COUNT 6 -#endif /* FRAG_COUNT */ - #ifndef TEX_COUNT #define TEX_COUNT 9 #endif /* TEXT_COUNT */ diff --git a/src/config_file.c b/src/config_file.c index f0934cf..ddfb2f4 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -102,7 +102,8 @@ char *config_file_get_str(ConfigFile config, char *key, char *default_value) { return item->value; } -int config_file_get_int(ConfigFile config, char *key, int default_value) { +unsigned int config_file_get_int(ConfigFile config, char *key, + int default_value) { ConfigFileItem c_key; ConfigFileItem *item; @@ -119,7 +120,7 @@ int config_file_get_int(ConfigFile config, char *key, int default_value) { return default_value; } - return atoi(item->value); + return (unsigned int)atoi(item->value); } void config_file_free(ConfigFile config) { hashmap_free(config.map); } \ No newline at end of file diff --git a/src/config_file.h b/src/config_file.h index 7e15448..52a99b2 100644 --- a/src/config_file.h +++ b/src/config_file.h @@ -7,7 +7,8 @@ ConfigFile config_file_read(char *path, bool free_path); char *config_file_get_str(ConfigFile config, char *key, char *default_value); -int config_file_get_int(ConfigFile config, char *key, int default_value); +unsigned int config_file_get_int(ConfigFile config, char *key, + int default_value); void config_file_free(ConfigFile config); diff --git a/src/forge.c b/src/forge.c index 40e6741..ebdd089 100644 --- a/src/forge.c +++ b/src/forge.c @@ -53,7 +53,7 @@ static void hot_reload(ShaderProgram program, File *common_shader_code, force_update = true; } - for (i = 0; i < FRAG_COUNT; i++) { + for (i = 0; i < program.frag_count; i++) { if (force_update || file_should_update(fragment_shaders[i])) { file_update(&fragment_shaders[i]); file_prepend(&fragment_shaders[i], *common_shader_code); @@ -96,10 +96,10 @@ File read_fragment_shader_file(char *frag_path, unsigned int i) { } static void init_files(char *frag_path, File *common_shader_code, - File *fragment_shaders) { + File *fragment_shaders, unsigned int frag_count) { unsigned int i; - for (i = 0; i < FRAG_COUNT + 1; i++) { + for (i = 0; i < frag_count + 1; i++) { if (i == 0) { (*common_shader_code) = read_fragment_shader_file(frag_path, i); } else { @@ -110,10 +110,11 @@ static void init_files(char *frag_path, File *common_shader_code, } } -static void free_files(File *common_shader_code, File *fragment_shaders) { +static void free_files(File *common_shader_code, File *fragment_shaders, + unsigned int frag_count) { unsigned int i; - for (i = 0; i < FRAG_COUNT; i++) { + for (i = 0; i < frag_count; i++) { file_free(&fragment_shaders[i], true); } @@ -121,7 +122,8 @@ static void free_files(File *common_shader_code, File *fragment_shaders) { } void forge_run(Parameters params) { - File fragment_shaders[FRAG_COUNT]; + unsigned int frag_count; + File *fragment_shaders; File common_shader_code; ShaderProgram program; Window *window; @@ -129,10 +131,15 @@ void forge_run(Parameters params) { Context context; ConfigFile shader_config; - init_files(params.frag_path, &common_shader_code, fragment_shaders); - shader_config = config_file_read(params.frag_config_path, false); + frag_count = config_file_get_int(shader_config, "FRAG_COUNT", 6); + + fragment_shaders = malloc(frag_count * sizeof(File)); + + init_files(params.frag_path, &common_shader_code, fragment_shaders, + frag_count); + window = window_init(PACKAGE " " VERSION, params.screen, error_callback, key_callback); @@ -152,9 +159,9 @@ void forge_run(Parameters params) { fragment_shaders, &timer); } - window_close(window, true); - - free_files(&common_shader_code, fragment_shaders); + free_files(&common_shader_code, fragment_shaders, frag_count); config_file_free(shader_config); + + window_close(window, true); } \ No newline at end of file diff --git a/src/shaders.c b/src/shaders.c index dad6cfd..6b38210 100644 --- a/src/shaders.c +++ b/src/shaders.c @@ -1,8 +1,10 @@ #include #include #include +#include #include "config.h" +#include "config_file.h" #include "constants.h" #include "logs.h" #include "shaders.h" @@ -59,9 +61,11 @@ static void init_textures(ShaderProgram *program, Context context) { static void init_framebuffers(ShaderProgram *program) { unsigned int i, j; - glGenFramebuffers(FRAG_COUNT, program->frame_buffers); + program->frame_buffers = malloc(program->frag_count * sizeof(GLuint)); - for (i = 0; i < FRAG_COUNT; i++) { + glGenFramebuffers(program->frag_count, program->frame_buffers); + + for (i = 0; i < program->frag_count; i++) { glBindFramebuffer(GL_FRAMEBUFFER, program->frame_buffers[i]); for (j = 0; j < TEX_COUNT; j++) { @@ -118,8 +122,10 @@ static void init_shaders(ShaderProgram *program, File *fragment_shaders) { "internal fragment shader (monitor)", monitor_shader_text); + program->fragment_shaders = malloc(program->frag_count * sizeof(GLuint)); + // compile fragment shaders - for (i = 0; i < FRAG_COUNT; i++) { + for (i = 0; i < program->frag_count; i++) { program->fragment_shaders[i] = glCreateShader(GL_FRAGMENT_SHADER); program->error |= !compile_shader(program->fragment_shaders[i], fragment_shaders[i].path, @@ -132,7 +138,7 @@ static void init_shaders(ShaderProgram *program, File *fragment_shaders) { } static void init_single_program(ShaderProgram *program, unsigned int i, - bool output) { + ConfigFile shader_config, bool output) { unsigned int j; char name[32]; @@ -150,14 +156,19 @@ static void init_single_program(ShaderProgram *program, unsigned int i, // create uniforms pointers if (!output) { - program->itime_locations[i] = - glGetUniformLocation(program->programs[i], "iTime"); - program->itempo_locations[i] = - glGetUniformLocation(program->programs[i], "iTempo"); - program->ifps_locations[i] = - glGetUniformLocation(program->programs[i], "iFPS"); - program->ires_locations[i] = - glGetUniformLocation(program->programs[i], "iResolution"); + program->itime_locations[i] = glGetUniformLocation( + program->programs[i], + config_file_get_str(shader_config, "UNIFORM_TIME", "iTime")); + program->itempo_locations[i] = glGetUniformLocation( + program->programs[i], + config_file_get_str(shader_config, "UNIFORM_TEMPO", "iTempo")); + program->ifps_locations[i] = glGetUniformLocation( + program->programs[i], + config_file_get_str(shader_config, "UNIFORM_FPS", "iFPS")); + program->ires_locations[i] = glGetUniformLocation( + program->programs[i], + config_file_get_str(shader_config, "UNIFORM_RESOLUTION", + "iResolution")); for (j = 0; j < SUB_COUNT; j++) { sprintf(name, "src_%d", j + 1); @@ -177,7 +188,7 @@ static void init_single_program(ShaderProgram *program, unsigned int i, // create texX uniforms pointer for (j = 0; j < TEX_COUNT; j++) { sprintf(name, "tex%d", j); - program->textures_locations[i][j] = + program->textures_locations[j][i] = glGetUniformLocation(program->programs[i], name); } @@ -194,6 +205,26 @@ static void init_single_program(ShaderProgram *program, unsigned int i, log_success("Program %d initialized", i + 1); } +static void init_programs(ShaderProgram *program, ConfigFile shader_config) { + unsigned int i; + + program->programs = malloc(program->frag_count * sizeof(GLuint)); + program->itime_locations = malloc(program->frag_count * sizeof(GLuint)); + program->itempo_locations = malloc(program->frag_count * sizeof(GLuint)); + program->ifps_locations = malloc(program->frag_count * sizeof(GLuint)); + program->ires_locations = malloc(program->frag_count * sizeof(GLuint)); + program->vpos_locations = malloc(program->frag_count * sizeof(GLuint)); + + for (i = 0; i < TEX_COUNT; i++) { + program->textures_locations[i] = + malloc(program->frag_count * sizeof(GLuint)); + } + + for (i = 0; i < program->frag_count + 1; i++) { + init_single_program(program, i, shader_config, i == program->frag_count); + } +} + ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config, Context context) { unsigned int i; @@ -202,6 +233,7 @@ ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config, program.error = false; program.last_width = context.width; program.last_height = context.height; + program.frag_count = config_file_get_int(shader_config, "FRAG_COUNT", 6); init_textures(&program, context); @@ -215,11 +247,9 @@ ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config, init_vertices(&program); - // create and link full shader programs - for (i = 0; i < FRAG_COUNT + 1; i++) { - init_single_program(&program, i, i == FRAG_COUNT); - } + init_programs(&program, shader_config); + // TODO each for each frag for (i = 0; i < TEX_COUNT; i++) { program.draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i; } @@ -263,11 +293,11 @@ void shaders_apply(ShaderProgram program, Context context) { resolution[0] = (float)context.width; resolution[1] = (float)context.height; - for (i = 0; i < FRAG_COUNT + 1; i++) { + for (i = 0; i < program.frag_count + 1; i++) { // use specific shader program glUseProgram(program.programs[i]); - if (i == FRAG_COUNT) { + if (i == program.frag_count) { // use default framebuffer (output) glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -294,7 +324,7 @@ void shaders_apply(ShaderProgram program, Context context) { // set GL_TEXTURE(X) to uniform sampler2D texX for (j = 0; j < TEX_COUNT; j++) { - glUniform1i(program.textures_locations[i][j], j); + glUniform1i(program.textures_locations[j][i], j); } glDrawBuffers(TEX_COUNT - 1, program.draw_buffers); @@ -302,4 +332,4 @@ void shaders_apply(ShaderProgram program, Context context) { // draw output glDrawArrays(GL_TRIANGLES, 0, 6); } -} \ No newline at end of file +} diff --git a/src/types.h b/src/types.h index e1a1c28..962099e 100644 --- a/src/types.h +++ b/src/types.h @@ -35,31 +35,33 @@ typedef struct ShaderProgram { int last_width; int last_height; - GLuint programs[FRAG_COUNT + 1]; + unsigned int frag_count; + + GLuint *programs; GLuint vertex_shader; GLuint output_shader; GLuint monitor_shader; - GLuint fragment_shaders[FRAG_COUNT]; + GLuint *fragment_shaders; - GLuint itime_locations[FRAG_COUNT]; - GLuint itempo_locations[FRAG_COUNT]; - GLuint ifps_locations[FRAG_COUNT]; - GLuint ires_locations[FRAG_COUNT]; + GLuint *itime_locations; + GLuint *itempo_locations; + GLuint *ifps_locations; + GLuint *ires_locations; - GLuint textures_locations[FRAG_COUNT + 1][TEX_COUNT]; + GLuint *textures_locations[TEX_COUNT]; - GLuint sub_src_indexes[FRAG_COUNT][SUB_COUNT]; - GLuint sub_fx_indexes[FRAG_COUNT][SUB_COUNT]; - GLuint sub_mix_indexes[FRAG_COUNT][2]; + GLuint sub_src_indexes[6][SUB_COUNT]; // TODO change + GLuint sub_fx_indexes[6][SUB_COUNT]; + GLuint sub_mix_indexes[6][2]; - GLuint vpos_locations[FRAG_COUNT + 1]; + GLuint *vpos_locations; GLuint vertex_buffer; GLuint vertex_array; - GLuint frame_buffers[FRAG_COUNT]; + GLuint *frame_buffers; GLuint textures[TEX_COUNT]; GLenum draw_buffers[TEX_COUNT];