feat: auto random
This commit is contained in:
+2
-1
@@ -98,7 +98,8 @@ make -f Makefile.dev release-arch
|
|||||||
- [x] `forge_project.cfg`
|
- [x] `forge_project.cfg`
|
||||||
- [x] Define frag prefix in config
|
- [x] Define frag prefix in config
|
||||||
- [ ] Use custom `#include xxx.glsl` preprocessor
|
- [ ] Use custom `#include xxx.glsl` preprocessor
|
||||||
- [ ] `--auto-random` / `--no-auto-random`
|
- [ ] Clean and sort args
|
||||||
|
- [x] `--auto-random` / `--no-auto-random`
|
||||||
- [ ] Update readme with usage documentation
|
- [ ] Update readme with usage documentation
|
||||||
- [x] Documentation in default config file
|
- [x] Documentation in default config file
|
||||||
- [x] Clone "shaders" and config in system path at setup
|
- [x] Clone "shaders" and config in system path at setup
|
||||||
|
|||||||
@@ -97,11 +97,12 @@ When running, the following keybindings are available:
|
|||||||
* <kbd>Esc</kbd>: Exit window
|
* <kbd>Esc</kbd>: Exit window
|
||||||
* <kbd>R</kbd>: Randomize shader state
|
* <kbd>R</kbd>: Randomize shader state
|
||||||
* <kbd>D</kbd>: Demo mode On/Off
|
* <kbd>D</kbd>: Demo mode On/Off
|
||||||
|
* <kbd>A</kbd>: Auto Random mode On/Off
|
||||||
|
|
||||||
### CLI arguments
|
### CLI arguments
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
usage: forge [-h] [-v] [-hr] [-s=SCREEN] [-m=SCREEN] [-mo] [-p=PROJECT_PATH] [-c=CFG_FILE] [-sf=STATE_PATH] [-ls / -nls] [-ss / -nss] [-is=SIZE] [-v=FILE] [-vs=SIZE] [-t=TEMPO] [-d] [-w] [-tm] [-tf]
|
usage: forge [-h] [-v] [-hr] [-s=SCREEN] [-m=SCREEN] [-mo] [-p=PROJECT_PATH] [-c=CFG_FILE] [-sf=STATE_PATH] [-ls / -nls] [-ss / -nss] [-is=SIZE] [-v=FILE] [-vs=SIZE] [-t=TEMPO] [-d] [-ar / -nar] [-w] [-tm] [-tf]
|
||||||
|
|
||||||
Fusion Of Real-time Generative Effects.
|
Fusion Of Real-time Generative Effects.
|
||||||
|
|
||||||
@@ -123,7 +124,9 @@ options:
|
|||||||
-v, --video-in path to video capture device (multiple allowed)
|
-v, --video-in path to video capture device (multiple allowed)
|
||||||
-vs, --video-size video capture desired height (default: internal texture height)
|
-vs, --video-size video capture desired height (default: internal texture height)
|
||||||
-t, --tempo base tempo (default: 60)
|
-t, --tempo base tempo (default: 60)
|
||||||
-d, --demo demonstration mode (assume --no-save-state and --no-load-state)
|
-d, --demo demonstration mode (assume --no-save-state , --no-load-state, --auto-random)
|
||||||
|
-ar, --auto-random randomize state every 4 beats
|
||||||
|
-nar, --no-auto-random do not randomize state (default)
|
||||||
-w, --windowed not fullscreen
|
-w, --windowed not fullscreen
|
||||||
-tm, --trace-midi print midi code and values
|
-tm, --trace-midi print midi code and values
|
||||||
-tf, --trace-fps print fps status of subsystems
|
-tf, --trace-fps print fps status of subsystems
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ UNIFORM_FPS=iFPS
|
|||||||
UNIFORM_IN_FPS_PREFIX=iInputFPS
|
UNIFORM_IN_FPS_PREFIX=iInputFPS
|
||||||
# 0/1 if demo
|
# 0/1 if demo
|
||||||
UNIFORM_DEMO=iDemo
|
UNIFORM_DEMO=iDemo
|
||||||
|
# 0/1 if auto random
|
||||||
|
UNIFORM_AUTORAND=iAutoRand
|
||||||
# Current page
|
# Current page
|
||||||
UNIFORM_PAGE=iPage
|
UNIFORM_PAGE=iPage
|
||||||
# Current selected shader
|
# Current selected shader
|
||||||
|
|||||||
+9
-2
@@ -17,6 +17,7 @@ uniform vec2 iInputResolution2;
|
|||||||
uniform int iInputFormat1;
|
uniform int iInputFormat1;
|
||||||
uniform int iInputFormat2;
|
uniform int iInputFormat2;
|
||||||
uniform int iDemo;
|
uniform int iDemo;
|
||||||
|
uniform int iAutoRand;
|
||||||
uniform int iPage;
|
uniform int iPage;
|
||||||
uniform int iSelected;
|
uniform int iSelected;
|
||||||
|
|
||||||
@@ -1265,12 +1266,13 @@ subroutine(src_stage_sub) vec4 src_15(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3
|
|||||||
|
|
||||||
// logic
|
// logic
|
||||||
|
|
||||||
const int texts[5][5] = {
|
const int texts[6][5] = {
|
||||||
{0x46, 0x50, 0x53, 0x00, 0x00}, // FPS
|
{0x46, 0x50, 0x53, 0x00, 0x00}, // FPS
|
||||||
{0x54, 0x45, 0x4D, 0x50, 0x4F}, // TEMPO
|
{0x54, 0x45, 0x4D, 0x50, 0x4F}, // TEMPO
|
||||||
{0x54, 0x49, 0x4D, 0x45, 0x00}, // TIME
|
{0x54, 0x49, 0x4D, 0x45, 0x00}, // TIME
|
||||||
{0x44, 0x45, 0x4D, 0x4F, 0x00}, // DEMO
|
{0x44, 0x45, 0x4D, 0x4F, 0x00}, // DEMO
|
||||||
{0x4C, 0x49, 0x56, 0x45, 0x00}, // LIVE
|
{0x4C, 0x49, 0x56, 0x45, 0x00}, // LIVE
|
||||||
|
{0x2B, 0x52, 0x41, 0x4E, 0x44}, // +RAND
|
||||||
};
|
};
|
||||||
|
|
||||||
vec2 uv2 = uv1;
|
vec2 uv2 = uv1;
|
||||||
@@ -1384,7 +1386,12 @@ subroutine(src_stage_sub) vec4 src_15(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3
|
|||||||
f += h_rect(uv3, vec2(x, 12), vec2(4, 0.5), 0.2);
|
f += h_rect(uv3, vec2(x, 12), vec2(4, 0.5), 0.2);
|
||||||
f += rect(uv3, vec2(x + 4 * v - 4, 12), vec2(4 * v, 0.4));
|
f += rect(uv3, vec2(x + 4 * v - 4, 12), vec2(4 * v, 0.4));
|
||||||
|
|
||||||
f += write_5(uv3, vec2(-2,-15), iDemo > 0 ? texts[3] : texts[4]);
|
if (iAutoRand > 0) {
|
||||||
|
f += write_5(uv3, vec2(-4,-15), iDemo > 0 ? texts[3] : texts[4]);
|
||||||
|
f += write_5(uv3, vec2(0,-15), texts[5]);
|
||||||
|
} else {
|
||||||
|
f += write_5(uv3, vec2(-2,-15), iDemo > 0 ? texts[3] : texts[4]);
|
||||||
|
}
|
||||||
|
|
||||||
return vec4(f);
|
return vec4(f);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -30,6 +30,7 @@ static void print_help(int status_code) {
|
|||||||
"[-vs=SIZE] "
|
"[-vs=SIZE] "
|
||||||
"[-t=TEMPO] "
|
"[-t=TEMPO] "
|
||||||
"[-d] "
|
"[-d] "
|
||||||
|
"[-ar / -nar] "
|
||||||
"[-w] "
|
"[-w] "
|
||||||
"[-tm] "
|
"[-tm] "
|
||||||
"[-tf] "
|
"[-tf] "
|
||||||
@@ -59,7 +60,9 @@ static void print_help(int status_code) {
|
|||||||
"internal texture height)\n"
|
"internal texture height)\n"
|
||||||
" -t, --tempo base tempo (default: 60)\n"
|
" -t, --tempo base tempo (default: 60)\n"
|
||||||
" -d, --demo demonstration mode (assume --no-save-state "
|
" -d, --demo demonstration mode (assume --no-save-state "
|
||||||
"and --no-load-state)\n"
|
", --no-load-state, --auto-random)\n"
|
||||||
|
" -ar, --auto-random randomize state every 4 beats\n"
|
||||||
|
" -nar, --no-auto-random do not randomize state (default)\n"
|
||||||
" -w, --windowed not fullscreen\n"
|
" -w, --windowed not fullscreen\n"
|
||||||
" -tm, --trace-midi print midi code and values\n"
|
" -tm, --trace-midi print midi code and values\n"
|
||||||
" -tf, --trace-fps print fps status of subsystems\n");
|
" -tf, --trace-fps print fps status of subsystems\n");
|
||||||
@@ -116,6 +119,7 @@ Parameters args_parse(int argc, char **argv) {
|
|||||||
params.video_size = 0;
|
params.video_size = 0;
|
||||||
params.base_tempo = 60.0f;
|
params.base_tempo = 60.0f;
|
||||||
params.demo = false;
|
params.demo = false;
|
||||||
|
params.auto_random = false;
|
||||||
params.windowed = false;
|
params.windowed = false;
|
||||||
params.video_in.length = 0;
|
params.video_in.length = 0;
|
||||||
params.trace_midi = false;
|
params.trace_midi = false;
|
||||||
@@ -175,6 +179,11 @@ Parameters args_parse(int argc, char **argv) {
|
|||||||
params.demo = true;
|
params.demo = true;
|
||||||
params.load_state = false;
|
params.load_state = false;
|
||||||
params.save_state = false;
|
params.save_state = false;
|
||||||
|
params.auto_random = true;
|
||||||
|
} else if (is_arg(arg, "-ar") || is_arg(arg, "--auto-random")) {
|
||||||
|
params.auto_random = true;
|
||||||
|
} else if (is_arg(arg, "-nar") || is_arg(arg, "--no-auto-random")) {
|
||||||
|
params.auto_random = false;
|
||||||
} else if (is_arg(arg, "-w") || is_arg(arg, "--windowed")) {
|
} else if (is_arg(arg, "-w") || is_arg(arg, "--windowed")) {
|
||||||
params.windowed = true;
|
params.windowed = true;
|
||||||
} else if (is_arg(arg, "-tm") || is_arg(arg, "--trace-midi")) {
|
} else if (is_arg(arg, "-tm") || is_arg(arg, "--trace-midi")) {
|
||||||
|
|||||||
+7
-2
@@ -61,8 +61,8 @@ static void compute_fps(bool trace_fps) {
|
|||||||
static void init_context(Parameters params, unsigned int in_count) {
|
static void init_context(Parameters params, unsigned int in_count) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
state_init(context, state_config, params.demo, params.base_tempo,
|
state_init(context, state_config, params.demo, params.auto_random,
|
||||||
params.state_file, params.load_state);
|
params.base_tempo, params.state_file, params.load_state);
|
||||||
|
|
||||||
context->monitor = params.monitor;
|
context->monitor = params.monitor;
|
||||||
|
|
||||||
@@ -199,6 +199,11 @@ static void key_callback(Window *window, int key,
|
|||||||
// D: demo on/off
|
// D: demo on/off
|
||||||
log_info((context->demo ? "[D] Demo OFF" : "[D] Demo ON"));
|
log_info((context->demo ? "[D] Demo OFF" : "[D] Demo ON"));
|
||||||
context->demo = !context->demo;
|
context->demo = !context->demo;
|
||||||
|
} else if (window_char_key(key, action, 65)) {
|
||||||
|
// A: auto random on/off
|
||||||
|
log_info(
|
||||||
|
(context->auto_random ? "[A] Auto Random OFF" : "[A] Auto Random ON"));
|
||||||
|
context->auto_random = !context->auto_random;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -268,6 +268,9 @@ static void init_single_program(ShaderProgram *program, unsigned int i,
|
|||||||
program->idemo_locations[i] = glGetUniformLocation(
|
program->idemo_locations[i] = glGetUniformLocation(
|
||||||
program->programs[i],
|
program->programs[i],
|
||||||
config_file_get_str(config, "UNIFORM_DEMO", "iDemo"));
|
config_file_get_str(config, "UNIFORM_DEMO", "iDemo"));
|
||||||
|
program->iautorand_locations[i] = glGetUniformLocation(
|
||||||
|
program->programs[i],
|
||||||
|
config_file_get_str(config, "UNIFORM_AUTORAND", "iAutoRand"));
|
||||||
program->ipage_locations[i] = glGetUniformLocation(
|
program->ipage_locations[i] = glGetUniformLocation(
|
||||||
program->programs[i],
|
program->programs[i],
|
||||||
config_file_get_str(config, "UNIFORM_PAGE", "iPage"));
|
config_file_get_str(config, "UNIFORM_PAGE", "iPage"));
|
||||||
@@ -515,6 +518,8 @@ static void use_program(ShaderProgram program, int i, bool output,
|
|||||||
write_uniform_1f(program.ibeats_locations[i], context->tempo_total);
|
write_uniform_1f(program.ibeats_locations[i], context->tempo_total);
|
||||||
write_uniform_1i(program.ifps_locations[i], context->fps);
|
write_uniform_1i(program.ifps_locations[i], context->fps);
|
||||||
write_uniform_1i(program.idemo_locations[i], context->demo ? 1 : 0);
|
write_uniform_1i(program.idemo_locations[i], context->demo ? 1 : 0);
|
||||||
|
write_uniform_1i(program.iautorand_locations[i],
|
||||||
|
context->auto_random ? 1 : 0);
|
||||||
write_uniform_1i(program.ipage_locations[i], context->page);
|
write_uniform_1i(program.ipage_locations[i], context->page);
|
||||||
write_uniform_1i(program.iselected_locations[i], context->selected + 1);
|
write_uniform_1i(program.iselected_locations[i], context->selected + 1);
|
||||||
write_uniform_2f(program.ires_locations[i], &context->resolution);
|
write_uniform_2f(program.ires_locations[i], &context->resolution);
|
||||||
|
|||||||
+5
-3
@@ -312,7 +312,7 @@ bool state_background_write(SharedContext *context, StateConfig state_config,
|
|||||||
|
|
||||||
change = tempo_progress(context->tempo, 4.0) < 0.25;
|
change = tempo_progress(context->tempo, 4.0) < 0.25;
|
||||||
|
|
||||||
if (context->demo && change && !last_change) {
|
if (context->auto_random && change && !last_change) {
|
||||||
state_randomize(context, state_config);
|
state_randomize(context, state_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,17 +365,19 @@ static void state_load(SharedContext *context, StateConfig state_config,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
||||||
unsigned int base_tempo, char *state_file, bool load_state) {
|
bool auto_random, unsigned int base_tempo, char *state_file,
|
||||||
|
bool load_state) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
context->tempo = tempo_init();
|
context->tempo = tempo_init();
|
||||||
tempo_set(&context->tempo, base_tempo);
|
tempo_set(&context->tempo, base_tempo);
|
||||||
context->demo = demo;
|
context->demo = demo;
|
||||||
|
context->auto_random = auto_random;
|
||||||
|
|
||||||
context->state.length = state_config.select_frag_codes.length;
|
context->state.length = state_config.select_frag_codes.length;
|
||||||
memset(context->state.values, 0, sizeof(context->state.values));
|
memset(context->state.values, 0, sizeof(context->state.values));
|
||||||
|
|
||||||
if (demo) {
|
if (auto_random) {
|
||||||
state_randomize(context, state_config);
|
state_randomize(context, state_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -13,7 +13,8 @@ bool state_background_write(SharedContext *context, StateConfig state_config,
|
|||||||
MidiDevice midi);
|
MidiDevice midi);
|
||||||
|
|
||||||
void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
||||||
unsigned int base_tempo, char *state_file, bool load_state);
|
bool auto_random, unsigned int base_tempo, char *state_file,
|
||||||
|
bool load_state);
|
||||||
|
|
||||||
void state_randomize(SharedContext *context, StateConfig state_config);
|
void state_randomize(SharedContext *context, StateConfig state_config);
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ typedef struct Parameters {
|
|||||||
unsigned int video_size;
|
unsigned int video_size;
|
||||||
float base_tempo;
|
float base_tempo;
|
||||||
bool demo;
|
bool demo;
|
||||||
|
bool auto_random;
|
||||||
bool windowed;
|
bool windowed;
|
||||||
StringArray video_in;
|
StringArray video_in;
|
||||||
bool trace_midi;
|
bool trace_midi;
|
||||||
@@ -96,6 +97,7 @@ typedef struct ShaderProgram {
|
|||||||
GLuint iinfmt_locations[ARRAY_SIZE];
|
GLuint iinfmt_locations[ARRAY_SIZE];
|
||||||
GLuint iinfps_locations[ARRAY_SIZE];
|
GLuint iinfps_locations[ARRAY_SIZE];
|
||||||
GLuint idemo_locations[ARRAY_SIZE];
|
GLuint idemo_locations[ARRAY_SIZE];
|
||||||
|
GLuint iautorand_locations[ARRAY_SIZE];
|
||||||
GLuint iseed_locations[ARRAY_SIZE];
|
GLuint iseed_locations[ARRAY_SIZE];
|
||||||
GLuint istate_locations[ARRAY_SIZE];
|
GLuint istate_locations[ARRAY_SIZE];
|
||||||
GLuint ipage_locations[ARRAY_SIZE];
|
GLuint ipage_locations[ARRAY_SIZE];
|
||||||
@@ -165,6 +167,7 @@ typedef struct SharedContext {
|
|||||||
unsigned int active[ARRAY_SIZE];
|
unsigned int active[ARRAY_SIZE];
|
||||||
vec3 values[ARRAY_SIZE];
|
vec3 values[ARRAY_SIZE];
|
||||||
bool demo;
|
bool demo;
|
||||||
|
bool auto_random;
|
||||||
unsigned int seeds[MAX_FRAG];
|
unsigned int seeds[MAX_FRAG];
|
||||||
bool monitor;
|
bool monitor;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user