fx: fx_order support
parent
2bc338172c
commit
9992c74e52
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) );
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
71
engine/v4k.c
71
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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue