downscale textures for monitor

This commit is contained in:
2025-09-21 02:05:32 +02:00
parent bb9cb7dd36
commit 4c61838665
9 changed files with 92 additions and 76 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ build:
.PHONY: run .PHONY: run
run: build run: build
./build/$(TARGET) $(TEST_ARGS) --monitor-only --internal-size=240 --hot-reload ./build/$(TARGET) $(TEST_ARGS) --monitor-only --hot-reload
.PHONY: demo .PHONY: demo
demo: build demo: build
+7 -2
View File
@@ -50,7 +50,7 @@ make install
## CLI arguments ## CLI arguments
```txt ```txt
usage: forge [-h] [-v] [-hr] [-s=SCREEN] [-f=DIR_PATH] [-fc=CFG_PATH] [-t=TEMPO] [--demo] usage: forge [-h] [-v] [-hr] [-s=SCREEN] [-m=SCREEN] [-mo] [-f=DIR_PATH] [-fc=CFG_PATH] [-is=SIZE] [-mf=FACTOR] [-t=TEMPO] [--demo] [-w]
Fusion Of Real-time Generative Effects. Fusion Of Real-time Generative Effects.
@@ -59,10 +59,15 @@ options:
-v, --version print version -v, --version print version
-hr, --hot-reload hot reload of shaders scripts -hr, --hot-reload hot reload of shaders scripts
-s, --screen output screen number (default: primary) -s, --screen output screen number (default: primary)
-m, --monitor monitor screen number (default: none)
-mo, --monitor-only no output screen
-f, --frag fragment shaders directory (default: TODO) -f, --frag fragment shaders directory (default: TODO)
-fc, --frag-config fragment shaders config file (default: TODO) -fc, --frag-config fragment shaders config file (default: TODO)
-t, --tempo base tempo (default: 120) -is, --internal-size internal texture height (default: 720)
-mf, --monitor-factor monitor internal texture downscale factor (default: 3)
-t, --tempo base tempo (default: 60)
--demo demonstration mode --demo demonstration mode
-w, --windowed not fullscreen
``` ```
## Release guide ## Release guide
+11 -2
View File
@@ -11,7 +11,8 @@
#include "types.h" #include "types.h"
static void print_help(int status_code) { static void print_help(int status_code) {
puts(PACKAGE puts(
PACKAGE
" " VERSION "\n\n" " " VERSION "\n\n"
"usage: " PACKAGE " " "usage: " PACKAGE " "
"[-h] " "[-h] "
@@ -23,6 +24,7 @@ static void print_help(int status_code) {
"[-f=DIR_PATH] " "[-f=DIR_PATH] "
"[-fc=CFG_PATH] " "[-fc=CFG_PATH] "
"[-is=SIZE] " "[-is=SIZE] "
"[-mf=FACTOR] "
"[-t=TEMPO] " "[-t=TEMPO] "
"[--demo] " "[--demo] "
"[-w] " "[-w] "
@@ -36,8 +38,12 @@ static void print_help(int status_code) {
" -m, --monitor monitor screen number (default: none)\n" " -m, --monitor monitor screen number (default: none)\n"
" -mo, --monitor-only no output screen\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"
" -mf, --monitor-factor monitor internal texture downscale factor "
"(default: "
"3)\n"
" -t, --tempo base tempo (default: 60)\n" " -t, --tempo base tempo (default: 60)\n"
" --demo demonstration mode\n" " --demo demonstration mode\n"
" -w, --windowed not fullscreen\n"); " -w, --windowed not fullscreen\n");
@@ -86,6 +92,7 @@ Parameters args_parse(int argc, char **argv) {
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;
params.monitor_factor = 3;
params.base_tempo = 60.0f; params.base_tempo = 60.0f;
params.demo = false; params.demo = false;
params.windowed = false; params.windowed = false;
@@ -110,6 +117,8 @@ Parameters args_parse(int argc, char **argv) {
params.base_tempo = (float)parse_uint(arg, value); params.base_tempo = (float)parse_uint(arg, value);
} else if (is_arg(arg, "-is") || is_arg(arg, "--internal-size")) { } else if (is_arg(arg, "-is") || is_arg(arg, "--internal-size")) {
params.internal_size = parse_uint(arg, value); params.internal_size = parse_uint(arg, value);
} else if (is_arg(arg, "-mf") || is_arg(arg, "--monitor-factor")) {
params.monitor_factor = parse_uint(arg, value);
} 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);
-4
View File
@@ -9,8 +9,4 @@
#define VERSION "(dev)" #define VERSION "(dev)"
#endif /* VERSION */ #endif /* VERSION */
#ifndef SUB_COUNT
#define SUB_COUNT 16
#endif /* SUB_COUNT */
#endif /* CONFIG_H */ #endif /* CONFIG_H */
+8 -7
View File
@@ -123,8 +123,7 @@ static void hot_reload(File *common_shader_code, File *fragment_shaders) {
} }
static void loop(bool hr, File *common_shader_code, File *fragment_shaders, static void loop(bool hr, File *common_shader_code, File *fragment_shaders,
Timer *timer) { unsigned int monitor_factor, Timer *timer) {
if (hr) { if (hr) {
hot_reload(common_shader_code, fragment_shaders); hot_reload(common_shader_code, fragment_shaders);
} }
@@ -136,7 +135,7 @@ static void loop(bool hr, File *common_shader_code, File *fragment_shaders,
if (window_output != NULL) { if (window_output != NULL) {
window_use(window_output, &context); window_use(window_output, &context);
shaders_compute(program, context, false); shaders_compute(program, context, false, 1);
window_refresh(window_output); window_refresh(window_output);
} }
@@ -144,7 +143,7 @@ static void loop(bool hr, File *common_shader_code, File *fragment_shaders,
if (window_monitor != NULL) { if (window_monitor != NULL) {
window_use(window_monitor, &context); window_use(window_monitor, &context);
shaders_compute(program_monitor, context, true); shaders_compute(program_monitor, context, true, monitor_factor);
window_refresh(window_monitor); window_refresh(window_monitor);
} }
@@ -240,7 +239,7 @@ void forge_run(Parameters params) {
window_use(window_output, &context); window_use(window_output, &context);
program = shaders_init(fragment_shaders, shader_config, context); program = shaders_init(fragment_shaders, shader_config, context, 1);
} else { } else {
window_output = NULL; window_output = NULL;
} }
@@ -252,7 +251,8 @@ void forge_run(Parameters params) {
window_use(window_monitor, &context); window_use(window_monitor, &context);
program_monitor = shaders_init(fragment_shaders, shader_config, context); program_monitor = shaders_init(fragment_shaders, shader_config, context,
params.monitor_factor);
} else { } else {
window_monitor = NULL; window_monitor = NULL;
} }
@@ -276,7 +276,8 @@ void forge_run(Parameters params) {
while ((window_output == NULL || !window_should_close(window_output)) && 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(params.hot_reload, &common_shader_code, fragment_shaders, &timer); loop(params.hot_reload, &common_shader_code, fragment_shaders,
params.monitor_factor, &timer);
} }
free_files(&common_shader_code, fragment_shaders, frag_count); free_files(&common_shader_code, fragment_shaders, frag_count);
+26 -21
View File
@@ -35,7 +35,8 @@ static bool compile_shader(GLuint shader_id, char *name, char *source_code) {
return status_params == GL_TRUE; return status_params == GL_TRUE;
} }
static void init_textures(ShaderProgram *program, Context context) { static void init_textures(ShaderProgram *program, Context context,
unsigned int downscaling) {
unsigned int i; unsigned int i;
program->textures = malloc(program->tex_count * sizeof(GLuint)); program->textures = malloc(program->tex_count * sizeof(GLuint));
@@ -52,10 +53,11 @@ static void init_textures(ShaderProgram *program, Context context) {
glBindTexture(GL_TEXTURE_2D, program->textures[i]); glBindTexture(GL_TEXTURE_2D, program->textures[i]);
// define texture image as empty // define texture image as empty
glTexImage2D( glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
GL_TEXTURE_2D, 0, GL_RGB, (int)((context.internal_size / downscaling) *
(int)(context.internal_size * (float)context.width / context.height), (float)context.width / (context.height)),
context.internal_size, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); context.internal_size / downscaling, 0, GL_RGB,
GL_UNSIGNED_BYTE, 0);
// setup mipmap context // setup mipmap context
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -248,7 +250,7 @@ static void init_programs(ShaderProgram *program, ConfigFile shader_config) {
} }
ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config, ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config,
Context context) { Context context, unsigned int downscaling) {
ShaderProgram program; ShaderProgram program;
program.error = false; program.error = false;
@@ -265,7 +267,7 @@ ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config,
program.sub_variant_count = program.sub_variant_count =
config_file_get_int(shader_config, "SUB_VARIANT_COUNT", 1); config_file_get_int(shader_config, "SUB_VARIANT_COUNT", 1);
init_textures(&program, context); init_textures(&program, context, downscaling);
init_framebuffers(&program, shader_config); init_framebuffers(&program, shader_config);
@@ -296,7 +298,8 @@ void shaders_update(ShaderProgram program, File *fragment_shaders,
} }
} }
static void update_viewport(ShaderProgram program, Context context) { static void update_viewport(ShaderProgram program, Context context,
unsigned int downscaling) {
unsigned int i; unsigned int i;
// viewport changed // viewport changed
@@ -305,16 +308,17 @@ static void update_viewport(ShaderProgram program, Context context) {
// clean and resize all textures // clean and resize all textures
for (i = 0; i < program.tex_count; i++) { for (i = 0; i < program.tex_count; i++) {
glActiveTexture(GL_TEXTURE0 + i); glActiveTexture(GL_TEXTURE0 + i);
glTexImage2D( glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
GL_TEXTURE_2D, 0, GL_RGB, (int)((context.internal_size / downscaling) *
(int)(context.internal_size * (float)context.width / context.height), (float)context.width / (context.height)),
context.internal_size, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); (int)(float)context.internal_size / downscaling, 0, GL_RGB,
GL_UNSIGNED_BYTE, 0);
} }
} }
} }
static void use_program(ShaderProgram program, int i, bool output, static void use_program(ShaderProgram program, int i, bool output,
Context context) { Context context, unsigned int downscaling) {
unsigned int j, k; unsigned int j, k;
GLuint *subroutines; GLuint *subroutines;
vec2 resolution; vec2 resolution;
@@ -335,10 +339,10 @@ static void use_program(ShaderProgram program, int i, bool output,
// clear buffer // clear buffer
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} else { } else {
glViewport( glViewport(0, 0,
0, 0, (int)((context.internal_size / downscaling) *
(int)(context.internal_size * (float)context.width / context.height), (float)context.width / (context.height)),
context.internal_size); (int)(float)context.internal_size / downscaling);
// use memory framebuffer // use memory framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, program.frame_buffers[i]); glBindFramebuffer(GL_FRAMEBUFFER, program.frame_buffers[i]);
@@ -384,18 +388,19 @@ static void use_program(ShaderProgram program, int i, bool output,
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
} }
void shaders_compute(ShaderProgram program, Context context, bool monitor) { void shaders_compute(ShaderProgram program, Context context, bool monitor,
unsigned int downscaling) {
unsigned int i; unsigned int i;
update_viewport(program, context); update_viewport(program, context, downscaling);
for (i = 0; i < program.frag_count; i++) { for (i = 0; i < program.frag_count; i++) {
if (i != program.frag_output_index && i != program.frag_monitor_index) { if (i != program.frag_output_index && i != program.frag_monitor_index) {
use_program(program, i, false, context); use_program(program, i, false, context, downscaling);
} }
} }
use_program(program, use_program(program,
monitor ? program.frag_monitor_index : program.frag_output_index, monitor ? program.frag_monitor_index : program.frag_output_index,
true, context); true, context, downscaling);
} }
+3 -2
View File
@@ -4,11 +4,12 @@
#define SHADERS_H #define SHADERS_H
ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config, ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config,
Context context); Context context, unsigned int downscaling);
void shaders_update(ShaderProgram program, File *fragment_shaders, void shaders_update(ShaderProgram program, File *fragment_shaders,
unsigned int i); unsigned int i);
void shaders_compute(ShaderProgram program, Context context, bool monitor); void shaders_compute(ShaderProgram program, Context context, bool monitor,
unsigned int downscaling);
#endif /* SHADERS_H */ #endif /* SHADERS_H */
+1
View File
@@ -18,6 +18,7 @@ typedef struct Parameters {
char *frag_path; char *frag_path;
char *frag_config_path; char *frag_config_path;
unsigned int internal_size; unsigned int internal_size;
unsigned int monitor_factor;
float base_tempo; float base_tempo;
bool demo; bool demo;
bool windowed; bool windowed;
-2
View File
@@ -89,8 +89,6 @@ static void use_window(GLFWwindow *window) {
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
// link GLAD and GLFW window // link GLAD and GLFW window
gladLoadGL(glfwGetProcAddress); gladLoadGL(glfwGetProcAddress);
// vsync
glfwSwapInterval(1);
} }
void window_startup(void (*error_callback)(int, const char *)) { void window_startup(void (*error_callback)(int, const char *)) {