working monitor and output

This commit is contained in:
2025-09-21 01:30:19 +02:00
parent ba2ccd3611
commit e59547538f
7 changed files with 98 additions and 64 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ build:
.PHONY: run .PHONY: run
run: build run: build
./build/$(TARGET) $(TEST_ARGS) --hot-reload ./build/$(TARGET) $(TEST_ARGS) --monitor-only --hot-reload
.PHONY: demo .PHONY: demo
demo: build demo: build
+3 -3
View File
@@ -131,9 +131,9 @@ make -f Makefile.dev release-arch
- [ ] Fixed camera video - [ ] Fixed camera video
- [ ] Video mapping config file - [ ] Video mapping config file
- [ ] Clean code and fix things - [ ] Clean code and fix things
- [ ] Monitor screen - [x] Monitor screen
- [ ] 2nd window - [x] 2nd window
- [x] Use buffers as panels (INA A FXA / DEBUG A+B FXA+B / INB B FXB) - [x] Use buffers as panels (INA A FXA / DEBUG A+B FXA+B / INB B FXB)
- [ ] Clean code and fix things - [x] Clean code and fix things
- [ ] Packaging & install - [ ] Packaging & install
- [ ] Clone "shaders" and config in system path at setup - [ ] Clone "shaders" and config in system path at setup
+11 -5
View File
@@ -19,6 +19,7 @@ static void print_help(int status_code) {
"[-hr] " "[-hr] "
"[-s=SCREEN] " "[-s=SCREEN] "
"[-m=SCREEN] " "[-m=SCREEN] "
"[-mo] "
"[-f=DIR_PATH] " "[-f=DIR_PATH] "
"[-fc=CFG_PATH] " "[-fc=CFG_PATH] "
"[-is=SIZE] " "[-is=SIZE] "
@@ -33,6 +34,7 @@ static void print_help(int status_code) {
" -hr, --hot-reload hot reload of shaders scripts\n" " -hr, --hot-reload hot reload of shaders scripts\n"
" -s, --screen output screen number (default: primary)\n" " -s, --screen output screen number (default: primary)\n"
" -m, --monitor monitor screen number (default: none)\n" " -m, --monitor monitor screen number (default: none)\n"
" -mo, --monitor-only no output screen\n"
" -f, --frag fragment shaders directory (default: TODO)\n" " -f, --frag fragment shaders directory (default: TODO)\n"
" -fc, --frag-config fragment shaders config file (default: TODO)\n" " -fc, --frag-config fragment shaders config file (default: TODO)\n"
" -is, --internal-size internal texture height (default: 720)\n" " -is, --internal-size internal texture height (default: 720)\n"
@@ -77,9 +79,10 @@ Parameters args_parse(int argc, char **argv) {
char *value; char *value;
params.hot_reload = false; params.hot_reload = false;
params.screen = 0; params.output = true;
params.monitor_screen = 0; params.output_screen = 0;
params.monitor = false; params.monitor = false;
params.monitor_screen = 0;
params.frag_path = 0; params.frag_path = 0;
params.frag_config_path = 0; params.frag_config_path = 0;
params.internal_size = 720; params.internal_size = 720;
@@ -98,7 +101,7 @@ Parameters args_parse(int argc, char **argv) {
} else if (is_arg(arg, "-hr") || is_arg(arg, "--hot-reload")) { } else if (is_arg(arg, "-hr") || is_arg(arg, "--hot-reload")) {
params.hot_reload = true; params.hot_reload = true;
} else if (is_arg(arg, "-s") || is_arg(arg, "--screen")) { } else if (is_arg(arg, "-s") || is_arg(arg, "--screen")) {
params.screen = parse_uint(arg, value); params.output_screen = parse_uint(arg, value);
} else if (is_arg(arg, "-f") || is_arg(arg, "--frag")) { } else if (is_arg(arg, "-f") || is_arg(arg, "--frag")) {
params.frag_path = value; params.frag_path = value;
} else if (is_arg(arg, "-fc") || is_arg(arg, "--frag-config")) { } else if (is_arg(arg, "-fc") || is_arg(arg, "--frag-config")) {
@@ -110,6 +113,9 @@ Parameters args_parse(int argc, char **argv) {
} else if (is_arg(arg, "-m") || is_arg(arg, "--monitor")) { } else if (is_arg(arg, "-m") || is_arg(arg, "--monitor")) {
params.monitor = true; params.monitor = true;
params.monitor_screen = parse_uint(arg, value); params.monitor_screen = parse_uint(arg, value);
} else if (is_arg(arg, "-mo") || is_arg(arg, "--monitor-only")) {
params.output = false;
params.monitor = true;
} else if (is_arg(arg, "--demo")) { } else if (is_arg(arg, "--demo")) {
params.demo = true; params.demo = true;
} else if (is_arg(arg, "-w") || is_arg(arg, "--windowed")) { } else if (is_arg(arg, "-w") || is_arg(arg, "--windowed")) {
@@ -124,8 +130,8 @@ Parameters args_parse(int argc, char **argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (params.monitor && params.monitor_screen == params.screen && if (params.monitor && params.output &&
!params.windowed) { params.monitor_screen == params.output_screen && !params.windowed) {
log_error("monitor screen cannot be the same as output screen"); log_error("monitor screen cannot be the same as output screen");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
+68 -36
View File
@@ -17,16 +17,20 @@
static Context context; static Context context;
static ShaderProgram program; static ShaderProgram program;
static ShaderProgram program_monitor; static ShaderProgram program_monitor;
static Window *window_output;
static Window *window_monitor;
static unsigned int compute_fps(Window *window_out, Window *window_monitor, static unsigned int compute_fps(Timer *timer) {
Timer *timer) {
static double fps; static double fps;
char title[100]; char title[100];
if (timer_inc(timer)) { if (timer_inc(timer)) {
fps = timer_reset(timer); fps = timer_reset(timer);
if (window_output != NULL) {
sprintf(title, PACKAGE " " VERSION " - %.0ffps", fps); sprintf(title, PACKAGE " " VERSION " - %.0ffps", fps);
window_update_title(window_out, title); window_update_title(window_output, title);
}
if (window_monitor != NULL) { if (window_monitor != NULL) {
sprintf(title, PACKAGE " " VERSION " (monitor) - %.0ffps", fps); sprintf(title, PACKAGE " " VERSION " (monitor) - %.0ffps", fps);
@@ -39,21 +43,31 @@ static unsigned int compute_fps(Window *window_out, Window *window_monitor,
static void randomize_context_state() { static void randomize_context_state() {
unsigned int i; unsigned int i;
unsigned int size;
unsigned int variants;
for (i = 0; i < program.frag_count * program.sub_type_count; i++) { size = window_output != NULL
context.sub_state[i] = rand_uint(program.sub_variant_count); ? program.frag_count * program.sub_type_count
: program_monitor.frag_count * program_monitor.sub_type_count;
variants = window_output != NULL ? program.sub_variant_count
: program_monitor.sub_variant_count;
for (i = 0; i < size; i++) {
context.sub_state[i] = rand_uint(variants);
} }
} }
static void init_context(Parameters params) { static void init_context(Parameters params) {
unsigned int size;
int size; unsigned int i;
int i;
context.tempo = params.base_tempo; context.tempo = params.base_tempo;
context.demo = params.demo; context.demo = params.demo;
context.monitor = params.monitor; context.monitor = params.monitor;
size = program.frag_count * program.sub_type_count; size = window_output != NULL
? program.frag_count * program.sub_type_count
: program_monitor.frag_count * program_monitor.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++) { for (i = 0; i < size; i++) {
@@ -64,8 +78,10 @@ static void init_context(Parameters params) {
randomize_context_state(); randomize_context_state();
} }
context.seeds = malloc(program.frag_count * sizeof(unsigned int)); size =
for (i = 0; i < (int)program.frag_count; i++) { window_output != NULL ? program.frag_count : program_monitor.frag_count;
context.seeds = malloc(size * sizeof(unsigned int));
for (i = 0; i < size; i++) {
context.seeds[i] = rand_uint(1000); context.seeds[i] = rand_uint(1000);
} }
} }
@@ -77,46 +93,56 @@ static void free_context() {
static void hot_reload(File *common_shader_code, File *fragment_shaders) { static void hot_reload(File *common_shader_code, File *fragment_shaders) {
unsigned int i; unsigned int i;
unsigned int frag_count;
bool force_update; bool force_update;
force_update = false; force_update = false;
frag_count =
window_output != NULL ? program.frag_count : program_monitor.frag_count;
if (file_should_update(*common_shader_code)) { if (file_should_update(*common_shader_code)) {
file_update(common_shader_code); file_update(common_shader_code);
force_update = true; force_update = true;
} }
for (i = 0; i < program.frag_count; i++) { for (i = 0; i < frag_count; i++) {
if (force_update || file_should_update(fragment_shaders[i])) { if (force_update || file_should_update(fragment_shaders[i])) {
file_update(&fragment_shaders[i]); file_update(&fragment_shaders[i]);
file_prepend(&fragment_shaders[i], *common_shader_code); file_prepend(&fragment_shaders[i], *common_shader_code);
if (window_output != NULL) {
shaders_update(program, fragment_shaders, i); shaders_update(program, fragment_shaders, i);
} }
if (window_monitor != NULL) {
shaders_update(program_monitor, fragment_shaders, i);
}
}
} }
} }
static void loop(Window *window_out, Window *window_monitor, bool hr, static void loop(bool hr, File *common_shader_code, File *fragment_shaders,
File *common_shader_code, File *fragment_shaders,
Timer *timer) { Timer *timer) {
if (hr) { if (hr) {
hot_reload(common_shader_code, fragment_shaders); hot_reload(common_shader_code, fragment_shaders);
} }
context.fps = compute_fps(window_out, window_monitor, timer); context.fps = compute_fps(timer);
window_get_context(window_out, &context, true); context.time = window_get_time();
window_use(window_out); if (window_output != NULL) {
window_use(window_output, &context);
shaders_compute(program, context, false); shaders_compute(program, context, false);
window_refresh(window_out); window_refresh(window_output);
}
if (window_monitor != NULL) { if (window_monitor != NULL) {
window_get_context(window_monitor, &context, false); window_use(window_monitor, &context);
window_use(window_monitor);
shaders_compute(program_monitor, context, true); shaders_compute(program_monitor, context, true);
@@ -192,8 +218,6 @@ void forge_run(Parameters params) {
unsigned int frag_count; unsigned int frag_count;
File *fragment_shaders; File *fragment_shaders;
File common_shader_code; File common_shader_code;
Window *window_out;
Window *window_monitor;
Timer timer; Timer timer;
ConfigFile shader_config; ConfigFile shader_config;
@@ -208,21 +232,25 @@ void forge_run(Parameters params) {
window_startup(error_callback); window_startup(error_callback);
window_out = window_init(PACKAGE " " VERSION, params.screen, params.windowed,
NULL, key_callback);
window_get_context(window_out, &context, true);
context.internal_size = params.internal_size; context.internal_size = params.internal_size;
if (params.output) {
window_output = window_init(PACKAGE " " VERSION, params.output_screen,
params.windowed, NULL, key_callback);
window_use(window_output, &context);
program = shaders_init(fragment_shaders, shader_config, context); program = shaders_init(fragment_shaders, shader_config, context);
} else {
window_output = NULL;
}
if (params.monitor) { if (params.monitor) {
window_monitor = window_monitor =
window_init(PACKAGE " " VERSION " (monitor)", params.monitor_screen, window_init(PACKAGE " " VERSION " (monitor)", params.monitor_screen,
params.windowed, window_out, key_callback); params.windowed, window_output, key_callback);
window_get_context(window_monitor, &context, false); window_use(window_monitor, &context);
program_monitor = shaders_init(fragment_shaders, shader_config, context); program_monitor = shaders_init(fragment_shaders, shader_config, context);
} else { } else {
@@ -231,8 +259,11 @@ void forge_run(Parameters params) {
init_context(params); init_context(params);
if (program.error) { if ((window_output != NULL && program.error) ||
window_close(window_out, true); (window_monitor != NULL && program_monitor.error)) {
if (window_output != NULL) {
window_close(window_output, true);
}
if (window_monitor != NULL) { if (window_monitor != NULL) {
window_close(window_monitor, true); window_close(window_monitor, true);
} }
@@ -243,17 +274,18 @@ void forge_run(Parameters params) {
log_success("Initialized"); log_success("Initialized");
while (!window_should_close(window_out) && while ((window_output == NULL || !window_should_close(window_output)) &&
(window_monitor == NULL || !window_should_close(window_monitor))) { (window_monitor == NULL || !window_should_close(window_monitor))) {
loop(window_out, window_monitor, params.hot_reload, &common_shader_code, loop(params.hot_reload, &common_shader_code, fragment_shaders, &timer);
fragment_shaders, &timer);
} }
free_files(&common_shader_code, fragment_shaders, frag_count); free_files(&common_shader_code, fragment_shaders, frag_count);
config_file_free(shader_config); config_file_free(shader_config);
window_close(window_out, true); if (window_output != NULL) {
window_close(window_output, true);
}
if (window_monitor != NULL) { if (window_monitor != NULL) {
window_close(window_monitor, true); window_close(window_monitor, true);
} }
+3 -2
View File
@@ -11,9 +11,10 @@
typedef struct Parameters { typedef struct Parameters {
bool hot_reload; bool hot_reload;
unsigned char screen; bool output;
unsigned char monitor_screen; unsigned char output_screen;
bool monitor; bool monitor;
unsigned char monitor_screen;
char *frag_path; char *frag_path;
char *frag_config_path; char *frag_config_path;
unsigned int internal_size; unsigned int internal_size;
+5 -10
View File
@@ -116,11 +116,6 @@ void window_update_title(Window *window, char *title) {
glfwSetWindowTitle(window, title); glfwSetWindowTitle(window, title);
} }
void window_use(Window *window) {
glfwMakeContextCurrent(window);
gladLoadGL(glfwGetProcAddress);
}
void window_refresh(Window *window) { void window_refresh(Window *window) {
// swap front and back buffers // swap front and back buffers
glfwSwapBuffers(window); glfwSwapBuffers(window);
@@ -128,12 +123,12 @@ void window_refresh(Window *window) {
void window_events() { glfwPollEvents(); } void window_events() { glfwPollEvents(); }
void window_get_context(Window *window, Context *context, bool with_time) { double window_get_time() { return glfwGetTime(); }
glfwGetFramebufferSize(window, &context->width, &context->height);
if (with_time) { void window_use(Window *window, Context *context) {
context->time = glfwGetTime(); glfwMakeContextCurrent(window);
} gladLoadGL(glfwGetProcAddress);
glfwGetFramebufferSize(window, &context->width, &context->height);
} }
void window_close(Window *window, bool hard) { void window_close(Window *window, bool hard) {
+3 -3
View File
@@ -11,14 +11,14 @@ Window *window_init(char *title, unsigned char monitor_index, bool windowed,
void window_update_title(Window *window, char *title); void window_update_title(Window *window, char *title);
void window_use(Window *window); double window_get_time();
void window_use(Window *window, Context *context);
void window_refresh(Window *window); void window_refresh(Window *window);
void window_events(); void window_events();
void window_get_context(Window *window, Context *context, bool with_time);
void window_close(Window *window, bool hard); void window_close(Window *window, bool hard);
bool window_should_close(Window *window); bool window_should_close(Window *window);