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
run: build
./build/$(TARGET) $(TEST_ARGS) --monitor-only --internal-size=240 --hot-reload
./build/$(TARGET) $(TEST_ARGS) --monitor-only --hot-reload
.PHONY: demo
demo: build
+14 -9
View File
@@ -50,19 +50,24 @@ make install
## CLI arguments
```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.
options:
-h, --help show this help message and exit
-v, --version print version
-hr, --hot-reload hot reload of shaders scripts
-s, --screen output screen number (default: primary)
-f, --frag fragment shaders directory (default: TODO)
-fc, --frag-config fragment shaders config file (default: TODO)
-t, --tempo base tempo (default: 120)
--demo demonstration mode
-h, --help show this help message and exit
-v, --version print version
-hr, --hot-reload hot reload of shaders scripts
-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)
-fc, --frag-config fragment shaders config file (default: TODO)
-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
-w, --windowed not fullscreen
```
## Release guide
+39 -30
View File
@@ -11,36 +11,42 @@
#include "types.h"
static void print_help(int status_code) {
puts(PACKAGE
" " VERSION "\n\n"
"usage: " PACKAGE " "
"[-h] "
"[-v] "
"[-hr] "
"[-s=SCREEN] "
"[-m=SCREEN] "
"[-mo] "
"[-f=DIR_PATH] "
"[-fc=CFG_PATH] "
"[-is=SIZE] "
"[-t=TEMPO] "
"[--demo] "
"[-w] "
"\n\n"
"Fusion Of Real-time Generative Effects.\n\n"
"options:\n"
" -h, --help show this help message and exit\n"
" -v, --version print version\n"
" -hr, --hot-reload hot reload of shaders scripts\n"
" -s, --screen output screen number (default: primary)\n"
" -m, --monitor monitor screen number (default: none)\n"
" -mo, --monitor-only no output screen\n"
" -f, --frag fragment shaders directory (default: TODO)\n"
" -fc, --frag-config fragment shaders config file (default: TODO)\n"
" -is, --internal-size internal texture height (default: 720)\n"
" -t, --tempo base tempo (default: 60)\n"
" --demo demonstration mode\n"
" -w, --windowed not fullscreen\n");
puts(
PACKAGE
" " VERSION "\n\n"
"usage: " PACKAGE " "
"[-h] "
"[-v] "
"[-hr] "
"[-s=SCREEN] "
"[-m=SCREEN] "
"[-mo] "
"[-f=DIR_PATH] "
"[-fc=CFG_PATH] "
"[-is=SIZE] "
"[-mf=FACTOR] "
"[-t=TEMPO] "
"[--demo] "
"[-w] "
"\n\n"
"Fusion Of Real-time Generative Effects.\n\n"
"options:\n"
" -h, --help show this help message and exit\n"
" -v, --version print version\n"
" -hr, --hot-reload hot reload of shaders scripts\n"
" -s, --screen output screen number (default: primary)\n"
" -m, --monitor monitor screen number (default: none)\n"
" -mo, --monitor-only no output screen\n"
" -f, --frag fragment shaders directory (default: TODO)\n"
" -fc, --frag-config fragment shaders config file (default: "
"TODO)\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"
" --demo demonstration mode\n"
" -w, --windowed not fullscreen\n");
exit(status_code);
}
@@ -86,6 +92,7 @@ Parameters args_parse(int argc, char **argv) {
params.frag_path = 0;
params.frag_config_path = 0;
params.internal_size = 720;
params.monitor_factor = 3;
params.base_tempo = 60.0f;
params.demo = false;
params.windowed = false;
@@ -110,6 +117,8 @@ Parameters args_parse(int argc, char **argv) {
params.base_tempo = (float)parse_uint(arg, value);
} else if (is_arg(arg, "-is") || is_arg(arg, "--internal-size")) {
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")) {
params.monitor = true;
params.monitor_screen = parse_uint(arg, value);
-4
View File
@@ -9,8 +9,4 @@
#define VERSION "(dev)"
#endif /* VERSION */
#ifndef SUB_COUNT
#define SUB_COUNT 16
#endif /* SUB_COUNT */
#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,
Timer *timer) {
unsigned int monitor_factor, Timer *timer) {
if (hr) {
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) {
window_use(window_output, &context);
shaders_compute(program, context, false);
shaders_compute(program, context, false, 1);
window_refresh(window_output);
}
@@ -144,7 +143,7 @@ static void loop(bool hr, File *common_shader_code, File *fragment_shaders,
if (window_monitor != NULL) {
window_use(window_monitor, &context);
shaders_compute(program_monitor, context, true);
shaders_compute(program_monitor, context, true, monitor_factor);
window_refresh(window_monitor);
}
@@ -240,7 +239,7 @@ void forge_run(Parameters params) {
window_use(window_output, &context);
program = shaders_init(fragment_shaders, shader_config, context);
program = shaders_init(fragment_shaders, shader_config, context, 1);
} else {
window_output = NULL;
}
@@ -252,7 +251,8 @@ void forge_run(Parameters params) {
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 {
window_monitor = NULL;
}
@@ -276,7 +276,8 @@ void forge_run(Parameters params) {
while ((window_output == NULL || !window_should_close(window_output)) &&
(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);
+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;
}
static void init_textures(ShaderProgram *program, Context context) {
static void init_textures(ShaderProgram *program, Context context,
unsigned int downscaling) {
unsigned int i;
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]);
// define texture image as empty
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
(int)(context.internal_size * (float)context.width / context.height),
context.internal_size, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
(int)((context.internal_size / downscaling) *
(float)context.width / (context.height)),
context.internal_size / downscaling, 0, GL_RGB,
GL_UNSIGNED_BYTE, 0);
// setup mipmap context
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,
Context context) {
Context context, unsigned int downscaling) {
ShaderProgram program;
program.error = false;
@@ -265,7 +267,7 @@ ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config,
program.sub_variant_count =
config_file_get_int(shader_config, "SUB_VARIANT_COUNT", 1);
init_textures(&program, context);
init_textures(&program, context, downscaling);
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;
// viewport changed
@@ -305,16 +308,17 @@ static void update_viewport(ShaderProgram program, Context context) {
// clean and resize all textures
for (i = 0; i < program.tex_count; i++) {
glActiveTexture(GL_TEXTURE0 + i);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
(int)(context.internal_size * (float)context.width / context.height),
context.internal_size, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
(int)((context.internal_size / downscaling) *
(float)context.width / (context.height)),
(int)(float)context.internal_size / downscaling, 0, GL_RGB,
GL_UNSIGNED_BYTE, 0);
}
}
}
static void use_program(ShaderProgram program, int i, bool output,
Context context) {
Context context, unsigned int downscaling) {
unsigned int j, k;
GLuint *subroutines;
vec2 resolution;
@@ -335,10 +339,10 @@ static void use_program(ShaderProgram program, int i, bool output,
// clear buffer
glClear(GL_COLOR_BUFFER_BIT);
} else {
glViewport(
0, 0,
(int)(context.internal_size * (float)context.width / context.height),
context.internal_size);
glViewport(0, 0,
(int)((context.internal_size / downscaling) *
(float)context.width / (context.height)),
(int)(float)context.internal_size / downscaling);
// use memory framebuffer
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);
}
void shaders_compute(ShaderProgram program, Context context, bool monitor) {
void shaders_compute(ShaderProgram program, Context context, bool monitor,
unsigned int downscaling) {
unsigned int i;
update_viewport(program, context);
update_viewport(program, context, downscaling);
for (i = 0; i < program.frag_count; i++) {
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,
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
ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config,
Context context);
Context context, unsigned int downscaling);
void shaders_update(ShaderProgram program, File *fragment_shaders,
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 */
+1
View File
@@ -18,6 +18,7 @@ typedef struct Parameters {
char *frag_path;
char *frag_config_path;
unsigned int internal_size;
unsigned int monitor_factor;
float base_tempo;
bool demo;
bool windowed;
-2
View File
@@ -89,8 +89,6 @@ static void use_window(GLFWwindow *window) {
glfwMakeContextCurrent(window);
// link GLAD and GLFW window
gladLoadGL(glfwGetProcAddress);
// vsync
glfwSwapInterval(1);
}
void window_startup(void (*error_callback)(int, const char *)) {