fx: fx_order support

main
Dominik Madarász 2024-03-27 14:00:03 +01:00
parent 2bc338172c
commit 9992c74e52
12 changed files with 166 additions and 78 deletions

View File

@ -1417,6 +1417,7 @@ typedef struct lightmap_t {
void fx_enable_all(int enabled);
char * fx_name(int pass);
int fx_find(const char *name);
void fx_order(int pass, unsigned priority);
int ui_fx(int pass);
int ui_fxs();
void* screenshot(int components);

View File

@ -81,10 +81,16 @@ int main() {
// fx: load all post fx files in all subdirs. enable a few filters by default
fx_load("fx**.fs");
fx_enable(fx_find("fxCRT2.fs"), 1);
fx_enable(fx_find("fxGrain.fs"), 1);
fx_enable(fx_find("fxContrast.fs"), 1);
fx_enable(fx_find("fxVignette.fs"), 1);
fx_enable(fx_find("fxCRT2.fs"), 1);
// sort them
fx_order(fx_find("fxCRT2.fs"), 1);
fx_order(fx_find("fxGrain.fs"), 2);
fx_order(fx_find("fxContrast.fs"), 3);
fx_order(fx_find("fxVignette.fs"), 4);
// demo loop
while (window_swap() && !input_down(KEY_ESC)) {

View File

@ -20,7 +20,7 @@ const char *skyboxes[][2] = { // reflection, env, metadata
int main() {
// create the window
window_create( 0.75f, WINDOW_MSAA8 );
window_create( 0.75f, 0 );
window_color( GRAY );
// create camera
@ -28,6 +28,7 @@ int main() {
// fx: load all post fx files in all subdirs.
fx_load("fx**.fs");
fx_enable(fx_find("fxAces.fs"), 1);
// load video, RGB texture, no audio
video_t *v = video( "pexels-pachon-in-motion-17486489.mp4", VIDEO_RGB | VIDEO_NO_AUDIO | VIDEO_LOOP ); video_seek(v, 30);
@ -37,8 +38,8 @@ int main() {
// load model
model_t m1 = model("suzanne.obj", MODEL_NO_ANIMATIONS);
model_t m2 = model("suzanne.obj", MODEL_NO_ANIMATIONS|MODEL_MATCAPS);
// model_t m3 = model("damagedhelmet.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR);
model_t m3 = model("Scutum_low.fbx", MODEL_NO_ANIMATIONS|MODEL_PBR);
model_t m3 = model("damagedhelmet.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR);
// model_t m3 = model("Scutum_low.fbx", MODEL_NO_ANIMATIONS|MODEL_PBR);
// model_t m4 = model("avp/scene.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR);
// model_t m3 = model("Cerberus_LP.FBX", MODEL_NO_ANIMATIONS|MODEL_PBR);
@ -71,7 +72,7 @@ int main() {
object_model(obj4, m3);
object_scale(obj4, vec3(3,3,3));
object_move(obj4, vec3(-10+6*3,0,-10));
object_pivot(obj4, vec3(0,0,90));
object_pivot(obj4, vec3(0,90,0));
// spawn object5 (pbr)
// object_t* obj5 = scene_spawn();
@ -84,7 +85,7 @@ int main() {
scene_spawn_light(); // sun
light_t* l = scene_spawn_light();
light_type(l, LIGHT_POINT);
l->diffuse = vec3(1,0,0);
// l->diffuse = vec3(0,0,0);
// load skybox
scene_get_active()->skybox = skybox_pbr(skyboxes[0][0], skyboxes[0][0], skyboxes[0][1]);
@ -92,7 +93,7 @@ int main() {
while(window_swap() && !input(KEY_ESC)) {
// draw environment
ddraw_grid(0);
// ddraw_grid(0);
// update video
video_decode( v );

View File

@ -128,7 +128,6 @@ void DrawModel(mesh_t *m) {
"out vec4 fragcolor;\n"
"void main() {\n"
"fragcolor = vec4(v_normal, 1.0);\n" // diffuse
"fragcolor.rgb = pow(fragcolor.rgb, vec3(2.2));\n" // diffuse
"}";
static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor", NULL);

View File

@ -8,7 +8,6 @@ uniform float uMieScattering;
uniform float uRayleighScaleHeight;
uniform float uMieScaleHeight;
uniform float uMiePreferredDirection;
uniform float u_gamma; /// set:2.2
in vec3 v_direction;
out vec4 fragcolor;
@ -36,7 +35,6 @@ void main() {
color = 1.0 - exp(-1.0 * color);
fragcolor = vec4(color, 1);
fragcolor.rgb = pow(fragcolor.rgb, vec3(u_gamma));
}

View File

@ -472,7 +472,7 @@ void main(void)
float e = 0.14f;
color = clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
// gamma correction
// color = pow( color, vec3(2.2) );
color = pow( color, vec3(1.0/2.2) );
#endif
// dither with noise.

View File

@ -56,5 +56,4 @@ void main(void) {
color += vec3( (-1.5/256.) + (3./256.) * dither );
frag_color = vec4( color, 1.0f );
frag_color.rgb = pow( frag_color.rgb, vec3(2.2) );
}

View File

@ -17674,6 +17674,7 @@ API int fx_enabled(int pass);
API void fx_enable_all(int enabled);
API char * fx_name(int pass);
API int fx_find(const char *name);
API void fx_order(int pass, unsigned priority);
API int ui_fx(int pass);
API int ui_fxs();
@ -372244,6 +372245,8 @@ struct passfx {
char *name;
unsigned program;
int uniforms[16];
unsigned priority; // 0xFFFFFF
bool enabled;
};
struct postfx {
@ -372251,8 +372254,7 @@ struct postfx {
unsigned fb[2];
texture_t diffuse[2], depth[2];
// shader passes
passfx pass[64];
uint64_t mask;
array(passfx) pass;
// global enable flag
bool enabled;
//
@ -372278,9 +372280,10 @@ void postfx_create(postfx *fx, int flags) {
}
void postfx_destroy( postfx *fx ) {
for( int i = 0; i < 64; ++i ) {
for( int i = 0; i < array_count(fx->pass); ++i ) {
FREE(fx->pass[i].name);
}
array_free(fx->pass);
texture_destroy(&fx->diffuse[0]);
texture_destroy(&fx->diffuse[1]);
texture_destroy(&fx->depth[0]);
@ -372292,21 +372295,31 @@ void postfx_destroy( postfx *fx ) {
}
char* postfx_name(postfx *fx, int slot) {
return slot < 0 ? "" : fx->pass[ slot & 63 ].name;
return slot < 0 || slot >= array_count(fx->pass) ? "" : fx->pass[ slot ].name;
}
int postfx_find(postfx *fx, const char *name) {
name = file_name(name);
for( int i = 0; i < 64; ++i) if(!strcmpi(fx->pass[i].name, name)) return i;
for( int i = 0; i < array_count(fx->pass); ++i) if(!strcmpi(fx->pass[i].name, name)) return i;
return -1;
}
static
int postfx_sort_fn(const void *a, const void *b) {
return ((passfx*)a)->priority - ((passfx*)b)->priority;
}
void postfx_order(postfx *fx, int pass, unsigned priority) {
if (pass < 0 || pass >= array_count(fx->pass)) return;
fx->pass[pass].priority = priority;
array_sort(fx->pass, postfx_sort_fn);
}
int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
PRINTF("%s\n", name);
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
int slot = fx->num_loaded++;
passfx *p = &fx->pass[ slot & 63 ];
passfx pass={0};
array_push(fx->pass, pass);
passfx *p = array_back(fx->pass);
p->name = STRDUP(name);
// preload stuff
@ -372357,31 +372370,35 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
// set quad
glGenVertexArrays(1, &p->m.vao);
return slot;
return array_count(fx->pass)-1;
}
bool postfx_enable(postfx *fx, int pass, bool enabled) {
if( pass < 0 ) return false;
fx->mask = enabled ? fx->mask | (1ull << pass) : fx->mask & ~(1ull << pass);
fx->enabled = !!popcnt64(fx->mask);
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
fx->pass[pass].enabled = enabled;
fx->enabled = !!array_count(fx->pass);
return fx->enabled;
}
bool postfx_enabled(postfx *fx, int pass) {
if( pass < 0 ) return false;
return (!!(fx->mask & (1ull << pass)));
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
return fx->pass[pass].enabled;
}
bool postfx_toggle(postfx *fx, int pass) {
if( pass < 0 ) return false;
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
return postfx_enable(fx, pass, 1 ^ postfx_enabled(fx, pass));
}
void postfx_clear(postfx *fx) {
fx->mask = fx->enabled = 0;
for (int i = 0; i < array_count(fx->pass); i++) {
fx->pass[i].enabled = 0;
}
fx->enabled = 0;
}
int ui_postfx(postfx *fx, int pass) {
if (pass < 0 || pass >= array_count(fx->pass)) return 0;
int on = ui_enabled();
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
int rc = ui_shader(fx->pass[pass].program);
@ -372389,6 +372406,15 @@ int ui_postfx(postfx *fx, int pass) {
return rc;
}
static
int postfx_active_passes(postfx *fx) {
int num_passes = 0;
for (int i = 0; i < array_count(fx->pass); i++)
if (fx->pass[i].enabled)
++num_passes;
return num_passes;
}
bool postfx_begin(postfx *fx, int width, int height) {
// reset clear color: needed in case transparent window is being used (alpha != 0)
glClearColor(0,0,0,0); // @transparent
@ -372416,7 +372442,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0);
}
uint64_t num_active_passes = popcnt64(fx->mask);
uint64_t num_active_passes = postfx_active_passes(fx);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
@ -372436,7 +372462,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
}
bool postfx_end(postfx *fx) {
uint64_t num_active_passes = popcnt64(fx->mask);
uint64_t num_active_passes = postfx_active_passes(fx);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
@ -372456,10 +372482,9 @@ bool postfx_end(postfx *fx) {
float mx = input(MOUSE_X);
float my = input(MOUSE_Y);
for(int i = 0, e = countof(fx->pass); i < e; ++i) {
if( fx->mask & (1ull << i) ) {
for(int i = 0, e = array_count(fx->pass); i < e; ++i) {
passfx *pass = &fx->pass[i];
if( pass->enabled ) {
if( !pass->program ) { --num_active_passes; continue; }
glUseProgram(pass->program);
@ -372557,6 +372582,9 @@ char *fx_name(int pass) {
int fx_find(const char *name) {
return postfx_find(&fx, name);
}
void fx_order(int pass, unsigned priority) {
postfx_order(&fx, pass, priority);
}
int ui_fx(int pass) {
return ui_postfx(&fx, pass);
}

View File

@ -2226,6 +2226,8 @@ struct passfx {
char *name;
unsigned program;
int uniforms[16];
unsigned priority; // 0xFFFFFF
bool enabled;
};
struct postfx {
@ -2233,8 +2235,7 @@ struct postfx {
unsigned fb[2];
texture_t diffuse[2], depth[2];
// shader passes
passfx pass[64];
uint64_t mask;
array(passfx) pass;
// global enable flag
bool enabled;
//
@ -2260,9 +2261,10 @@ void postfx_create(postfx *fx, int flags) {
}
void postfx_destroy( postfx *fx ) {
for( int i = 0; i < 64; ++i ) {
for( int i = 0; i < array_count(fx->pass); ++i ) {
FREE(fx->pass[i].name);
}
array_free(fx->pass);
texture_destroy(&fx->diffuse[0]);
texture_destroy(&fx->diffuse[1]);
texture_destroy(&fx->depth[0]);
@ -2274,21 +2276,31 @@ void postfx_destroy( postfx *fx ) {
}
char* postfx_name(postfx *fx, int slot) {
return slot < 0 ? "" : fx->pass[ slot & 63 ].name;
return slot < 0 || slot >= array_count(fx->pass) ? "" : fx->pass[ slot ].name;
}
int postfx_find(postfx *fx, const char *name) {
name = file_name(name);
for( int i = 0; i < 64; ++i) if(!strcmpi(fx->pass[i].name, name)) return i;
for( int i = 0; i < array_count(fx->pass); ++i) if(!strcmpi(fx->pass[i].name, name)) return i;
return -1;
}
static
int postfx_sort_fn(const void *a, const void *b) {
return ((passfx*)a)->priority - ((passfx*)b)->priority;
}
void postfx_order(postfx *fx, int pass, unsigned priority) {
if (pass < 0 || pass >= array_count(fx->pass)) return;
fx->pass[pass].priority = priority;
array_sort(fx->pass, postfx_sort_fn);
}
int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
PRINTF("%s\n", name);
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
int slot = fx->num_loaded++;
passfx *p = &fx->pass[ slot & 63 ];
passfx pass={0};
array_push(fx->pass, pass);
passfx *p = array_back(fx->pass);
p->name = STRDUP(name);
// preload stuff
@ -2339,31 +2351,35 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
// set quad
glGenVertexArrays(1, &p->m.vao);
return slot;
return array_count(fx->pass)-1;
}
bool postfx_enable(postfx *fx, int pass, bool enabled) {
if( pass < 0 ) return false;
fx->mask = enabled ? fx->mask | (1ull << pass) : fx->mask & ~(1ull << pass);
fx->enabled = !!popcnt64(fx->mask);
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
fx->pass[pass].enabled = enabled;
fx->enabled = !!array_count(fx->pass);
return fx->enabled;
}
bool postfx_enabled(postfx *fx, int pass) {
if( pass < 0 ) return false;
return (!!(fx->mask & (1ull << pass)));
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
return fx->pass[pass].enabled;
}
bool postfx_toggle(postfx *fx, int pass) {
if( pass < 0 ) return false;
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
return postfx_enable(fx, pass, 1 ^ postfx_enabled(fx, pass));
}
void postfx_clear(postfx *fx) {
fx->mask = fx->enabled = 0;
for (int i = 0; i < array_count(fx->pass); i++) {
fx->pass[i].enabled = 0;
}
fx->enabled = 0;
}
int ui_postfx(postfx *fx, int pass) {
if (pass < 0 || pass >= array_count(fx->pass)) return 0;
int on = ui_enabled();
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
int rc = ui_shader(fx->pass[pass].program);
@ -2371,6 +2387,15 @@ int ui_postfx(postfx *fx, int pass) {
return rc;
}
static
int postfx_active_passes(postfx *fx) {
int num_passes = 0;
for (int i = 0; i < array_count(fx->pass); i++)
if (fx->pass[i].enabled)
++num_passes;
return num_passes;
}
bool postfx_begin(postfx *fx, int width, int height) {
// reset clear color: needed in case transparent window is being used (alpha != 0)
glClearColor(0,0,0,0); // @transparent
@ -2398,7 +2423,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0);
}
uint64_t num_active_passes = popcnt64(fx->mask);
uint64_t num_active_passes = postfx_active_passes(fx);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
@ -2418,7 +2443,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
}
bool postfx_end(postfx *fx) {
uint64_t num_active_passes = popcnt64(fx->mask);
uint64_t num_active_passes = postfx_active_passes(fx);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
@ -2438,10 +2463,9 @@ bool postfx_end(postfx *fx) {
float mx = input(MOUSE_X);
float my = input(MOUSE_Y);
for(int i = 0, e = countof(fx->pass); i < e; ++i) {
if( fx->mask & (1ull << i) ) {
for(int i = 0, e = array_count(fx->pass); i < e; ++i) {
passfx *pass = &fx->pass[i];
if( pass->enabled ) {
if( !pass->program ) { --num_active_passes; continue; }
glUseProgram(pass->program);
@ -2539,6 +2563,9 @@ char *fx_name(int pass) {
int fx_find(const char *name) {
return postfx_find(&fx, name);
}
void fx_order(int pass, unsigned priority) {
postfx_order(&fx, pass, priority);
}
int ui_fx(int pass) {
return ui_postfx(&fx, pass);
}

View File

@ -652,6 +652,7 @@ API int fx_enabled(int pass);
API void fx_enable_all(int enabled);
API char * fx_name(int pass);
API int fx_find(const char *name);
API void fx_order(int pass, unsigned priority);
API int ui_fx(int pass);
API int ui_fxs();

View File

@ -19398,6 +19398,8 @@ struct passfx {
char *name;
unsigned program;
int uniforms[16];
unsigned priority; // 0xFFFFFF
bool enabled;
};
struct postfx {
@ -19405,8 +19407,7 @@ struct postfx {
unsigned fb[2];
texture_t diffuse[2], depth[2];
// shader passes
passfx pass[64];
uint64_t mask;
array(passfx) pass;
// global enable flag
bool enabled;
//
@ -19432,9 +19433,10 @@ void postfx_create(postfx *fx, int flags) {
}
void postfx_destroy( postfx *fx ) {
for( int i = 0; i < 64; ++i ) {
for( int i = 0; i < array_count(fx->pass); ++i ) {
FREE(fx->pass[i].name);
}
array_free(fx->pass);
texture_destroy(&fx->diffuse[0]);
texture_destroy(&fx->diffuse[1]);
texture_destroy(&fx->depth[0]);
@ -19446,21 +19448,31 @@ void postfx_destroy( postfx *fx ) {
}
char* postfx_name(postfx *fx, int slot) {
return slot < 0 ? "" : fx->pass[ slot & 63 ].name;
return slot < 0 || slot >= array_count(fx->pass) ? "" : fx->pass[ slot ].name;
}
int postfx_find(postfx *fx, const char *name) {
name = file_name(name);
for( int i = 0; i < 64; ++i) if(!strcmpi(fx->pass[i].name, name)) return i;
for( int i = 0; i < array_count(fx->pass); ++i) if(!strcmpi(fx->pass[i].name, name)) return i;
return -1;
}
static
int postfx_sort_fn(const void *a, const void *b) {
return ((passfx*)a)->priority - ((passfx*)b)->priority;
}
void postfx_order(postfx *fx, int pass, unsigned priority) {
if (pass < 0 || pass >= array_count(fx->pass)) return;
fx->pass[pass].priority = priority;
array_sort(fx->pass, postfx_sort_fn);
}
int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
PRINTF("%s\n", name);
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
int slot = fx->num_loaded++;
passfx *p = &fx->pass[ slot & 63 ];
passfx pass={0};
array_push(fx->pass, pass);
passfx *p = array_back(fx->pass);
p->name = STRDUP(name);
// preload stuff
@ -19511,31 +19523,35 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
// set quad
glGenVertexArrays(1, &p->m.vao);
return slot;
return array_count(fx->pass)-1;
}
bool postfx_enable(postfx *fx, int pass, bool enabled) {
if( pass < 0 ) return false;
fx->mask = enabled ? fx->mask | (1ull << pass) : fx->mask & ~(1ull << pass);
fx->enabled = !!popcnt64(fx->mask);
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
fx->pass[pass].enabled = enabled;
fx->enabled = !!array_count(fx->pass);
return fx->enabled;
}
bool postfx_enabled(postfx *fx, int pass) {
if( pass < 0 ) return false;
return (!!(fx->mask & (1ull << pass)));
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
return fx->pass[pass].enabled;
}
bool postfx_toggle(postfx *fx, int pass) {
if( pass < 0 ) return false;
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
return postfx_enable(fx, pass, 1 ^ postfx_enabled(fx, pass));
}
void postfx_clear(postfx *fx) {
fx->mask = fx->enabled = 0;
for (int i = 0; i < array_count(fx->pass); i++) {
fx->pass[i].enabled = 0;
}
fx->enabled = 0;
}
int ui_postfx(postfx *fx, int pass) {
if (pass < 0 || pass >= array_count(fx->pass)) return 0;
int on = ui_enabled();
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
int rc = ui_shader(fx->pass[pass].program);
@ -19543,6 +19559,15 @@ int ui_postfx(postfx *fx, int pass) {
return rc;
}
static
int postfx_active_passes(postfx *fx) {
int num_passes = 0;
for (int i = 0; i < array_count(fx->pass); i++)
if (fx->pass[i].enabled)
++num_passes;
return num_passes;
}
bool postfx_begin(postfx *fx, int width, int height) {
// reset clear color: needed in case transparent window is being used (alpha != 0)
glClearColor(0,0,0,0); // @transparent
@ -19570,7 +19595,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0);
}
uint64_t num_active_passes = popcnt64(fx->mask);
uint64_t num_active_passes = postfx_active_passes(fx);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
@ -19590,7 +19615,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
}
bool postfx_end(postfx *fx) {
uint64_t num_active_passes = popcnt64(fx->mask);
uint64_t num_active_passes = postfx_active_passes(fx);
bool active = fx->enabled && num_active_passes;
if( !active ) {
return false;
@ -19610,10 +19635,9 @@ bool postfx_end(postfx *fx) {
float mx = input(MOUSE_X);
float my = input(MOUSE_Y);
for(int i = 0, e = countof(fx->pass); i < e; ++i) {
if( fx->mask & (1ull << i) ) {
for(int i = 0, e = array_count(fx->pass); i < e; ++i) {
passfx *pass = &fx->pass[i];
if( pass->enabled ) {
if( !pass->program ) { --num_active_passes; continue; }
glUseProgram(pass->program);
@ -19711,6 +19735,9 @@ char *fx_name(int pass) {
int fx_find(const char *name) {
return postfx_find(&fx, name);
}
void fx_order(int pass, unsigned priority) {
postfx_order(&fx, pass, priority);
}
int ui_fx(int pass) {
return ui_postfx(&fx, pass);
}

View File

@ -3741,6 +3741,7 @@ API int fx_enabled(int pass);
API void fx_enable_all(int enabled);
API char * fx_name(int pass);
API int fx_find(const char *name);
API void fx_order(int pass, unsigned priority);
API int ui_fx(int pass);
API int ui_fxs();