diff --git a/bind/v4k.lua b/bind/v4k.lua index 8ce8872..a547c01 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -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); diff --git a/demos/01-demo2d.c b/demos/01-demo2d.c index d474c66..b230a8b 100644 --- a/demos/01-demo2d.c +++ b/demos/01-demo2d.c @@ -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)) { diff --git a/demos/06-material.c b/demos/06-material.c index 9f06faf..43d9427 100644 --- a/demos/06-material.c +++ b/demos/06-material.c @@ -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 ); diff --git a/demos/99-lod.c b/demos/99-lod.c index a897d16..99bfe91 100644 --- a/demos/99-lod.c +++ b/demos/99-lod.c @@ -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); diff --git a/engine/art/shaders/fs_3_4_skybox_rayleigh.glsl b/engine/art/shaders/fs_3_4_skybox_rayleigh.glsl index 6f4bbfa..bb68bd1 100644 --- a/engine/art/shaders/fs_3_4_skybox_rayleigh.glsl +++ b/engine/art/shaders/fs_3_4_skybox_rayleigh.glsl @@ -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)); } diff --git a/engine/art/shaders/pbr.fs b/engine/art/shaders/pbr.fs index 139a5e2..817415c 100644 --- a/engine/art/shaders/pbr.fs +++ b/engine/art/shaders/pbr.fs @@ -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. diff --git a/engine/art/skyboxes/skysphere.fs b/engine/art/skyboxes/skysphere.fs index abc286f..feffa5a 100644 --- a/engine/art/skyboxes/skysphere.fs +++ b/engine/art/skyboxes/skysphere.fs @@ -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) ); } diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index 14f5413..2f3a071 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -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) ) { - passfx *pass = &fx->pass[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); } diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index 82db3d1..dd26857 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -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) ) { - passfx *pass = &fx->pass[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); } diff --git a/engine/split/v4k_render.h b/engine/split/v4k_render.h index 8de3286..5611b37 100644 --- a/engine/split/v4k_render.h +++ b/engine/split/v4k_render.h @@ -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(); diff --git a/engine/v4k.c b/engine/v4k.c index 0ad3568..c4bc261 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -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) ) { - passfx *pass = &fx->pass[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); } diff --git a/engine/v4k.h b/engine/v4k.h index 69834f1..3519545 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -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();