fx: fx_order support
parent
2bc338172c
commit
9992c74e52
|
@ -1417,6 +1417,7 @@ typedef struct lightmap_t {
|
||||||
void fx_enable_all(int enabled);
|
void fx_enable_all(int enabled);
|
||||||
char * fx_name(int pass);
|
char * fx_name(int pass);
|
||||||
int fx_find(const char *name);
|
int fx_find(const char *name);
|
||||||
|
void fx_order(int pass, unsigned priority);
|
||||||
int ui_fx(int pass);
|
int ui_fx(int pass);
|
||||||
int ui_fxs();
|
int ui_fxs();
|
||||||
void* screenshot(int components);
|
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 all post fx files in all subdirs. enable a few filters by default
|
||||||
fx_load("fx**.fs");
|
fx_load("fx**.fs");
|
||||||
fx_enable(fx_find("fxCRT2.fs"), 1);
|
|
||||||
fx_enable(fx_find("fxGrain.fs"), 1);
|
fx_enable(fx_find("fxGrain.fs"), 1);
|
||||||
fx_enable(fx_find("fxContrast.fs"), 1);
|
fx_enable(fx_find("fxContrast.fs"), 1);
|
||||||
fx_enable(fx_find("fxVignette.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
|
// demo loop
|
||||||
while (window_swap() && !input_down(KEY_ESC)) {
|
while (window_swap() && !input_down(KEY_ESC)) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ const char *skyboxes[][2] = { // reflection, env, metadata
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// create the window
|
// create the window
|
||||||
window_create( 0.75f, WINDOW_MSAA8 );
|
window_create( 0.75f, 0 );
|
||||||
window_color( GRAY );
|
window_color( GRAY );
|
||||||
|
|
||||||
// create camera
|
// create camera
|
||||||
|
@ -28,6 +28,7 @@ int main() {
|
||||||
|
|
||||||
// fx: load all post fx files in all subdirs.
|
// fx: load all post fx files in all subdirs.
|
||||||
fx_load("fx**.fs");
|
fx_load("fx**.fs");
|
||||||
|
fx_enable(fx_find("fxAces.fs"), 1);
|
||||||
|
|
||||||
// load video, RGB texture, no audio
|
// 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);
|
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
|
// load model
|
||||||
model_t m1 = model("suzanne.obj", MODEL_NO_ANIMATIONS);
|
model_t m1 = model("suzanne.obj", MODEL_NO_ANIMATIONS);
|
||||||
model_t m2 = model("suzanne.obj", MODEL_NO_ANIMATIONS|MODEL_MATCAPS);
|
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("damagedhelmet.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR);
|
||||||
model_t m3 = model("Scutum_low.fbx", 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 m4 = model("avp/scene.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR);
|
||||||
// model_t m3 = model("Cerberus_LP.FBX", 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_model(obj4, m3);
|
||||||
object_scale(obj4, vec3(3,3,3));
|
object_scale(obj4, vec3(3,3,3));
|
||||||
object_move(obj4, vec3(-10+6*3,0,-10));
|
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)
|
// spawn object5 (pbr)
|
||||||
// object_t* obj5 = scene_spawn();
|
// object_t* obj5 = scene_spawn();
|
||||||
|
@ -84,7 +85,7 @@ int main() {
|
||||||
scene_spawn_light(); // sun
|
scene_spawn_light(); // sun
|
||||||
light_t* l = scene_spawn_light();
|
light_t* l = scene_spawn_light();
|
||||||
light_type(l, LIGHT_POINT);
|
light_type(l, LIGHT_POINT);
|
||||||
l->diffuse = vec3(1,0,0);
|
// l->diffuse = vec3(0,0,0);
|
||||||
|
|
||||||
// load skybox
|
// load skybox
|
||||||
scene_get_active()->skybox = skybox_pbr(skyboxes[0][0], skyboxes[0][0], skyboxes[0][1]);
|
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)) {
|
while(window_swap() && !input(KEY_ESC)) {
|
||||||
// draw environment
|
// draw environment
|
||||||
ddraw_grid(0);
|
// ddraw_grid(0);
|
||||||
|
|
||||||
// update video
|
// update video
|
||||||
video_decode( v );
|
video_decode( v );
|
||||||
|
|
|
@ -128,7 +128,6 @@ void DrawModel(mesh_t *m) {
|
||||||
"out vec4 fragcolor;\n"
|
"out vec4 fragcolor;\n"
|
||||||
"void main() {\n"
|
"void main() {\n"
|
||||||
"fragcolor = vec4(v_normal, 1.0);\n" // diffuse
|
"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);
|
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 uRayleighScaleHeight;
|
||||||
uniform float uMieScaleHeight;
|
uniform float uMieScaleHeight;
|
||||||
uniform float uMiePreferredDirection;
|
uniform float uMiePreferredDirection;
|
||||||
uniform float u_gamma; /// set:2.2
|
|
||||||
|
|
||||||
in vec3 v_direction;
|
in vec3 v_direction;
|
||||||
out vec4 fragcolor;
|
out vec4 fragcolor;
|
||||||
|
@ -36,7 +35,6 @@ void main() {
|
||||||
color = 1.0 - exp(-1.0 * color);
|
color = 1.0 - exp(-1.0 * color);
|
||||||
|
|
||||||
fragcolor = vec4(color, 1);
|
fragcolor = vec4(color, 1);
|
||||||
fragcolor.rgb = pow(fragcolor.rgb, vec3(u_gamma));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -472,7 +472,7 @@ void main(void)
|
||||||
float e = 0.14f;
|
float e = 0.14f;
|
||||||
color = clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
|
color = clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
|
||||||
// gamma correction
|
// gamma correction
|
||||||
// color = pow( color, vec3(2.2) );
|
color = pow( color, vec3(1.0/2.2) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// dither with noise.
|
// dither with noise.
|
||||||
|
|
|
@ -56,5 +56,4 @@ void main(void) {
|
||||||
color += vec3( (-1.5/256.) + (3./256.) * dither );
|
color += vec3( (-1.5/256.) + (3./256.) * dither );
|
||||||
|
|
||||||
frag_color = vec4( color, 1.0f );
|
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 void fx_enable_all(int enabled);
|
||||||
API char * fx_name(int pass);
|
API char * fx_name(int pass);
|
||||||
API int fx_find(const char *name);
|
API int fx_find(const char *name);
|
||||||
|
API void fx_order(int pass, unsigned priority);
|
||||||
|
|
||||||
API int ui_fx(int pass);
|
API int ui_fx(int pass);
|
||||||
API int ui_fxs();
|
API int ui_fxs();
|
||||||
|
@ -372244,6 +372245,8 @@ struct passfx {
|
||||||
char *name;
|
char *name;
|
||||||
unsigned program;
|
unsigned program;
|
||||||
int uniforms[16];
|
int uniforms[16];
|
||||||
|
unsigned priority; // 0xFFFFFF
|
||||||
|
bool enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct postfx {
|
struct postfx {
|
||||||
|
@ -372251,8 +372254,7 @@ struct postfx {
|
||||||
unsigned fb[2];
|
unsigned fb[2];
|
||||||
texture_t diffuse[2], depth[2];
|
texture_t diffuse[2], depth[2];
|
||||||
// shader passes
|
// shader passes
|
||||||
passfx pass[64];
|
array(passfx) pass;
|
||||||
uint64_t mask;
|
|
||||||
// global enable flag
|
// global enable flag
|
||||||
bool enabled;
|
bool enabled;
|
||||||
//
|
//
|
||||||
|
@ -372278,9 +372280,10 @@ void postfx_create(postfx *fx, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void postfx_destroy( postfx *fx ) {
|
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);
|
FREE(fx->pass[i].name);
|
||||||
}
|
}
|
||||||
|
array_free(fx->pass);
|
||||||
texture_destroy(&fx->diffuse[0]);
|
texture_destroy(&fx->diffuse[0]);
|
||||||
texture_destroy(&fx->diffuse[1]);
|
texture_destroy(&fx->diffuse[1]);
|
||||||
texture_destroy(&fx->depth[0]);
|
texture_destroy(&fx->depth[0]);
|
||||||
|
@ -372292,21 +372295,31 @@ void postfx_destroy( postfx *fx ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char* postfx_name(postfx *fx, int slot) {
|
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) {
|
int postfx_find(postfx *fx, const char *name) {
|
||||||
name = file_name(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;
|
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 ) {
|
int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
|
||||||
PRINTF("%s\n", name);
|
PRINTF("%s\n", name);
|
||||||
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
|
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
|
||||||
|
|
||||||
int slot = fx->num_loaded++;
|
passfx pass={0};
|
||||||
|
array_push(fx->pass, pass);
|
||||||
passfx *p = &fx->pass[ slot & 63 ];
|
passfx *p = array_back(fx->pass);
|
||||||
p->name = STRDUP(name);
|
p->name = STRDUP(name);
|
||||||
|
|
||||||
// preload stuff
|
// preload stuff
|
||||||
|
@ -372357,31 +372370,35 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
|
||||||
|
|
||||||
// set quad
|
// set quad
|
||||||
glGenVertexArrays(1, &p->m.vao);
|
glGenVertexArrays(1, &p->m.vao);
|
||||||
return slot;
|
return array_count(fx->pass)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_enable(postfx *fx, int pass, bool enabled) {
|
bool postfx_enable(postfx *fx, int pass, bool enabled) {
|
||||||
if( pass < 0 ) return false;
|
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
|
||||||
fx->mask = enabled ? fx->mask | (1ull << pass) : fx->mask & ~(1ull << pass);
|
fx->pass[pass].enabled = enabled;
|
||||||
fx->enabled = !!popcnt64(fx->mask);
|
fx->enabled = !!array_count(fx->pass);
|
||||||
return fx->enabled;
|
return fx->enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_enabled(postfx *fx, int pass) {
|
bool postfx_enabled(postfx *fx, int pass) {
|
||||||
if( pass < 0 ) return false;
|
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
|
||||||
return (!!(fx->mask & (1ull << pass)));
|
return fx->pass[pass].enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_toggle(postfx *fx, int pass) {
|
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));
|
return postfx_enable(fx, pass, 1 ^ postfx_enabled(fx, pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
void postfx_clear(postfx *fx) {
|
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) {
|
int ui_postfx(postfx *fx, int pass) {
|
||||||
|
if (pass < 0 || pass >= array_count(fx->pass)) return 0;
|
||||||
int on = ui_enabled();
|
int on = ui_enabled();
|
||||||
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
|
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
|
||||||
int rc = ui_shader(fx->pass[pass].program);
|
int rc = ui_shader(fx->pass[pass].program);
|
||||||
|
@ -372389,6 +372406,15 @@ int ui_postfx(postfx *fx, int pass) {
|
||||||
return rc;
|
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) {
|
bool postfx_begin(postfx *fx, int width, int height) {
|
||||||
// reset clear color: needed in case transparent window is being used (alpha != 0)
|
// reset clear color: needed in case transparent window is being used (alpha != 0)
|
||||||
glClearColor(0,0,0,0); // @transparent
|
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);
|
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;
|
bool active = fx->enabled && num_active_passes;
|
||||||
if( !active ) {
|
if( !active ) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -372436,7 +372462,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_end(postfx *fx) {
|
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;
|
bool active = fx->enabled && num_active_passes;
|
||||||
if( !active ) {
|
if( !active ) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -372456,10 +372482,9 @@ bool postfx_end(postfx *fx) {
|
||||||
float mx = input(MOUSE_X);
|
float mx = input(MOUSE_X);
|
||||||
float my = input(MOUSE_Y);
|
float my = input(MOUSE_Y);
|
||||||
|
|
||||||
for(int i = 0, e = countof(fx->pass); i < e; ++i) {
|
for(int i = 0, e = array_count(fx->pass); i < e; ++i) {
|
||||||
if( fx->mask & (1ull << i) ) {
|
passfx *pass = &fx->pass[i];
|
||||||
passfx *pass = &fx->pass[i];
|
if( pass->enabled ) {
|
||||||
|
|
||||||
if( !pass->program ) { --num_active_passes; continue; }
|
if( !pass->program ) { --num_active_passes; continue; }
|
||||||
glUseProgram(pass->program);
|
glUseProgram(pass->program);
|
||||||
|
|
||||||
|
@ -372557,6 +372582,9 @@ char *fx_name(int pass) {
|
||||||
int fx_find(const char *name) {
|
int fx_find(const char *name) {
|
||||||
return postfx_find(&fx, name);
|
return postfx_find(&fx, name);
|
||||||
}
|
}
|
||||||
|
void fx_order(int pass, unsigned priority) {
|
||||||
|
postfx_order(&fx, pass, priority);
|
||||||
|
}
|
||||||
int ui_fx(int pass) {
|
int ui_fx(int pass) {
|
||||||
return ui_postfx(&fx, pass);
|
return ui_postfx(&fx, pass);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2226,6 +2226,8 @@ struct passfx {
|
||||||
char *name;
|
char *name;
|
||||||
unsigned program;
|
unsigned program;
|
||||||
int uniforms[16];
|
int uniforms[16];
|
||||||
|
unsigned priority; // 0xFFFFFF
|
||||||
|
bool enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct postfx {
|
struct postfx {
|
||||||
|
@ -2233,8 +2235,7 @@ struct postfx {
|
||||||
unsigned fb[2];
|
unsigned fb[2];
|
||||||
texture_t diffuse[2], depth[2];
|
texture_t diffuse[2], depth[2];
|
||||||
// shader passes
|
// shader passes
|
||||||
passfx pass[64];
|
array(passfx) pass;
|
||||||
uint64_t mask;
|
|
||||||
// global enable flag
|
// global enable flag
|
||||||
bool enabled;
|
bool enabled;
|
||||||
//
|
//
|
||||||
|
@ -2260,9 +2261,10 @@ void postfx_create(postfx *fx, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void postfx_destroy( postfx *fx ) {
|
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);
|
FREE(fx->pass[i].name);
|
||||||
}
|
}
|
||||||
|
array_free(fx->pass);
|
||||||
texture_destroy(&fx->diffuse[0]);
|
texture_destroy(&fx->diffuse[0]);
|
||||||
texture_destroy(&fx->diffuse[1]);
|
texture_destroy(&fx->diffuse[1]);
|
||||||
texture_destroy(&fx->depth[0]);
|
texture_destroy(&fx->depth[0]);
|
||||||
|
@ -2274,21 +2276,31 @@ void postfx_destroy( postfx *fx ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char* postfx_name(postfx *fx, int slot) {
|
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) {
|
int postfx_find(postfx *fx, const char *name) {
|
||||||
name = file_name(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;
|
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 ) {
|
int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
|
||||||
PRINTF("%s\n", name);
|
PRINTF("%s\n", name);
|
||||||
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
|
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
|
||||||
|
|
||||||
int slot = fx->num_loaded++;
|
passfx pass={0};
|
||||||
|
array_push(fx->pass, pass);
|
||||||
passfx *p = &fx->pass[ slot & 63 ];
|
passfx *p = array_back(fx->pass);
|
||||||
p->name = STRDUP(name);
|
p->name = STRDUP(name);
|
||||||
|
|
||||||
// preload stuff
|
// preload stuff
|
||||||
|
@ -2339,31 +2351,35 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
|
||||||
|
|
||||||
// set quad
|
// set quad
|
||||||
glGenVertexArrays(1, &p->m.vao);
|
glGenVertexArrays(1, &p->m.vao);
|
||||||
return slot;
|
return array_count(fx->pass)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_enable(postfx *fx, int pass, bool enabled) {
|
bool postfx_enable(postfx *fx, int pass, bool enabled) {
|
||||||
if( pass < 0 ) return false;
|
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
|
||||||
fx->mask = enabled ? fx->mask | (1ull << pass) : fx->mask & ~(1ull << pass);
|
fx->pass[pass].enabled = enabled;
|
||||||
fx->enabled = !!popcnt64(fx->mask);
|
fx->enabled = !!array_count(fx->pass);
|
||||||
return fx->enabled;
|
return fx->enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_enabled(postfx *fx, int pass) {
|
bool postfx_enabled(postfx *fx, int pass) {
|
||||||
if( pass < 0 ) return false;
|
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
|
||||||
return (!!(fx->mask & (1ull << pass)));
|
return fx->pass[pass].enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_toggle(postfx *fx, int pass) {
|
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));
|
return postfx_enable(fx, pass, 1 ^ postfx_enabled(fx, pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
void postfx_clear(postfx *fx) {
|
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) {
|
int ui_postfx(postfx *fx, int pass) {
|
||||||
|
if (pass < 0 || pass >= array_count(fx->pass)) return 0;
|
||||||
int on = ui_enabled();
|
int on = ui_enabled();
|
||||||
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
|
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
|
||||||
int rc = ui_shader(fx->pass[pass].program);
|
int rc = ui_shader(fx->pass[pass].program);
|
||||||
|
@ -2371,6 +2387,15 @@ int ui_postfx(postfx *fx, int pass) {
|
||||||
return rc;
|
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) {
|
bool postfx_begin(postfx *fx, int width, int height) {
|
||||||
// reset clear color: needed in case transparent window is being used (alpha != 0)
|
// reset clear color: needed in case transparent window is being used (alpha != 0)
|
||||||
glClearColor(0,0,0,0); // @transparent
|
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);
|
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;
|
bool active = fx->enabled && num_active_passes;
|
||||||
if( !active ) {
|
if( !active ) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2418,7 +2443,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_end(postfx *fx) {
|
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;
|
bool active = fx->enabled && num_active_passes;
|
||||||
if( !active ) {
|
if( !active ) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2438,10 +2463,9 @@ bool postfx_end(postfx *fx) {
|
||||||
float mx = input(MOUSE_X);
|
float mx = input(MOUSE_X);
|
||||||
float my = input(MOUSE_Y);
|
float my = input(MOUSE_Y);
|
||||||
|
|
||||||
for(int i = 0, e = countof(fx->pass); i < e; ++i) {
|
for(int i = 0, e = array_count(fx->pass); i < e; ++i) {
|
||||||
if( fx->mask & (1ull << i) ) {
|
passfx *pass = &fx->pass[i];
|
||||||
passfx *pass = &fx->pass[i];
|
if( pass->enabled ) {
|
||||||
|
|
||||||
if( !pass->program ) { --num_active_passes; continue; }
|
if( !pass->program ) { --num_active_passes; continue; }
|
||||||
glUseProgram(pass->program);
|
glUseProgram(pass->program);
|
||||||
|
|
||||||
|
@ -2539,6 +2563,9 @@ char *fx_name(int pass) {
|
||||||
int fx_find(const char *name) {
|
int fx_find(const char *name) {
|
||||||
return postfx_find(&fx, name);
|
return postfx_find(&fx, name);
|
||||||
}
|
}
|
||||||
|
void fx_order(int pass, unsigned priority) {
|
||||||
|
postfx_order(&fx, pass, priority);
|
||||||
|
}
|
||||||
int ui_fx(int pass) {
|
int ui_fx(int pass) {
|
||||||
return ui_postfx(&fx, pass);
|
return ui_postfx(&fx, pass);
|
||||||
}
|
}
|
||||||
|
|
|
@ -652,6 +652,7 @@ API int fx_enabled(int pass);
|
||||||
API void fx_enable_all(int enabled);
|
API void fx_enable_all(int enabled);
|
||||||
API char * fx_name(int pass);
|
API char * fx_name(int pass);
|
||||||
API int fx_find(const char *name);
|
API int fx_find(const char *name);
|
||||||
|
API void fx_order(int pass, unsigned priority);
|
||||||
|
|
||||||
API int ui_fx(int pass);
|
API int ui_fx(int pass);
|
||||||
API int ui_fxs();
|
API int ui_fxs();
|
||||||
|
|
71
engine/v4k.c
71
engine/v4k.c
|
@ -19398,6 +19398,8 @@ struct passfx {
|
||||||
char *name;
|
char *name;
|
||||||
unsigned program;
|
unsigned program;
|
||||||
int uniforms[16];
|
int uniforms[16];
|
||||||
|
unsigned priority; // 0xFFFFFF
|
||||||
|
bool enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct postfx {
|
struct postfx {
|
||||||
|
@ -19405,8 +19407,7 @@ struct postfx {
|
||||||
unsigned fb[2];
|
unsigned fb[2];
|
||||||
texture_t diffuse[2], depth[2];
|
texture_t diffuse[2], depth[2];
|
||||||
// shader passes
|
// shader passes
|
||||||
passfx pass[64];
|
array(passfx) pass;
|
||||||
uint64_t mask;
|
|
||||||
// global enable flag
|
// global enable flag
|
||||||
bool enabled;
|
bool enabled;
|
||||||
//
|
//
|
||||||
|
@ -19432,9 +19433,10 @@ void postfx_create(postfx *fx, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void postfx_destroy( postfx *fx ) {
|
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);
|
FREE(fx->pass[i].name);
|
||||||
}
|
}
|
||||||
|
array_free(fx->pass);
|
||||||
texture_destroy(&fx->diffuse[0]);
|
texture_destroy(&fx->diffuse[0]);
|
||||||
texture_destroy(&fx->diffuse[1]);
|
texture_destroy(&fx->diffuse[1]);
|
||||||
texture_destroy(&fx->depth[0]);
|
texture_destroy(&fx->depth[0]);
|
||||||
|
@ -19446,21 +19448,31 @@ void postfx_destroy( postfx *fx ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char* postfx_name(postfx *fx, int slot) {
|
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) {
|
int postfx_find(postfx *fx, const char *name) {
|
||||||
name = file_name(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;
|
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 ) {
|
int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
|
||||||
PRINTF("%s\n", name);
|
PRINTF("%s\n", name);
|
||||||
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
|
if(!fs || !fs[0]) return -1; // PANIC("!invalid fragment shader");
|
||||||
|
|
||||||
int slot = fx->num_loaded++;
|
passfx pass={0};
|
||||||
|
array_push(fx->pass, pass);
|
||||||
passfx *p = &fx->pass[ slot & 63 ];
|
passfx *p = array_back(fx->pass);
|
||||||
p->name = STRDUP(name);
|
p->name = STRDUP(name);
|
||||||
|
|
||||||
// preload stuff
|
// preload stuff
|
||||||
|
@ -19511,31 +19523,35 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) {
|
||||||
|
|
||||||
// set quad
|
// set quad
|
||||||
glGenVertexArrays(1, &p->m.vao);
|
glGenVertexArrays(1, &p->m.vao);
|
||||||
return slot;
|
return array_count(fx->pass)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_enable(postfx *fx, int pass, bool enabled) {
|
bool postfx_enable(postfx *fx, int pass, bool enabled) {
|
||||||
if( pass < 0 ) return false;
|
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
|
||||||
fx->mask = enabled ? fx->mask | (1ull << pass) : fx->mask & ~(1ull << pass);
|
fx->pass[pass].enabled = enabled;
|
||||||
fx->enabled = !!popcnt64(fx->mask);
|
fx->enabled = !!array_count(fx->pass);
|
||||||
return fx->enabled;
|
return fx->enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_enabled(postfx *fx, int pass) {
|
bool postfx_enabled(postfx *fx, int pass) {
|
||||||
if( pass < 0 ) return false;
|
if( pass < 0 || pass >= array_count(fx->pass) ) return false;
|
||||||
return (!!(fx->mask & (1ull << pass)));
|
return fx->pass[pass].enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_toggle(postfx *fx, int pass) {
|
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));
|
return postfx_enable(fx, pass, 1 ^ postfx_enabled(fx, pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
void postfx_clear(postfx *fx) {
|
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) {
|
int ui_postfx(postfx *fx, int pass) {
|
||||||
|
if (pass < 0 || pass >= array_count(fx->pass)) return 0;
|
||||||
int on = ui_enabled();
|
int on = ui_enabled();
|
||||||
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
|
( postfx_enabled(fx,pass) ? ui_enable : ui_disable )();
|
||||||
int rc = ui_shader(fx->pass[pass].program);
|
int rc = ui_shader(fx->pass[pass].program);
|
||||||
|
@ -19543,6 +19559,15 @@ int ui_postfx(postfx *fx, int pass) {
|
||||||
return rc;
|
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) {
|
bool postfx_begin(postfx *fx, int width, int height) {
|
||||||
// reset clear color: needed in case transparent window is being used (alpha != 0)
|
// reset clear color: needed in case transparent window is being used (alpha != 0)
|
||||||
glClearColor(0,0,0,0); // @transparent
|
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);
|
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;
|
bool active = fx->enabled && num_active_passes;
|
||||||
if( !active ) {
|
if( !active ) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -19590,7 +19615,7 @@ bool postfx_begin(postfx *fx, int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool postfx_end(postfx *fx) {
|
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;
|
bool active = fx->enabled && num_active_passes;
|
||||||
if( !active ) {
|
if( !active ) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -19610,10 +19635,9 @@ bool postfx_end(postfx *fx) {
|
||||||
float mx = input(MOUSE_X);
|
float mx = input(MOUSE_X);
|
||||||
float my = input(MOUSE_Y);
|
float my = input(MOUSE_Y);
|
||||||
|
|
||||||
for(int i = 0, e = countof(fx->pass); i < e; ++i) {
|
for(int i = 0, e = array_count(fx->pass); i < e; ++i) {
|
||||||
if( fx->mask & (1ull << i) ) {
|
passfx *pass = &fx->pass[i];
|
||||||
passfx *pass = &fx->pass[i];
|
if( pass->enabled ) {
|
||||||
|
|
||||||
if( !pass->program ) { --num_active_passes; continue; }
|
if( !pass->program ) { --num_active_passes; continue; }
|
||||||
glUseProgram(pass->program);
|
glUseProgram(pass->program);
|
||||||
|
|
||||||
|
@ -19711,6 +19735,9 @@ char *fx_name(int pass) {
|
||||||
int fx_find(const char *name) {
|
int fx_find(const char *name) {
|
||||||
return postfx_find(&fx, name);
|
return postfx_find(&fx, name);
|
||||||
}
|
}
|
||||||
|
void fx_order(int pass, unsigned priority) {
|
||||||
|
postfx_order(&fx, pass, priority);
|
||||||
|
}
|
||||||
int ui_fx(int pass) {
|
int ui_fx(int pass) {
|
||||||
return ui_postfx(&fx, pass);
|
return ui_postfx(&fx, pass);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3741,6 +3741,7 @@ API int fx_enabled(int pass);
|
||||||
API void fx_enable_all(int enabled);
|
API void fx_enable_all(int enabled);
|
||||||
API char * fx_name(int pass);
|
API char * fx_name(int pass);
|
||||||
API int fx_find(const char *name);
|
API int fx_find(const char *name);
|
||||||
|
API void fx_order(int pass, unsigned priority);
|
||||||
|
|
||||||
API int ui_fx(int pass);
|
API int ui_fx(int pass);
|
||||||
API int ui_fxs();
|
API int ui_fxs();
|
||||||
|
|
Loading…
Reference in New Issue