From e437dcabe2a1c81ce725905ff37b12b01d225009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Mon, 25 Sep 2023 06:29:29 +0200 Subject: [PATCH] sync to FWK new: FX params exposed automatically (int,float,vec2/3/4,color3/4), set/min/max/tooltips new: atof2/3/4, ftoa2/3/4, swapf2/3/4, clamp2/3/4 lab: shader reflection API brk: changed ui_enable() signature; renamed clamp234->clamp234f --- demos/02-ddraw.c | 1 + demos/03-anims.c | 28 +- demos/07-network.c | 11 - demos/99-bt.c | 1 - demos/99-pathfind.c | 5 +- demos/99-pbr.c | 9 +- demos/99-sprite.c | 10 +- demos/99-temperature.c | 1 - demos/art/fx/fxAberration.fs | 4 +- demos/art/fx/fxBloom.fs | 2 +- demos/art/fx/fxBlur.fs | 4 +- demos/art/fx/fxColorblind.fs | 8 +- demos/art/fx/fxContrast.fs | 4 +- demos/art/fx/fxDissolve.fs | 2 +- demos/art/fx/fxGrain.fs | 2 +- demos/art/fx/fxHSV.fs | 6 +- demos/art/fx/fxLetterbox.fs | 3 +- demos/art/fx/fxOutline.fs | 4 +- demos/art/fx/fxPixelate.fs | 7 +- demos/art/fx/fxQuantize.fs | 2 +- demos/art/fx/fxScanlines.fs | 4 +- demos/art/fx/fxScreenSpaceDither.fs | 2 +- demos/art/fx/fxSepia.fs | 2 +- demos/art/fx/fxSharpen.fs | 2 +- demos/art/fx/fxTonemapExposure.fs | 2 +- demos/art/fx/fxTonemapZZGamma.fs | 2 +- demos/art/fx/fxVignette.fs | 4 +- engine/bind/v4k.lua | 144 ++++++++-- engine/joint/v4k.h | 402 +++++++++++++++++++--------- engine/split/v4k_file.c | 7 +- engine/split/v4k_math.c | 57 +++- engine/split/v4k_math.h | 26 +- engine/split/v4k_render.c | 162 ++++++++++- engine/split/v4k_render.h | 15 +- engine/split/v4k_renderdd.c | 8 +- engine/split/v4k_system.c | 6 +- engine/split/v4k_system.h | 2 +- engine/split/v4k_ui.c | 113 ++------ engine/split/v4k_ui.h | 4 +- engine/split/v4k_window.c | 2 + engine/v4k.c | 355 +++++++++++++++--------- engine/v4k.h | 47 +++- tools/cook.ini | 2 +- 43 files changed, 999 insertions(+), 485 deletions(-) diff --git a/demos/02-ddraw.c b/demos/02-ddraw.c index 51c6064..501a517 100644 --- a/demos/02-ddraw.c +++ b/demos/02-ddraw.c @@ -111,6 +111,7 @@ int main() { char *name = fx_name(i); if( !name ) break; bool b = fx_enabled(i); if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1); + ui_fx(i); } ui_panel_end(); } diff --git a/demos/03-anims.c b/demos/03-anims.c index d4a6574..a8b5b33 100644 --- a/demos/03-anims.c +++ b/demos/03-anims.c @@ -10,6 +10,8 @@ #include "v4k.h" +array(mat44) M; // instanced transforms + int main() { bool do_showaabb = 0; bool do_showbones = 0; @@ -22,8 +24,20 @@ int main() { camera_t cam = camera(); skybox_t sky = skybox("cubemaps/stardust", 0); - model_t mdl = model("Stan.fbx", MODEL_RIMLIGHT); - anims_t a = animations("Stan.fbx", 0); + model_t mdl = model("George.fbx", MODEL_RIMLIGHT); // kgirls01.fbx + anims_t a = animations("George.fbx", 0); // kgirl/animlist.txt + + // 32*32 max instances + int NUM_INSTANCES = 1; + array_resize(M, 32*32); + for(int z = 0, i = 0; z < 32; ++z) { + for(int x = 0; x < 32; ++x, ++i) { + vec3 p = vec3(-x*9,0,-z*9); + vec3 r = vec3(0,-90,0); // kgirl: 0,0,0 + vec3 s = vec3(2,2,2); + compose44(M[i], p, eulerq(r), s); + } + } // shader_bind(mdl.program); // shader_vec3("u_rimcolor", vec3(0.12,0.23,0.34)); @@ -74,12 +88,12 @@ int main() { // characters profile("Skeletal render") { - if( do_showmodel ) model_render(mdl, cam.proj, cam.view, mdl.pivot, 0); + if( do_showmodel ) model_render_instanced(mdl, cam.proj, cam.view, M /*mdl.pivot*/, 0, NUM_INSTANCES); - if( do_showbones ) model_render_skeleton(mdl, mdl.pivot); + if( do_showbones ) model_render_skeleton(mdl, M[0] /*mdl.pivot*/); if( do_showaabb ) { - aabb box = model_aabb(mdl, mdl.pivot); + aabb box = model_aabb(mdl, M[0] /*mdl.pivot*/); ddraw_aabb(box.min, box.max); } @@ -97,6 +111,9 @@ int main() { if( ui_bool("Show bones", &do_showbones) ); if( ui_bool("Show models", &do_showmodel) ); if( ui_bool("Show gizmo", &do_showgizmo) ); + + ui_separator(); + if( ui_int("Instances", &NUM_INSTANCES)) NUM_INSTANCES = clampi(NUM_INSTANCES, 1, array_count(M)); ui_separator(); ui_label(va("Anim %s [%d.. %.2f ..%d]", a.anims[ a.inuse ].name, anim.min, mdl.curframe, anim.max )); @@ -155,6 +172,7 @@ int main() { char *name = fx_name(i); if( !name ) break; bool b = fx_enabled(i); if( ui_bool(name, &b) ) fx_enable(i, b); + ui_fx(i); } ui_panel_end(); } diff --git a/demos/07-network.c b/demos/07-network.c index ee5e453..f84e841 100644 --- a/demos/07-network.c +++ b/demos/07-network.c @@ -75,14 +75,3 @@ int main() { // https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-demo.c // https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-script.c // https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-socket.c - -#if 0 // teal - script_run("local tl=require(\"tl\")\ntl.loader()"); - script_run("addsub = require(\"s2\"); print (addsub.add(10, 20))"); -s2.tl: - local function add(a: number, b: number): number - return a + b - end - local s = add(1,2) - print(s) -#endif diff --git a/demos/99-bt.c b/demos/99-bt.c index 56a56db..6657543 100644 --- a/demos/99-bt.c +++ b/demos/99-bt.c @@ -1,4 +1,3 @@ -#define COOK_ON_DEMAND 1 #include "v4k.h" int yes() { diff --git a/demos/99-pathfind.c b/demos/99-pathfind.c index d0f1e0c..cace76b 100644 --- a/demos/99-pathfind.c +++ b/demos/99-pathfind.c @@ -1,8 +1,5 @@ -#define COOK_ON_DEMAND 1 #include "v4k.h" -#define min(a,b) (a>b?b:a) - bool topdown_cam = 1; void move_players(); @@ -56,7 +53,7 @@ void draw_scene() { for( int y = oz; y < (oz+dd); ++y ) for( int x = ox; x < (ox+ww); ++x ) - chunk[ (x + W/2) + min(y + Z/2, Z-1) * W ] |= 1; + chunk[ (x + W/2) + mini(y + Z/2, Z-1) * W ] |= 1; } ddraw_color(BLUE); diff --git a/demos/99-pbr.c b/demos/99-pbr.c index a98a770..f8214fc 100644 --- a/demos/99-pbr.c +++ b/demos/99-pbr.c @@ -193,8 +193,8 @@ void ModelRender( Model *G, const mat44 _worldRootMatrix ) { for( int i = 0, end = array_count(G->meshes); i < end; i++ ) { const Mesh *mesh = &G->meshes[ i ]; // Postpone rendering transparent meshes - // if(mesh->transparent != bTransparentPass) - // continue; + if(mesh->transparent != bTransparentPass) + continue; const pbr_material_t *material = &G->materials[ mesh->material_idx ]; shader_colormap( "map_diffuse", material->diffuse ); @@ -363,7 +363,7 @@ unsigned gShader = ~0u; unsigned gShaderConfig = ~0u; bool LoadShaderConfig( int slot ) { // name,vs,fs - unsigned newShader = shader( vfs_read(shaders[slot][0]), vfs_read(shaders[slot][1]), NULL, NULL , ""); + unsigned newShader = shader( vfs_read(shaders[slot][0]), vfs_read(shaders[slot][1]), NULL, NULL, NULL ); if( newShader == ~0u ) return false; shader_destroy( gShader ); @@ -418,7 +418,7 @@ int main( int argc, const char *argv[] ) { lightYaw = g_skybox.sunYaw; lightPitch = g_skybox.sunPitch; - unsigned skysphereShader = shader( vfs_read("Skyboxes/skysphere.vs"), vfs_read("Skyboxes/skysphere.fs"), NULL, NULL , ""); + unsigned skysphereShader = shader( vfs_read("Skyboxes/skysphere.vs"), vfs_read("Skyboxes/skysphere.fs"), NULL, NULL, NULL ); Model skysphere = { 0 }; ModelLoad(&skysphere, "Skyboxes/skysphere.fbx"); ModelRebind(&skysphere, skysphereShader); if( ModelLoad( &gModel, argc > 1 && argv[1][0] != '-' ? argv[ 1 ] : "damagedhelmet.gltf" ) ) { @@ -653,6 +653,7 @@ int main( int argc, const char *argv[] ) { char *name = fx_name(i); if( !name ) break; bool b = fx_enabled(i); if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1); + ui_fx(i); } ui_panel_end(); } diff --git a/demos/99-sprite.c b/demos/99-sprite.c index b4aa285..a3da64b 100644 --- a/demos/99-sprite.c +++ b/demos/99-sprite.c @@ -142,6 +142,7 @@ void demo_kids() { int main(int argc, char **argv) { window_create(75.f, 0); window_title("V4K - Sprite"); + window_color( SILVER ); // options int do_cats = 1; @@ -154,10 +155,8 @@ int main(int argc, char **argv) { shadowImage = texture( "cat-shadow.png", TEXTURE_LINEAR ); inputs = texture( "prompts_tilemap_34x24_16x16x1.png", TEXTURE_LINEAR ); - // load all post fx files - for(const char **list = file_list("./","fx**.fs"); *list; list++) { - fx_load(*list); - } + // load all fx files, including subdirs + fx_load("fx**.fs"); // init camera (x,y) (z = zoom) camera_t cam = camera(); @@ -169,8 +168,6 @@ int main(int argc, char **argv) { if( input(KEY_F11)) window_fullscreen( window_has_fullscreen() ^ 1); if( input(KEY_ESC) ) break; - viewport_color3(vec3(0.4,0.4,0.4)); - // camera panning (x,y) & zooming (z) if( !ui_hover() && !ui_active() ) { if( input(MOUSE_L) ) cam.position.x -= input_diff(MOUSE_X); @@ -222,6 +219,7 @@ int main(int argc, char **argv) { char *name = fx_name(i); if( !name ) break; bool b = fx_enabled(i); if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1); + ui_fx(i); } ui_panel_end(); } diff --git a/demos/99-temperature.c b/demos/99-temperature.c index d374162..c2e3d93 100644 --- a/demos/99-temperature.c +++ b/demos/99-temperature.c @@ -1,4 +1,3 @@ -#define COOK_ON_DEMAND 1 #include "v4k.h" int TEMP_GPU = 1; diff --git a/demos/art/fx/fxAberration.fs b/demos/art/fx/fxAberration.fs index c1e60c2..3d3c498 100644 --- a/demos/art/fx/fxAberration.fs +++ b/demos/art/fx/fxAberration.fs @@ -1,5 +1,5 @@ -uniform float intensity = 0.003f; -uniform float angle = 0.0f; +uniform float intensity = 0.003f; /// min:0.001 max:0.10 set:0.003 +uniform float angle = 0.0f; /// min:0 max:6.28 set:0 void main() { vec2 uv = TEXCOORD.st; diff --git a/demos/art/fx/fxBloom.fs b/demos/art/fx/fxBloom.fs index 7fd83f7..dc4e07e 100644 --- a/demos/art/fx/fxBloom.fs +++ b/demos/art/fx/fxBloom.fs @@ -1,4 +1,4 @@ -uniform float intensity = 2.0; +uniform float intensity = 2.0; /// set:2.0 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; diff --git a/demos/art/fx/fxBlur.fs b/demos/art/fx/fxBlur.fs index f836971..bf59569 100644 --- a/demos/art/fx/fxBlur.fs +++ b/demos/art/fx/fxBlur.fs @@ -1,7 +1,7 @@ // [ref] https://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ -uniform float intensity = 4; -uniform vec2 direction = vec2(1.0, 0.0); +uniform float intensity = 4; /// set:4 +uniform vec2 direction = vec2(1.0, 0.0); /// set:1,0 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; diff --git a/demos/art/fx/fxColorblind.fs b/demos/art/fx/fxColorblind.fs index 61a71ea..aabc31f 100644 --- a/demos/art/fx/fxColorblind.fs +++ b/demos/art/fx/fxColorblind.fs @@ -1,20 +1,20 @@ // [ref] https://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulation.html -uniform int colorblind_mode = 2; // [0..4] +uniform int colorblind_mode = 2; /// min:0 max:4 set:2 tip:"off, achromatopsia, protanomaly, deuteranomaly, tritanomaly" uniform mat3 colorblind_matrices[5] = mat3[5]( mat3(1.000,0.000,0.000, 0.000,1.000,0.000, 0.000,0.000,1.000), // 0 no colorblind mat3(0.299,0.587,0.114, 0.299,0.587,0.114, 0.299,0.587,0.114), // 1 achromatopsia (luma) - mat3( // protanomaly (no red cone) + mat3( // 2 protanomaly (no red cone) 0.152286, 1.052583,-0.204868, 0.114503, 0.786281, 0.099216, -0.003882,-0.048116, 1.051998 ), - mat3( // deuteranomaly (no green cone) + mat3( // 3 deuteranomaly (no green cone) 0.367322, 0.860646, -0.227968, 0.280085, 0.672501, 0.047413, -0.011820, 0.042940, 0.968881 ), - mat3( // tritanomaly (no blue cone) + mat3( // 4 tritanomaly (no blue cone) 1.255528,-0.076749,-0.178779, -0.078411, 0.930809, 0.147602, 0.004733, 0.691367, 0.303900 diff --git a/demos/art/fx/fxContrast.fs b/demos/art/fx/fxContrast.fs index 61f29ce..0489b72 100644 --- a/demos/art/fx/fxContrast.fs +++ b/demos/art/fx/fxContrast.fs @@ -1,5 +1,5 @@ -uniform float contrast = 1.5; // > 1 to saturate, < 1 to bleach-to-gray -uniform float brightness = 0; +uniform float contrast = 1.5; /// set:1.5 tip:"bleach-to-gray < 1 > saturate" +uniform float brightness = 0; /// set:0 max:2 void main() { vec4 pixelColor = texture(iChannel0, TEXCOORD.st); diff --git a/demos/art/fx/fxDissolve.fs b/demos/art/fx/fxDissolve.fs index 62d53d5..fdbe96e 100644 --- a/demos/art/fx/fxDissolve.fs +++ b/demos/art/fx/fxDissolve.fs @@ -1,4 +1,4 @@ -uniform float intensity = 0.004; +uniform float intensity = 0.004; /// set:0.004 max:0.03 highp float rand(vec2 co) { highp float a = 12.9898; diff --git a/demos/art/fx/fxGrain.fs b/demos/art/fx/fxGrain.fs index 105b0d3..dd044a0 100644 --- a/demos/art/fx/fxGrain.fs +++ b/demos/art/fx/fxGrain.fs @@ -1,4 +1,4 @@ -uniform float intensity = 16.0; +uniform float intensity = 16.0; /// set:16 max:32 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; diff --git a/demos/art/fx/fxHSV.fs b/demos/art/fx/fxHSV.fs index db98dfc..3b49422 100644 --- a/demos/art/fx/fxHSV.fs +++ b/demos/art/fx/fxHSV.fs @@ -1,6 +1,6 @@ -uniform float h = 1.0; // tint shift -uniform float s = 0.5; // saturate: >1, decolorize: <1 -uniform float v = 1.0; // white: >1, gray: <1 +uniform float h = 1.0; /// set:1.0 tip:"hue color shift" +uniform float s = 0.5; /// set:0.5 tip:"gray: <1, saturate: >1" +uniform float v = 1.0; /// set:1.0 tip:"black: <1, white: >1" vec3 hsv2rgb(vec3 c) { return mix(vec3(1.),clamp((abs(fract(c.r+vec3(3.,2.,1.)/3.)*6.-3.)-1.),0.,1.),c.g)*c.b; diff --git a/demos/art/fx/fxLetterbox.fs b/demos/art/fx/fxLetterbox.fs index 85fff18..bbf5897 100644 --- a/demos/art/fx/fxLetterbox.fs +++ b/demos/art/fx/fxLetterbox.fs @@ -1,5 +1,4 @@ -void mainImage( out vec4 fragColor, in vec2 fragCoord ) -{ +void mainImage( out vec4 fragColor, in vec2 fragCoord ) { // letterbox if( abs(2.*fragCoord.y-iResolution.y) > iResolution.x * 0.42 ) { fragColor = vec4( 0., 0., 0., 1. ); diff --git a/demos/art/fx/fxOutline.fs b/demos/art/fx/fxOutline.fs index 9f2c8f7..6f66d91 100644 --- a/demos/art/fx/fxOutline.fs +++ b/demos/art/fx/fxOutline.fs @@ -1,5 +1,5 @@ -uniform int thickness = 2; -uniform vec4 border_color = vec4(1,1,0,1); +uniform int thickness = 2; /// set:2 +uniform vec4 border_color = vec4(1,1,0,1); /// set:1,1,0,1 void main() { vec4 texel = texture(iChannel0, uv); diff --git a/demos/art/fx/fxPixelate.fs b/demos/art/fx/fxPixelate.fs index 751eeec..67c4a53 100644 --- a/demos/art/fx/fxPixelate.fs +++ b/demos/art/fx/fxPixelate.fs @@ -1,8 +1,9 @@ -uniform float xCellSize = 2.5; -uniform float yCellSize = 2.5; +uniform float CellSize = 2.5; /// min:1 set:2.5 max:16 +//uniform float xCellSize = 2.5; /// min:1 set:2.5 +//uniform float yCellSize = 2.5; /// min:1 set:2.5 void main() { - float xPixels = iWidth/xCellSize, yPixels = iHeight/yCellSize; + float xPixels = iWidth/CellSize, yPixels = iHeight/CellSize; // iWidth/xCellSize, iHeight/yCellSize; vec2 uv = vec2(floor(texcoord.s * xPixels) / xPixels, floor(texcoord.t * yPixels) / yPixels); FRAGCOLOR = texture(iChannel0, uv); } diff --git a/demos/art/fx/fxQuantize.fs b/demos/art/fx/fxQuantize.fs index 716ea58..a17b08c 100644 --- a/demos/art/fx/fxQuantize.fs +++ b/demos/art/fx/fxQuantize.fs @@ -1,4 +1,4 @@ -uniform float factor = 3.0; // [1(max)..255(min)] +uniform float factor = 3.0; /// min:1 max:255 set:3 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; diff --git a/demos/art/fx/fxScanlines.fs b/demos/art/fx/fxScanlines.fs index a7443b0..ff2cdf3 100644 --- a/demos/art/fx/fxScanlines.fs +++ b/demos/art/fx/fxScanlines.fs @@ -1,5 +1,5 @@ -uniform float hardness = 0.1; -uniform float flickering = 0.01; +uniform float hardness = 0.1; /// set:0.1 max:2 +uniform float flickering = 0.01; /// set:0.01 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; diff --git a/demos/art/fx/fxScreenSpaceDither.fs b/demos/art/fx/fxScreenSpaceDither.fs index 461a1c1..996c8a7 100644 --- a/demos/art/fx/fxScreenSpaceDither.fs +++ b/demos/art/fx/fxScreenSpaceDither.fs @@ -5,7 +5,7 @@ // note: valve edition from http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf // note: input in pixels (ie not normalized uv) -uniform float intensity = 250.0; // [2..255] +uniform float intensity = 250.0; /// min:245 max:255 set:250 vec3 ScreenSpaceDither2(vec2 vScreenPos, float colorDepth) { // lestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR diff --git a/demos/art/fx/fxSepia.fs b/demos/art/fx/fxSepia.fs index fe80b6f..8bd23d3 100644 --- a/demos/art/fx/fxSepia.fs +++ b/demos/art/fx/fxSepia.fs @@ -1,4 +1,4 @@ -uniform float intensity = 1.0; +uniform float intensity = 1.0; /// set:1 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; diff --git a/demos/art/fx/fxSharpen.fs b/demos/art/fx/fxSharpen.fs index ce6d926..41debf1 100644 --- a/demos/art/fx/fxSharpen.fs +++ b/demos/art/fx/fxSharpen.fs @@ -1,4 +1,4 @@ -uniform float intensity = 1.0; +uniform float intensity = 0.25; /// set:0.25 max:2 void mainImage( out vec4 fragColor, in vec2 fragCoord ){ vec2 uv = fragCoord / iResolution.xy; diff --git a/demos/art/fx/fxTonemapExposure.fs b/demos/art/fx/fxTonemapExposure.fs index cd3381b..6f213fe 100644 --- a/demos/art/fx/fxTonemapExposure.fs +++ b/demos/art/fx/fxTonemapExposure.fs @@ -1,7 +1,7 @@ // exposure tone mapping // https://learnopengl.com/Advanced-Lighting/HDR -uniform float exposure = 1.0; // [0.1 .. 5] +uniform float exposure = 1.0; // min:0.1 max:5 set:1 out vec4 color; diff --git a/demos/art/fx/fxTonemapZZGamma.fs b/demos/art/fx/fxTonemapZZGamma.fs index b3545a8..b210514 100644 --- a/demos/art/fx/fxTonemapZZGamma.fs +++ b/demos/art/fx/fxTonemapZZGamma.fs @@ -1,4 +1,4 @@ -uniform float gamma = 2.2; +uniform float gamma = 2.2; /// set:2.2 out vec4 color; void main(void) { diff --git a/demos/art/fx/fxVignette.fs b/demos/art/fx/fxVignette.fs index 9d05359..10d17a7 100644 --- a/demos/art/fx/fxVignette.fs +++ b/demos/art/fx/fxVignette.fs @@ -1,4 +1,4 @@ -uniform float vignette = 0.75; +uniform float radius = 0.75; /// set:0.75 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; @@ -6,7 +6,7 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec4 src = texture( iChannel0, uv ); vec3 color = src.rgb; - color *= (1.0 - vignette) + vignette * 16.0 * uv.x * uv.y * (1.0-uv.x) * (1.0-uv.y); + color *= (1.0 - radius) + radius * 16.0 * uv.x * uv.y * (1.0-uv.x) * (1.0-uv.y); fragColor = vec4(color, src.a); } diff --git a/engine/bind/v4k.lua b/engine/bind/v4k.lua index fadf326..c55ae26 100644 --- a/engine/bind/v4k.lua +++ b/engine/bind/v4k.lua @@ -300,12 +300,24 @@ ffi.cdef([[ //lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 mix2 (vec2 a,vec2 b,float t); //lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 mix2 (vec2 a,vec2 b,float t); //lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 mix2 (vec2 a,vec2 b,float t); -//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 clamp2(vec2 v,float a,float b); -//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 clamp2(vec2 v,float a,float b); -//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 clamp2(vec2 v,float a,float b); -//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 clamp2(vec2 v,float a,float b); -//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 clamp2(vec2 v,float a,float b); -//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 clamp2(vec2 v,float a,float b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 clamp2(vec2 v,vec2 a,vec2 b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 clamp2f(vec2 v,float a,float b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 clamp2f(vec2 v,float a,float b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 clamp2f(vec2 v,float a,float b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 clamp2f(vec2 v,float a,float b); +//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 clamp2f(vec2 v,float a,float b); +//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 clamp2f(vec2 v,float a,float b); //lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 rnd3 (void); //lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 rnd3 (void); //lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 rnd3 (void); @@ -480,12 +492,24 @@ ffi.cdef([[ //lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 mix3 (vec3 a,vec3 b,float t); //lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 mix3 (vec3 a,vec3 b,float t); //lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 mix3 (vec3 a,vec3 b,float t); -//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 clamp3(vec3 v,float a,float b); -//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 clamp3(vec3 v,float a,float b); -//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 clamp3(vec3 v,float a,float b); -//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 clamp3(vec3 v,float a,float b); -//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 clamp3(vec3 v,float a,float b); -//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 clamp3(vec3 v,float a,float b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 clamp3(vec3 v,vec3 a,vec3 b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 clamp3f(vec3 v,float a,float b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 clamp3f(vec3 v,float a,float b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 clamp3f(vec3 v,float a,float b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 clamp3f(vec3 v,float a,float b); +//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 clamp3f(vec3 v,float a,float b); +//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 clamp3f(vec3 v,float a,float b); //lcpp INF [0000] vec3: macro name but used as C declaration in:API void ortho3 (vec3 *left, vec3 *up, vec3 v); //lcpp INF [0000] vec3: macro name but used as C declaration in:API void ortho3 (vec3 *left, vec3 *up, vec3 v); //lcpp INF [0000] vec3: macro name but used as C declaration in:API void ortho3 (vec3 *left, vec3 *up, vec3 v); @@ -675,12 +699,24 @@ ffi.cdef([[ //lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 mix4 (vec4 a,vec4 b,float t); //lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 mix4 (vec4 a,vec4 b,float t); //lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 mix4 (vec4 a,vec4 b,float t); -//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 clamp4(vec4 v,float a,float b); -//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 clamp4(vec4 v,float a,float b); -//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 clamp4(vec4 v,float a,float b); -//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 clamp4(vec4 v,float a,float b); -//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 clamp4(vec4 v,float a,float b); -//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 clamp4(vec4 v,float a,float b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 clamp4(vec4 v,vec4 a,vec4 b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 clamp4f(vec4 v,float a,float b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 clamp4f(vec4 v,float a,float b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 clamp4f(vec4 v,float a,float b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 clamp4f(vec4 v,float a,float b); +//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 clamp4f(vec4 v,float a,float b); +//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 clamp4f(vec4 v,float a,float b); //lcpp INF [0000] quat: macro name but used as C declaration in:API quat idq ( ); //lcpp INF [0000] quat: macro name but used as C declaration in:STATIC quat idq ( ); //lcpp INF [0000] quat: macro name but used as C declaration in: quat idq ( ); @@ -903,6 +939,42 @@ ffi.cdef([[ //lcpp INF [0000] quat: macro name but used as C declaration in:API void printq( quat q ); //lcpp INF [0000] quat: macro name but used as C declaration in:STATIC void printq( quat q ); //lcpp INF [0000] quat: macro name but used as C declaration in: void printq( quat q ); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 atof2(const char *s); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 atof2(const char *s); +//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 atof2(const char *s); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 atof3(const char *s); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 atof3(const char *s); +//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 atof3(const char *s); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 atof4(const char *s); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 atof4(const char *s); +//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 atof4(const char *s); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API char* ftoa2(vec2 v); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC char* ftoa2(vec2 v); +//lcpp INF [0000] vec2: macro name but used as C declaration in: char* ftoa2(vec2 v); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API char* ftoa3(vec3 v); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC char* ftoa3(vec3 v); +//lcpp INF [0000] vec3: macro name but used as C declaration in: char* ftoa3(vec3 v); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API char* ftoa4(vec4 v); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC char* ftoa4(vec4 v); +//lcpp INF [0000] vec4: macro name but used as C declaration in: char* ftoa4(vec4 v); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API void swapf2(vec2 *a, vec2 *b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API void swapf2(vec2 *a, vec2 *b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC void swapf2(vec2 *a, vec2 *b); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC void swapf2(vec2 *a, vec2 *b); +//lcpp INF [0000] vec2: macro name but used as C declaration in: void swapf2(vec2 *a, vec2 *b); +//lcpp INF [0000] vec2: macro name but used as C declaration in: void swapf2(vec2 *a, vec2 *b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API void swapf3(vec3 *a, vec3 *b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API void swapf3(vec3 *a, vec3 *b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void swapf3(vec3 *a, vec3 *b); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void swapf3(vec3 *a, vec3 *b); +//lcpp INF [0000] vec3: macro name but used as C declaration in: void swapf3(vec3 *a, vec3 *b); +//lcpp INF [0000] vec3: macro name but used as C declaration in: void swapf3(vec3 *a, vec3 *b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API void swapf4(vec4 *a, vec4 *b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API void swapf4(vec4 *a, vec4 *b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void swapf4(vec4 *a, vec4 *b); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void swapf4(vec4 *a, vec4 *b); +//lcpp INF [0000] vec4: macro name but used as C declaration in: void swapf4(vec4 *a, vec4 *b); +//lcpp INF [0000] vec4: macro name but used as C declaration in: void swapf4(vec4 *a, vec4 *b); //lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 position; //lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 velocity; //lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 acceleration; @@ -1196,9 +1268,6 @@ ffi.cdef([[ //lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength); //lcpp INF [0000] vec3: macro name but used as C declaration in: void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength); //lcpp INF [0000] vec3: macro name but used as C declaration in: void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength); -//lcpp INF [0000] vec3: macro name but used as C declaration in:API void viewport_color3(vec3 color); -//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void viewport_color3(vec3 color); -//lcpp INF [0000] vec3: macro name but used as C declaration in: void viewport_color3(vec3 color); //lcpp INF [0000] vec2: macro name but used as C declaration in:API void viewport_clip(vec2 from, vec2 to); //lcpp INF [0000] vec2: macro name but used as C declaration in:API void viewport_clip(vec2 from, vec2 to); //lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC void viewport_clip(vec2 from, vec2 to); @@ -1589,7 +1658,8 @@ EASE_OUT = 0, vec2 norm2 (vec2 a ); int finite2 (vec2 a ); vec2 mix2 (vec2 a,vec2 b,float t); - vec2 clamp2(vec2 v,float a,float b); + vec2 clamp2(vec2 v,vec2 a,vec2 b); + vec2 clamp2f(vec2 v,float a,float b); vec3 rnd3 (void); vec3 ptr3 (const float *a ); vec3 vec23 (vec2 a, float z ); @@ -1617,7 +1687,8 @@ EASE_OUT = 0, vec3 norm3sq (vec3 a ); int finite3 (vec3 a ); vec3 mix3 (vec3 a,vec3 b,float t); - vec3 clamp3(vec3 v,float a,float b); + vec3 clamp3(vec3 v,vec3 a,vec3 b); + vec3 clamp3f(vec3 v,float a,float b); void ortho3 (vec3 *left, vec3 *up, vec3 v); vec3 rotatex3 (vec3 dir, float degrees); vec3 rotatey3 (vec3 dir, float degrees); @@ -1647,7 +1718,8 @@ EASE_OUT = 0, vec4 norm4sq (vec4 a ); int finite4 (vec4 a ); vec4 mix4 (vec4 a,vec4 b,float t); - vec4 clamp4(vec4 v,float a,float b); + vec4 clamp4(vec4 v,vec4 a,vec4 b); + vec4 clamp4f(vec4 v,float a,float b); quat idq ( ); quat ptrq (const float *a ); quat vec3q (vec3 a, float w ); @@ -1725,6 +1797,17 @@ EASE_OUT = 0, void print33( float *m ); void print34( float *m ); void print44( float *m ); + vec2 atof2(const char *s); + vec3 atof3(const char *s); + vec4 atof4(const char *s); + char* ftoa(float f); + char* ftoa2(vec2 v); + char* ftoa3(vec3 v); + char* ftoa4(vec4 v); + void swapf(float *a, float *b); + void swapf2(vec2 *a, vec2 *b); + void swapf3(vec3 *a, vec3 *b); + void swapf4(vec4 *a, vec4 *b); typedef enum SWARM_DISTANCE { SWARM_DISTANCE_LINEAR, SWARM_DISTANCE_INVERSE_LINEAR, @@ -2405,6 +2488,10 @@ int texture_width; void shader_colormap(const char *name, colormap_t cm); unsigned shader_get_active(); void shader_destroy(unsigned shader); + unsigned shader_properties(unsigned shader); + char** shader_property(unsigned shader, unsigned property_no); + int ui_shader(unsigned shader); + int ui_shaders(); enum BUFFER_MODE { BUFFER_READ, BUFFER_WRITE, @@ -2589,8 +2676,6 @@ float *pixels; void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength); int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); int skybox_pop_state(); - void viewport_color(uint32_t color); - void viewport_color3(vec3 color); void viewport_clear(bool color, bool depth); void viewport_clip(vec2 from, vec2 to); int fx_load(const char *file); @@ -2603,6 +2688,7 @@ float *pixels; void fx_enable_all(int enabled); char * fx_name(int pass); int fx_find(const char *name); + int ui_fx(int pass); void* screenshot(int components); void* screenshot_async(int components); void ddraw_color(unsigned rgb); @@ -2789,7 +2875,7 @@ int u_coefficients_sh; void tty_attach(); void tty_detach(); const char* app_exec(const char *command); - void app_spawn(const char *command); + int app_spawn(const char *command); int app_cores(); int app_battery(); const char* app_name(); @@ -2909,8 +2995,8 @@ PANEL_OPEN = 1, int ui_show(const char *panel_or_window_title, int enabled); int ui_dims(const char *panel_or_window_title, float width, float height); int ui_visible(const char *panel_or_window_title); - int ui_enable(); - int ui_disable(); + int ui_enable(int on); + int ui_enabled(); vec2 ui_get_dims(); int ui_has_menubar(); int ui_menu(const char *items); diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index 23770d4..3c05d3d 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -14905,7 +14905,8 @@ API float len2 (vec2 a ); API vec2 norm2 (vec2 a ); API int finite2 (vec2 a ); API vec2 mix2 (vec2 a,vec2 b,float t); -API vec2 clamp2(vec2 v,float a,float b); +API vec2 clamp2(vec2 v,vec2 a,vec2 b); +API vec2 clamp2f(vec2 v,float a,float b); // ---------------------------------------------------------------------------- API vec3 rnd3 (void); // @todo: rnd2,rnd4,rndq @@ -14936,7 +14937,8 @@ API vec3 norm3 (vec3 a ); API vec3 norm3sq (vec3 a ); API int finite3 (vec3 a ); API vec3 mix3 (vec3 a,vec3 b,float t); -API vec3 clamp3(vec3 v,float a,float b); +API vec3 clamp3(vec3 v,vec3 a,vec3 b); +API vec3 clamp3f(vec3 v,float a,float b); //vec3 tricross3 (vec3 a, vec3 b, vec3 c); API void ortho3 (vec3 *left, vec3 *up, vec3 v); @@ -14972,7 +14974,8 @@ API vec4 norm4 (vec4 a ); API vec4 norm4sq (vec4 a ); API int finite4 (vec4 a ); API vec4 mix4 (vec4 a,vec4 b,float t); -API vec4 clamp4(vec4 v,float a,float b); +API vec4 clamp4(vec4 v,vec4 a,vec4 b); +API vec4 clamp4f(vec4 v,float a,float b); // vec4 cross4(vec4 v0, vec4 v1); // ---------------------------------------------------------------------------- @@ -15074,7 +15077,7 @@ API vec4 transform444(const mat44 m, const vec4 p); API bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp); // ---------------------------------------------------------------------------- -// !!! for debugging +// debugging and utils API void print2( vec2 v ); API void print3( vec3 v ); @@ -15083,6 +15086,21 @@ API void printq( quat q ); API void print33( float *m ); API void print34( float *m ); API void print44( float *m ); + +API vec2 atof2(const char *s); +API vec3 atof3(const char *s); +API vec4 atof4(const char *s); + +API char* ftoa(float f); +API char* ftoa2(vec2 v); +API char* ftoa3(vec3 v); +API char* ftoa4(vec4 v); + +API void swapf(float *a, float *b); +API void swapf2(vec2 *a, vec2 *b); +API void swapf3(vec3 *a, vec3 *b); +API void swapf4(vec4 *a, vec4 *b); + #line 0 @@ -16390,7 +16408,8 @@ API float alpha( unsigned rgba ); #define ORANGE RGB3( 255,144,48 ) #define PURPLE RGB3( 102,77,102 ) // 178,128,255 ) #define YELLOW RGB3( 255,224,0 ) -#define GRAY RGB3( 32, 32, 32 ) // 149,149,149 ) +#define GRAY RGB3( 32,32,32 ) // dark gray +#define SILVER RGB3( 149,149,149 ) // dark white, gray-ish #define PINK RGB3( 255,48,144 ) #define AQUA RGB3( 48,255,144 ) @@ -16687,6 +16706,14 @@ API void shader_colormap(const char *name, colormap_t cm); API unsigned shader_get_active(); API void shader_destroy(unsigned shader); +// reflection. [0..N] are shader properties + +API unsigned shader_properties(unsigned shader); +API char** shader_property(unsigned shader, unsigned property_no); + +API int ui_shader(unsigned shader); +API int ui_shaders(); + // compute shaders enum BUFFER_MODE { BUFFER_READ, @@ -17013,8 +17040,6 @@ API int skybox_pop_state(); // @to deprecate // ----------------------------------------------------------------------------- // post-fxs -API void viewport_color(uint32_t color); // background(uint32_t) instead? -API void viewport_color3(vec3 color); // background3(vec3) instead? API void viewport_clear(bool color, bool depth); API void viewport_clip(vec2 from, vec2 to); @@ -17029,6 +17054,8 @@ API void fx_enable_all(int enabled); API char * fx_name(int pass); API int fx_find(const char *name); +API int ui_fx(int pass); + // ----------------------------------------------------------------------------- // utils @@ -17352,7 +17379,7 @@ API void tty_attach(); API void tty_detach(); API const char* app_exec(const char *command); // returns ("%15d %s", retcode, output_last_line) -API void app_spawn(const char *command); +API int app_spawn(const char *command); API int app_cores(); API int app_battery(); /// return battery level [1..100]. also positive if charging (+), negative if discharging (-), and 0 if no battery is present. @@ -17496,8 +17523,8 @@ API int ui_window_end(); API int ui_show(const char *panel_or_window_title, int enabled); API int ui_dims(const char *panel_or_window_title, float width, float height); API int ui_visible(const char *panel_or_window_title); // @todo: include ui_collapse() items that are open as well? -API int ui_enable(); -API int ui_disable(); +API int ui_enable(int on); +API int ui_enabled(); API vec2 ui_get_dims(); API int ui_has_menubar(); @@ -334164,10 +334191,6 @@ const char *vfs_resolve(const char *pathfile) { return pathfile; } -#ifndef VFS_ALWAYS_PACK -#define VFS_ALWAYS_PACK flag("--vfs-always-pack") -#endif - char* vfs_load(const char *pathfile, int *size_out) { // @todo: fix leaks, vfs_unpack() // @fixme: handle \\?\ absolute path (win) if (!pathfile[0]) return file_load(pathfile, size_out); @@ -334239,7 +334262,8 @@ if( found && *found == 0 ) { ptr = vfs_unpack(pathfile, &size); // asset not found? maybe it has not been cooked yet at this point (see --cook-on-demand) - if( (!ptr && COOK_ON_DEMAND) || VFS_ALWAYS_PACK ) { + if( !ptr && COOK_ON_DEMAND ) { + static thread_mutex_t mutex, *init = 0; if(!init) thread_mutex_init(init = &mutex); thread_mutex_lock(&mutex); @@ -337593,6 +337617,54 @@ void input_demo() { #include #include +vec2 atof2(const char *s) { + vec2 v = {0}; + sscanf(s, "%f,%f", &v.x, &v.y); + return v; +} +vec3 atof3(const char *s) { + vec3 v = {0}; + sscanf(s, "%f,%f,%f", &v.x, &v.y, &v.z); + return v; +} +vec4 atof4(const char *s) { + vec4 v = {0}; + sscanf(s, "%f,%f,%f,%f", &v.x, &v.y, &v.z, &v.w); + return v; +} + +char* ftoa(float f) { + return va("%f", f); +} +char* ftoa2(vec2 v) { + return va("%f,%f", v.x, v.y); +} +char* ftoa3(vec3 v) { + return va("%f,%f,%f", v.x, v.y, v.z); +} +char* ftoa4(vec4 v) { + return va("%f,%f,%f,%f", v.x, v.y, v.z, v.w); +} + +void swapf(float *a, float *b) { + float t = *a; *a = *b; *b = *a; +} +void swapf2(vec2 *a, vec2 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; +} +void swapf3(vec3 *a, vec3 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; + float z = a->z; a->z = b->z; b->z = a->z; +} +void swapf4(vec4 *a, vec4 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; + float z = a->z; a->z = b->z; b->z = a->z; + float w = a->w; a->w = b->w; b->w = a->w; +} + static uint64_t rand_xoro256(uint64_t x256_s[4]) { // xoshiro256+ 1.0 by David Blackman and Sebastiano Vigna (PD) const uint64_t result = x256_s[0] + x256_s[3]; const uint64_t t = x256_s[1] << 17; @@ -337790,7 +337862,8 @@ vec2 norm2 (vec2 a ) { return len2sq(a) == 0 ? a : scale2(a, 1 / vec2 norm2sq (vec2 a ) { return len2sq(a) == 0 ? a : scale2(a, 1 / len2sq(a)); } int finite2 (vec2 a ) { return FINITE(a.x) && FINITE(a.y); } vec2 mix2 (vec2 a,vec2 b,float t) { return add2(scale2((a),1-(t)), scale2((b), t)); } -vec2 clamp2(vec2 v,float a,float b){ return vec2(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a)); } +vec2 clamp2(vec2 v, vec2 a, vec2 b){ return vec2(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y)); } +vec2 clamp2f(vec2 v,float a,float b){ return vec2(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a)); } // ---------------------------------------------------------------------------- vec3 ptr3 (const float *a ) { return vec3(a[0],a[1],a[2]); } @@ -337820,7 +337893,8 @@ vec3 norm3 (vec3 a ) { return len3sq(a) == 0 ? a : scale3(a, 1 / vec3 norm3sq (vec3 a ) { return len3sq(a) == 0 ? a : scale3(a, 1 / len3sq(a)); } int finite3 (vec3 a ) { return finite2(vec2(a.x,a.y)) && FINITE(a.z); } vec3 mix3 (vec3 a,vec3 b,float t) { return add3(scale3((a),1-(t)), scale3((b), t)); } -vec3 clamp3(vec3 v,float a,float b){ return vec3(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a)); } +vec3 clamp3(vec3 v, vec3 a, vec3 b){ return vec3(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y),maxf(minf(b.z,v.z),a.z)); } +vec3 clamp3f(vec3 v,float a,float b){ return vec3(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a)); } //vec3 tricross3 (vec3 a, vec3 b, vec3 c) { return cross3(a,cross3(b,c)); } // useful? void ortho3 (vec3 *left, vec3 *up, vec3 v) { #if 0 @@ -337874,7 +337948,8 @@ vec4 norm4 (vec4 a ) { return len4sq(a) == 0 ? a : scale4(a, 1 / vec4 norm4sq (vec4 a ) { return len4sq(a) == 0 ? a : scale4(a, 1 / len4sq(a)); } int finite4 (vec4 a ) { return finite3(vec3(a.x,a.y,a.z)) && FINITE(a.w); } vec4 mix4 (vec4 a,vec4 b,float t) { return add4(scale4((a),1-(t)), scale4((b), t)); } -vec4 clamp4(vec4 v,float a,float b){ return vec4(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a),maxf(minf(b,v.w),a)); } +vec4 clamp4(vec4 v, vec4 a, vec4 b){ return vec4(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y),maxf(minf(b.z,v.z),a.z),maxf(minf(b.w,v.w),a.w)); } +vec4 clamp4f(vec4 v,float a,float b){ return vec4(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a),maxf(minf(b,v.w),a)); } // vec4 cross4(vec4 v0, vec4 v1) { return vec34(cross3(v0.xyz, v1.xyz), (v0.w + v1.w) * 0.5f); } // may fail // ---------------------------------------------------------------------------- @@ -339687,6 +339762,9 @@ void shader_print(const char *source) { } } +// sorted by shader handle. an array of properties per shader. properties are plain strings. +static __thread map(unsigned, array(char*)) shader_reflect; + static GLuint shader_compile( GLenum type, const char *source ) { GLuint shader = glCreateShader(type); @@ -339812,9 +339890,140 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char } */ + // shader compiled fine, before returning, let's parse the source and reflect the uniforms + array(char*) props = 0; + do_once map_init_int( shader_reflect ); + if(vs) for each_substring(vs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if(fs) for each_substring(fs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if(gs) for each_substring(gs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if( props ) { + map_insert(shader_reflect, program, props); + } + return program; } +unsigned shader_properties(unsigned shader) { + array(char*) *found = map_find(shader_reflect, shader); + return found ? array_count(*found) : 0; +} + +char** shader_property(unsigned shader, unsigned property) { + array(char*) *found = map_find(shader_reflect, shader); + return found ? &(*found)[property] : NULL; +} + +int ui_shader(unsigned shader) { + int changed = 0; + + unsigned num_properties = shader_properties(shader); + for( unsigned i = 0; i < num_properties; ++i ) { + char **ptr = shader_property(shader,i); + + const char *line = *ptr; // debug: ui_label(line); + char uniform[32], type[32], name[32]; + if( sscanf(line, "%s %s %s", uniform, type, name) != 3) continue; + + int is_color = !!strstri(name, "color"), top = is_color ? 1 : 10; + vec4 minv = strstr(line, "min:") ? atof4(strstr(line, "min:") + 4) : vec4(0,0,0,0); + vec4 setv = strstr(line, "set:") ? atof4(strstr(line, "set:") + 4) : vec4(0,0,0,0); + vec4 maxv = strstr(line, "max:") ? atof4(strstr(line, "max:") + 4) : vec4(top,top,top,top); + char* tip = strstr(line, "tip:"); tip = tip && tip[4] ? tip + 4 : 0; + char *label = !tip ? va("%c%s", name[0] - 32 * !!(name[0] >= 'a'), name+1) : + va("%c%s " ICON_MD_HELP "@%s", name[0] - 32 * !!(name[0] >= 'a'), name+1, tip); + + if(minv.x > maxv.x) swapf(&minv.x, &maxv.x); + if(minv.y > maxv.y) swapf(&minv.y, &maxv.y); + if(minv.z > maxv.z) swapf(&minv.z, &maxv.z); + if(minv.w > maxv.w) swapf(&minv.w, &maxv.w); + + // supports int,float,vec2/3/4,color3/4 + int touched = 0; + if( type[0] == 'i' ) { + int v = setv.x; + + if( (touched = ui_int(label, &v)) != 0 ) { + setv.x = clampi(v, minv.x, maxv.x); // min..max range + } + } + else if( type[0] == 'f' ) { + setv.x = (clampf(setv.x, minv.x, maxv.x) - minv.x) / (maxv.x - minv.x); + + if( (touched = ui_slider2(label, &setv.x, va("%5.2f", setv.x))) != 0 ) { + setv.x = clampf(minv.x + setv.x * (maxv.x-minv.x), minv.x, maxv.x); // min..max range + } + } + else if( type[0] == 'v' && type[3] == '2' ) { + setv.xy = clamp2(setv.xy,minv.xy,maxv.xy); + + if( (touched = ui_float2(label, &setv.x)) != 0 ) { + setv.xy = clamp2(setv.xy,minv.xy,maxv.xy); + } + } + else if( type[0] == 'v' && type[3] == '3' ) { + setv.xyz = clamp3(setv.xyz,minv.xyz,maxv.xyz); + + if( (touched = (is_color ? ui_color3f : ui_float3)(label, &setv.x)) != 0 ) { + setv.xyz = clamp3(setv.xyz,minv.xyz,maxv.xyz); + } + } + else if( type[0] == 'v' && type[3] == '4' ) { + setv = clamp4(setv,minv,maxv); + + if( (touched = (is_color ? ui_color4f : ui_float4)(label, &setv.x)) != 0 ) { + setv = clamp4(setv,minv,maxv); + } + } + + if( touched ) { + // send to shader + GLint shader_bak; glGetIntegerv(GL_CURRENT_PROGRAM, &shader_bak); + glUseProgram(shader); + /**/ if(type[0] == 'i') glUniform1i(glGetUniformLocation(shader, name), setv.x); + else if(type[0] == 'f') glUniform1f(glGetUniformLocation(shader, name), setv.x); + else if(type[3] == '2') glUniform2fv(glGetUniformLocation(shader, name), 1, &setv.x); + else if(type[3] == '3') glUniform3fv(glGetUniformLocation(shader, name), 1, &setv.x); + else if(type[3] == '4') glUniform4fv(glGetUniformLocation(shader, name), 1, &setv.x); + glUseProgram(shader_bak); + + // upgrade value + *ptr = FREE(*ptr); + *ptr = stringf("%s %s %s ///set:%s min:%s max:%s tip:%s", uniform,type,name,ftoa4(setv),ftoa4(minv),ftoa4(maxv),tip?tip:""); + + changed = 1; + } + } + + if(num_properties) ui_separator(); + + return changed; +} + +int ui_shaders() { + int changed = 0; + int has_menu = ui_has_menubar(); + if( (has_menu ? ui_window("Shaders", 0) : ui_panel("Shaders", 0) ) ) { + for each_map_ptr(shader_reflect, unsigned, k, array(char*), v) { + ui_section(va("Shader %d",*k)); + changed |= ui_shader(*k); + } + (has_menu ? ui_window_end : ui_panel_end)(); + } + return changed; +} + unsigned compute(const char *cs){ #if is(ems) return 0; @@ -342472,16 +342681,6 @@ void* screenshot_async( int n ) { // 3 RGB, 4 RGBA, -3 BGR, -4 BGRA // ----------------------------------------------------------------------------- // viewports -void viewport_color3(vec3 color3) { - glClearColor(color3.x, color3.y, color3.z, 1); -} -void viewport_color(uint32_t rgba) { - float b = ((rgba >> 0) & 255) / 255.f; - float g = ((rgba >> 8) & 255) / 255.f; - float r = ((rgba >> 16) & 255) / 255.f; - glClearColor(r, g, b, 1); -} - void viewport_clear(bool color, bool depth) { glClearDepthf(1); glClearStencil(0); @@ -342582,6 +342781,8 @@ void postfx_clear(postfx *fx); char* postfx_name(postfx *fx, int slot); +int ui_postfx(postfx *fx, int slot); + struct passfx { mesh_t m; char *name; @@ -342724,6 +342925,14 @@ void postfx_clear(postfx *fx) { fx->mask = fx->enabled = 0; } +int ui_postfx(postfx *fx, int pass) { + int on = ui_enabled(); + ui_enable( postfx_enabled(fx,pass) ); + int rc = ui_shader(fx->pass[pass].program); + ui_enable( on ); + return rc; +} + static __thread array(handle) last_fb; bool postfx_begin(postfx *fx, int width, int height) { @@ -342849,6 +343058,9 @@ bool postfx_end(postfx *fx) { if(is_depth_test_enabled); glEnable(GL_DEPTH_TEST); + // restore clear color: needed in case transparent window is being used (alpha != 0) + glClearColor(0,0,0,1); // @transparent + return true; } @@ -342891,6 +343103,9 @@ char *fx_name(int pass) { int fx_find(const char *name) { return postfx_find(&fx, name); } +int ui_fx(int pass) { + return ui_postfx(&fx, pass); +} // ----------------------------------------------------------------------------- // brdf @@ -344155,7 +344370,7 @@ anims_t animations(const char *pathfile, int flags) { char anim_name[128] = {0}; if( sscanf(anim, "%*s %d-%d %127[^\r\n]", &from, &to, anim_name) != 3) continue; array_push(a.anims, !!strstri(anim_name, "loop") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] - array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); + array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); // @leak } a.speed = 1.0; return a; @@ -344260,7 +344475,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) { vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f}; glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x); // config vertex data - glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); // feed vertex data glDrawArrays(mode, 0, count); @@ -344292,7 +344507,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) { vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f}; glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x); // config vertex data - glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); // feed vertex data glDrawArrays(mode, 0, count); @@ -344378,7 +344593,7 @@ void ddraw_ground_(float scale) { // 10x10 ddraw_line(vec3(-scale,0,i), vec3(+scale,0,i)); // horiz ddraw_line(vec3(i,0,-scale), vec3(i,0,+scale)); // vert } - ddraw_color( GRAY ); // inner + ddraw_color( RGB3(149,149,149) ); // inner, light grey for( float i = -scale + scale/10, c = 1; c < 20; ++c, i += (scale/10) ) { ddraw_line_thin(vec3(-scale,0,i), vec3(+scale,0,i)); // horiz ddraw_line_thin(vec3(i,0,-scale), vec3(i,0,+scale)); // vert @@ -344922,7 +345137,7 @@ void ddraw_init() { do_once { for( int i = 0; i < 2; ++i ) for( int j = 0; j < 3; ++j ) map_init(dd_lists[i][j], less_int, hash_int); - dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", ""); + dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", NULL); dd_u_color = glGetUniformLocation(dd_program, "u_color"); ddraw_flush(); // alloc vao & vbo, also resets color } @@ -345809,11 +346024,11 @@ const char * app_exec( const char *cmd ) { return snprintf(output, 16, "%-15d", rc), buf[-1] = ' ', output; } -void app_spawn( const char *cmd ) { - if( !cmd[0] ) return; +int app_spawn( const char *cmd ) { + if( !cmd[0] ) return -1; cmd = file_normalize(cmd); - system(cmd); + return system(cmd); } #if is(osx) @@ -346906,7 +347121,7 @@ static void nk_config_custom_fonts() { // nk_style_load_all_cursors(ctx, atlas->cursors); glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); } -static void nk_config_custom_style() { +static void nk_config_custom_theme() { #ifdef UI_HUE float default_hue = UI_HUE; #else @@ -346955,13 +347170,6 @@ table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = hover_hue; // nk_rgba(255, 0, 0, 255); // table[NK_COLOR_SELECT] = nk_rgba(57, 67, 61, 255); // table[NK_COLOR_SELECT_ACTIVE] = main; - // @transparent - #if !is(ems) - if( glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE ) - for(int i = 0; i < countof(table); ++i) table[i].a = 255; // table[i].a ? 255 : 0; - #endif - // @transparent - nk_style_default(ui_ctx); nk_style_from_table(ui_ctx, table); @@ -347186,7 +347394,7 @@ static map(char*,unsigned) ui_windows = 0; static void ui_init() { do_once { nk_config_custom_fonts(); - nk_config_custom_style(); + nk_config_custom_theme(); map_init(ui_windows, less_str, hash_str); } @@ -347536,71 +347744,6 @@ int ui_enable_(int enabled) { off.window.header.normal.data.color.a *= alpha; off.window.header.hover.data.color.a *= alpha; off.window.header.active.data.color.a *= alpha; - - // @transparent { - // fixes for transparent windows - #if !is(ems) - float hsva[4]; - if( glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE ) { - #define fix(col) off.col = nk_rgba_cf(nk_hsva_colorfv( (nk_colorf_hsva_fv(hsva, nk_color_cf(on.col)),hsva[1] *= alpha,hsva[2] *= alpha, hsva) )) - fix(contextual_button.normal.data.color); - fix(menu_button.normal.data.color); - fix(option.normal.data.color); - fix(option.cursor_normal.data.color); - fix(checkbox.normal.data.color); - fix(checkbox.cursor_normal.data.color); - fix(selectable.normal.data.color); - fix(selectable.normal_active.data.color); - fix(slider.normal.data.color); - fix(slider.bar_normal); - fix(slider.cursor_normal.data.color); - fix(slider.dec_button.normal.data.color); - fix(slider.inc_button.normal.data.color); - fix(progress.normal.data.color); - fix(progress.cursor_normal.data.color); - fix(property.normal.data.color); - fix(property.label_normal); - fix(property.edit.normal.data.color); - fix(property.edit.cursor_normal); - fix(property.edit.selected_normal); - fix(property.dec_button.normal.data.color); - fix(property.inc_button.normal.data.color); - fix(edit.normal.data.color); - fix(edit.cursor_normal); - fix(edit.selected_normal); - fix(scrollh.normal.data.color); - fix(scrollh.cursor_normal.data.color); - fix(scrollv.normal.data.color); - fix(scrollv.cursor_normal.data.color); - fix(combo.normal.data.color); - fix(combo.label_normal); - fix(combo.symbol_normal); - fix(combo.button.normal.data.color); - fix(window.header.normal.data.color); - fix(button.normal.data.color); - #undef fix - #define fix(field) on.field.a = off.field.a = 0 - fix(button.border_color); - fix(button.border_color); - fix(button.border_color); - fix(contextual_button.border_color); - fix(menu_button.border_color); - fix(option.border_color); - fix(checkbox.border_color); - fix(slider.border_color); - fix(progress.border_color); - fix(property.border_color); - fix(edit.border_color); - fix(chart.border_color); - fix(scrollh.border_color); - fix(scrollv.border_color); - fix(tab.border_color); - fix(combo.border_color); - fix(window.border_color); - #undef fix - } - #endif - // } @transparent } static struct nk_input input; if (!enabled) { @@ -347617,11 +347760,11 @@ int ui_enable_(int enabled) { } static int ui_is_enabled = 1; -int ui_enable() { - return ui_is_enabled ? 0 : ui_enable_(ui_is_enabled = 1); +int ui_enable(int on) { + return ui_is_enabled == on ? 0 : ui_enable_(ui_is_enabled = on); } -int ui_disable() { - return ui_is_enabled ? ui_enable_(ui_is_enabled = 0) ^ 1 : 0; +int ui_enabled() { + return ui_is_enabled; } static @@ -347639,7 +347782,7 @@ void ui_create() { nk_glfw3_new_frame(&nk_glfw); //g->nk_glfw); ui_dirty = 0; - ui_enable(); + ui_enable(1); } } @@ -347714,7 +347857,11 @@ void ui_render() { * Make sure to either a.) save and restore or b.) reset your own state after * rendering the UI. */ //nk_sdl_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); + + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); // @transparent nk_glfw3_render(&nk_glfw, NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); // @transparent + #if is(ems) glFinish(); #endif @@ -348423,13 +348570,6 @@ int ui_button_transparent(const char *text) { static int ui_button_(const char *text) { - // @transparent - static bool transparency_fix_needed = 0; ifndef(ems, do_once transparency_fix_needed = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); - const float dim = transparency_fix_needed && ui_alpha < 1 ? 0.5 : 1; - const float dim_alpha = transparency_fix_needed ? 1.0 : 0.90*ui_alpha; - const float text_alpha = transparency_fix_needed ? 1.0 : ui_alpha; - // @transparent - if( 1 ) { #if UI_BUTTON_MONOCHROME nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba(0,0,0,ui_alpha)); @@ -348448,13 +348588,13 @@ int ui_button_(const char *text) { nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,1.00,1.0*ui_alpha)); nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.60,0.4*ui_alpha)); #else // new - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba_f(0.00,0.00,0.00,text_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_hover, nk_rgba_f(0.11,0.11,0.11,text_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_active, nk_rgba_f(0.00,0.00,0.00,text_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba_f(0.00,0.00,0.00,ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_hover, nk_rgba_f(0.11,0.11,0.11,ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_active, nk_rgba_f(0.00,0.00,0.00,ui_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.normal.data.color, nk_hsva_f(ui_hue,0.80*dim,0.6*dim,dim_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,0.85*dim,0.9*dim,dim_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.80*dim,0.6*dim,dim_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.normal.data.color, nk_hsva_f(ui_hue,0.80,0.6,0.90*ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,0.85,0.9,0.90*ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.80,0.6,0.90*ui_alpha)); #endif } @@ -349115,7 +349255,7 @@ int ui_demo(int do_windows) { if(choice == 2) ui_notify(va("My random toast (%d)", rand()), va("This is notification #%d", ++hits)); if(choice == 3) disable_all ^= 1; - if( disable_all ) ui_disable(); + if( disable_all ) ui_enable(0); if( ui_browse(&browsed_file, &show_browser) ) puts(browsed_file); @@ -349164,7 +349304,7 @@ int ui_demo(int do_windows) { if( ui_buttons(3, "yes", "no", "maybe") ) { puts("button clicked"); } if( ui_dialog("my dialog", __FILE__ "\n" __DATE__ "\n" "Public Domain.", 2/*two buttons*/, &show_dialog) ) {} - if( disable_all ) ui_enable(); + if( disable_all ) ui_enable(1); ui_panel_end(); } @@ -350060,6 +350200,8 @@ int window_frame_begin() { ui_create(); profile_render(); + + ui_shaders(); #if 0 // deprecated // run user-defined hooks diff --git a/engine/split/v4k_file.c b/engine/split/v4k_file.c index 1f1cdbd..d93a935 100644 --- a/engine/split/v4k_file.c +++ b/engine/split/v4k_file.c @@ -681,10 +681,6 @@ const char *vfs_resolve(const char *pathfile) { return pathfile; } -#ifndef VFS_ALWAYS_PACK -#define VFS_ALWAYS_PACK flag("--vfs-always-pack") -#endif - char* vfs_load(const char *pathfile, int *size_out) { // @todo: fix leaks, vfs_unpack() // @fixme: handle \\?\ absolute path (win) if (!pathfile[0]) return file_load(pathfile, size_out); @@ -756,7 +752,8 @@ if( found && *found == 0 ) { ptr = vfs_unpack(pathfile, &size); // asset not found? maybe it has not been cooked yet at this point (see --cook-on-demand) - if( (!ptr && COOK_ON_DEMAND) || VFS_ALWAYS_PACK ) { + if( !ptr && COOK_ON_DEMAND ) { + static thread_mutex_t mutex, *init = 0; if(!init) thread_mutex_init(init = &mutex); thread_mutex_lock(&mutex); diff --git a/engine/split/v4k_math.c b/engine/split/v4k_math.c index b2f246e..8a0806d 100644 --- a/engine/split/v4k_math.c +++ b/engine/split/v4k_math.c @@ -9,6 +9,54 @@ #include #include +vec2 atof2(const char *s) { + vec2 v = {0}; + sscanf(s, "%f,%f", &v.x, &v.y); + return v; +} +vec3 atof3(const char *s) { + vec3 v = {0}; + sscanf(s, "%f,%f,%f", &v.x, &v.y, &v.z); + return v; +} +vec4 atof4(const char *s) { + vec4 v = {0}; + sscanf(s, "%f,%f,%f,%f", &v.x, &v.y, &v.z, &v.w); + return v; +} + +char* ftoa(float f) { + return va("%f", f); +} +char* ftoa2(vec2 v) { + return va("%f,%f", v.x, v.y); +} +char* ftoa3(vec3 v) { + return va("%f,%f,%f", v.x, v.y, v.z); +} +char* ftoa4(vec4 v) { + return va("%f,%f,%f,%f", v.x, v.y, v.z, v.w); +} + +void swapf(float *a, float *b) { + float t = *a; *a = *b; *b = *a; +} +void swapf2(vec2 *a, vec2 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; +} +void swapf3(vec3 *a, vec3 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; + float z = a->z; a->z = b->z; b->z = a->z; +} +void swapf4(vec4 *a, vec4 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; + float z = a->z; a->z = b->z; b->z = a->z; + float w = a->w; a->w = b->w; b->w = a->w; +} + static uint64_t rand_xoro256(uint64_t x256_s[4]) { // xoshiro256+ 1.0 by David Blackman and Sebastiano Vigna (PD) const uint64_t result = x256_s[0] + x256_s[3]; const uint64_t t = x256_s[1] << 17; @@ -206,7 +254,8 @@ vec2 norm2 (vec2 a ) { return len2sq(a) == 0 ? a : scale2(a, 1 / vec2 norm2sq (vec2 a ) { return len2sq(a) == 0 ? a : scale2(a, 1 / len2sq(a)); } int finite2 (vec2 a ) { return FINITE(a.x) && FINITE(a.y); } vec2 mix2 (vec2 a,vec2 b,float t) { return add2(scale2((a),1-(t)), scale2((b), t)); } -vec2 clamp2(vec2 v,float a,float b){ return vec2(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a)); } +vec2 clamp2(vec2 v, vec2 a, vec2 b){ return vec2(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y)); } +vec2 clamp2f(vec2 v,float a,float b){ return vec2(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a)); } // ---------------------------------------------------------------------------- vec3 ptr3 (const float *a ) { return vec3(a[0],a[1],a[2]); } @@ -236,7 +285,8 @@ vec3 norm3 (vec3 a ) { return len3sq(a) == 0 ? a : scale3(a, 1 / vec3 norm3sq (vec3 a ) { return len3sq(a) == 0 ? a : scale3(a, 1 / len3sq(a)); } int finite3 (vec3 a ) { return finite2(vec2(a.x,a.y)) && FINITE(a.z); } vec3 mix3 (vec3 a,vec3 b,float t) { return add3(scale3((a),1-(t)), scale3((b), t)); } -vec3 clamp3(vec3 v,float a,float b){ return vec3(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a)); } +vec3 clamp3(vec3 v, vec3 a, vec3 b){ return vec3(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y),maxf(minf(b.z,v.z),a.z)); } +vec3 clamp3f(vec3 v,float a,float b){ return vec3(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a)); } //vec3 tricross3 (vec3 a, vec3 b, vec3 c) { return cross3(a,cross3(b,c)); } // useful? void ortho3 (vec3 *left, vec3 *up, vec3 v) { #if 0 @@ -290,7 +340,8 @@ vec4 norm4 (vec4 a ) { return len4sq(a) == 0 ? a : scale4(a, 1 / vec4 norm4sq (vec4 a ) { return len4sq(a) == 0 ? a : scale4(a, 1 / len4sq(a)); } int finite4 (vec4 a ) { return finite3(vec3(a.x,a.y,a.z)) && FINITE(a.w); } vec4 mix4 (vec4 a,vec4 b,float t) { return add4(scale4((a),1-(t)), scale4((b), t)); } -vec4 clamp4(vec4 v,float a,float b){ return vec4(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a),maxf(minf(b,v.w),a)); } +vec4 clamp4(vec4 v, vec4 a, vec4 b){ return vec4(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y),maxf(minf(b.z,v.z),a.z),maxf(minf(b.w,v.w),a.w)); } +vec4 clamp4f(vec4 v,float a,float b){ return vec4(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a),maxf(minf(b,v.w),a)); } // vec4 cross4(vec4 v0, vec4 v1) { return vec34(cross3(v0.xyz, v1.xyz), (v0.w + v1.w) * 0.5f); } // may fail // ---------------------------------------------------------------------------- diff --git a/engine/split/v4k_math.h b/engine/split/v4k_math.h index 84ac29a..5835bf0 100644 --- a/engine/split/v4k_math.h +++ b/engine/split/v4k_math.h @@ -156,7 +156,8 @@ API float len2 (vec2 a ); API vec2 norm2 (vec2 a ); API int finite2 (vec2 a ); API vec2 mix2 (vec2 a,vec2 b,float t); -API vec2 clamp2(vec2 v,float a,float b); +API vec2 clamp2(vec2 v,vec2 a,vec2 b); +API vec2 clamp2f(vec2 v,float a,float b); // ---------------------------------------------------------------------------- API vec3 rnd3 (void); // @todo: rnd2,rnd4,rndq @@ -187,7 +188,8 @@ API vec3 norm3 (vec3 a ); API vec3 norm3sq (vec3 a ); API int finite3 (vec3 a ); API vec3 mix3 (vec3 a,vec3 b,float t); -API vec3 clamp3(vec3 v,float a,float b); +API vec3 clamp3(vec3 v,vec3 a,vec3 b); +API vec3 clamp3f(vec3 v,float a,float b); //vec3 tricross3 (vec3 a, vec3 b, vec3 c); API void ortho3 (vec3 *left, vec3 *up, vec3 v); @@ -223,7 +225,8 @@ API vec4 norm4 (vec4 a ); API vec4 norm4sq (vec4 a ); API int finite4 (vec4 a ); API vec4 mix4 (vec4 a,vec4 b,float t); -API vec4 clamp4(vec4 v,float a,float b); +API vec4 clamp4(vec4 v,vec4 a,vec4 b); +API vec4 clamp4f(vec4 v,float a,float b); // vec4 cross4(vec4 v0, vec4 v1); // ---------------------------------------------------------------------------- @@ -325,7 +328,7 @@ API vec4 transform444(const mat44 m, const vec4 p); API bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp); // ---------------------------------------------------------------------------- -// !!! for debugging +// debugging and utils API void print2( vec2 v ); API void print3( vec3 v ); @@ -334,3 +337,18 @@ API void printq( quat q ); API void print33( float *m ); API void print34( float *m ); API void print44( float *m ); + +API vec2 atof2(const char *s); +API vec3 atof3(const char *s); +API vec4 atof4(const char *s); + +API char* ftoa(float f); +API char* ftoa2(vec2 v); +API char* ftoa3(vec3 v); +API char* ftoa4(vec4 v); + +API void swapf(float *a, float *b); +API void swapf2(vec2 *a, vec2 *b); +API void swapf3(vec3 *a, vec3 *b); +API void swapf4(vec4 *a, vec4 *b); + diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index fb6f05d..0db56d4 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -62,6 +62,9 @@ void shader_print(const char *source) { } } +// sorted by shader handle. an array of properties per shader. properties are plain strings. +static __thread map(unsigned, array(char*)) shader_reflect; + static GLuint shader_compile( GLenum type, const char *source ) { GLuint shader = glCreateShader(type); @@ -187,9 +190,140 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char } */ + // shader compiled fine, before returning, let's parse the source and reflect the uniforms + array(char*) props = 0; + do_once map_init_int( shader_reflect ); + if(vs) for each_substring(vs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if(fs) for each_substring(fs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if(gs) for each_substring(gs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if( props ) { + map_insert(shader_reflect, program, props); + } + return program; } +unsigned shader_properties(unsigned shader) { + array(char*) *found = map_find(shader_reflect, shader); + return found ? array_count(*found) : 0; +} + +char** shader_property(unsigned shader, unsigned property) { + array(char*) *found = map_find(shader_reflect, shader); + return found ? &(*found)[property] : NULL; +} + +int ui_shader(unsigned shader) { + int changed = 0; + + unsigned num_properties = shader_properties(shader); + for( unsigned i = 0; i < num_properties; ++i ) { + char **ptr = shader_property(shader,i); + + const char *line = *ptr; // debug: ui_label(line); + char uniform[32], type[32], name[32]; + if( sscanf(line, "%s %s %s", uniform, type, name) != 3) continue; + + int is_color = !!strstri(name, "color"), top = is_color ? 1 : 10; + vec4 minv = strstr(line, "min:") ? atof4(strstr(line, "min:") + 4) : vec4(0,0,0,0); + vec4 setv = strstr(line, "set:") ? atof4(strstr(line, "set:") + 4) : vec4(0,0,0,0); + vec4 maxv = strstr(line, "max:") ? atof4(strstr(line, "max:") + 4) : vec4(top,top,top,top); + char* tip = strstr(line, "tip:"); tip = tip && tip[4] ? tip + 4 : 0; + char *label = !tip ? va("%c%s", name[0] - 32 * !!(name[0] >= 'a'), name+1) : + va("%c%s " ICON_MD_HELP "@%s", name[0] - 32 * !!(name[0] >= 'a'), name+1, tip); + + if(minv.x > maxv.x) swapf(&minv.x, &maxv.x); + if(minv.y > maxv.y) swapf(&minv.y, &maxv.y); + if(minv.z > maxv.z) swapf(&minv.z, &maxv.z); + if(minv.w > maxv.w) swapf(&minv.w, &maxv.w); + + // supports int,float,vec2/3/4,color3/4 + int touched = 0; + if( type[0] == 'i' ) { + int v = setv.x; + + if( (touched = ui_int(label, &v)) != 0 ) { + setv.x = clampi(v, minv.x, maxv.x); // min..max range + } + } + else if( type[0] == 'f' ) { + setv.x = (clampf(setv.x, minv.x, maxv.x) - minv.x) / (maxv.x - minv.x); + + if( (touched = ui_slider2(label, &setv.x, va("%5.2f", setv.x))) != 0 ) { + setv.x = clampf(minv.x + setv.x * (maxv.x-minv.x), minv.x, maxv.x); // min..max range + } + } + else if( type[0] == 'v' && type[3] == '2' ) { + setv.xy = clamp2(setv.xy,minv.xy,maxv.xy); + + if( (touched = ui_float2(label, &setv.x)) != 0 ) { + setv.xy = clamp2(setv.xy,minv.xy,maxv.xy); + } + } + else if( type[0] == 'v' && type[3] == '3' ) { + setv.xyz = clamp3(setv.xyz,minv.xyz,maxv.xyz); + + if( (touched = (is_color ? ui_color3f : ui_float3)(label, &setv.x)) != 0 ) { + setv.xyz = clamp3(setv.xyz,minv.xyz,maxv.xyz); + } + } + else if( type[0] == 'v' && type[3] == '4' ) { + setv = clamp4(setv,minv,maxv); + + if( (touched = (is_color ? ui_color4f : ui_float4)(label, &setv.x)) != 0 ) { + setv = clamp4(setv,minv,maxv); + } + } + + if( touched ) { + // send to shader + GLint shader_bak; glGetIntegerv(GL_CURRENT_PROGRAM, &shader_bak); + glUseProgram(shader); + /**/ if(type[0] == 'i') glUniform1i(glGetUniformLocation(shader, name), setv.x); + else if(type[0] == 'f') glUniform1f(glGetUniformLocation(shader, name), setv.x); + else if(type[3] == '2') glUniform2fv(glGetUniformLocation(shader, name), 1, &setv.x); + else if(type[3] == '3') glUniform3fv(glGetUniformLocation(shader, name), 1, &setv.x); + else if(type[3] == '4') glUniform4fv(glGetUniformLocation(shader, name), 1, &setv.x); + glUseProgram(shader_bak); + + // upgrade value + *ptr = FREE(*ptr); + *ptr = stringf("%s %s %s ///set:%s min:%s max:%s tip:%s", uniform,type,name,ftoa4(setv),ftoa4(minv),ftoa4(maxv),tip?tip:""); + + changed = 1; + } + } + + if(num_properties) ui_separator(); + + return changed; +} + +int ui_shaders() { + int changed = 0; + int has_menu = ui_has_menubar(); + if( (has_menu ? ui_window("Shaders", 0) : ui_panel("Shaders", 0) ) ) { + for each_map_ptr(shader_reflect, unsigned, k, array(char*), v) { + ui_section(va("Shader %d",*k)); + changed |= ui_shader(*k); + } + (has_menu ? ui_window_end : ui_panel_end)(); + } + return changed; +} + unsigned compute(const char *cs){ #if is(ems) return 0; @@ -2847,16 +2981,6 @@ void* screenshot_async( int n ) { // 3 RGB, 4 RGBA, -3 BGR, -4 BGRA // ----------------------------------------------------------------------------- // viewports -void viewport_color3(vec3 color3) { - glClearColor(color3.x, color3.y, color3.z, 1); -} -void viewport_color(uint32_t rgba) { - float b = ((rgba >> 0) & 255) / 255.f; - float g = ((rgba >> 8) & 255) / 255.f; - float r = ((rgba >> 16) & 255) / 255.f; - glClearColor(r, g, b, 1); -} - void viewport_clear(bool color, bool depth) { glClearDepthf(1); glClearStencil(0); @@ -2957,6 +3081,8 @@ void postfx_clear(postfx *fx); char* postfx_name(postfx *fx, int slot); +int ui_postfx(postfx *fx, int slot); + struct passfx { mesh_t m; char *name; @@ -3099,6 +3225,14 @@ void postfx_clear(postfx *fx) { fx->mask = fx->enabled = 0; } +int ui_postfx(postfx *fx, int pass) { + int on = ui_enabled(); + ui_enable( postfx_enabled(fx,pass) ); + int rc = ui_shader(fx->pass[pass].program); + ui_enable( on ); + return rc; +} + static __thread array(handle) last_fb; bool postfx_begin(postfx *fx, int width, int height) { @@ -3224,6 +3358,9 @@ bool postfx_end(postfx *fx) { if(is_depth_test_enabled); glEnable(GL_DEPTH_TEST); + // restore clear color: needed in case transparent window is being used (alpha != 0) + glClearColor(0,0,0,1); // @transparent + return true; } @@ -3266,6 +3403,9 @@ char *fx_name(int pass) { int fx_find(const char *name) { return postfx_find(&fx, name); } +int ui_fx(int pass) { + return ui_postfx(&fx, pass); +} // ----------------------------------------------------------------------------- // brdf @@ -4530,7 +4670,7 @@ anims_t animations(const char *pathfile, int flags) { char anim_name[128] = {0}; if( sscanf(anim, "%*s %d-%d %127[^\r\n]", &from, &to, anim_name) != 3) continue; array_push(a.anims, !!strstri(anim_name, "loop") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] - array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); + array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); // @leak } a.speed = 1.0; return a; diff --git a/engine/split/v4k_render.h b/engine/split/v4k_render.h index 6eb3744..eec13c7 100644 --- a/engine/split/v4k_render.h +++ b/engine/split/v4k_render.h @@ -40,7 +40,8 @@ API float alpha( unsigned rgba ); #define ORANGE RGB3( 255,144,48 ) #define PURPLE RGB3( 102,77,102 ) // 178,128,255 ) #define YELLOW RGB3( 255,224,0 ) -#define GRAY RGB3( 32, 32, 32 ) // 149,149,149 ) +#define GRAY RGB3( 32,32,32 ) // dark gray +#define SILVER RGB3( 149,149,149 ) // dark white, gray-ish #define PINK RGB3( 255,48,144 ) #define AQUA RGB3( 48,255,144 ) @@ -337,6 +338,14 @@ API void shader_colormap(const char *name, colormap_t cm); API unsigned shader_get_active(); API void shader_destroy(unsigned shader); +// reflection. [0..N] are shader properties + +API unsigned shader_properties(unsigned shader); +API char** shader_property(unsigned shader, unsigned property_no); + +API int ui_shader(unsigned shader); +API int ui_shaders(); + // compute shaders enum BUFFER_MODE { BUFFER_READ, @@ -663,8 +672,6 @@ API int skybox_pop_state(); // @to deprecate // ----------------------------------------------------------------------------- // post-fxs -API void viewport_color(uint32_t color); // background(uint32_t) instead? -API void viewport_color3(vec3 color); // background3(vec3) instead? API void viewport_clear(bool color, bool depth); API void viewport_clip(vec2 from, vec2 to); @@ -679,6 +686,8 @@ API void fx_enable_all(int enabled); API char * fx_name(int pass); API int fx_find(const char *name); +API int ui_fx(int pass); + // ----------------------------------------------------------------------------- // utils diff --git a/engine/split/v4k_renderdd.c b/engine/split/v4k_renderdd.c index 0d664f9..2894346 100644 --- a/engine/split/v4k_renderdd.c +++ b/engine/split/v4k_renderdd.c @@ -95,7 +95,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) { vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f}; glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x); // config vertex data - glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); // feed vertex data glDrawArrays(mode, 0, count); @@ -127,7 +127,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) { vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f}; glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x); // config vertex data - glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); // feed vertex data glDrawArrays(mode, 0, count); @@ -213,7 +213,7 @@ void ddraw_ground_(float scale) { // 10x10 ddraw_line(vec3(-scale,0,i), vec3(+scale,0,i)); // horiz ddraw_line(vec3(i,0,-scale), vec3(i,0,+scale)); // vert } - ddraw_color( GRAY ); // inner + ddraw_color( RGB3(149,149,149) ); // inner, light grey for( float i = -scale + scale/10, c = 1; c < 20; ++c, i += (scale/10) ) { ddraw_line_thin(vec3(-scale,0,i), vec3(+scale,0,i)); // horiz ddraw_line_thin(vec3(i,0,-scale), vec3(i,0,+scale)); // vert @@ -757,7 +757,7 @@ void ddraw_init() { do_once { for( int i = 0; i < 2; ++i ) for( int j = 0; j < 3; ++j ) map_init(dd_lists[i][j], less_int, hash_int); - dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", ""); + dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", NULL); dd_u_color = glGetUniformLocation(dd_program, "u_color"); ddraw_flush(); // alloc vao & vbo, also resets color } diff --git a/engine/split/v4k_system.c b/engine/split/v4k_system.c index e6712fc..ae89d8e 100644 --- a/engine/split/v4k_system.c +++ b/engine/split/v4k_system.c @@ -106,11 +106,11 @@ const char * app_exec( const char *cmd ) { return snprintf(output, 16, "%-15d", rc), buf[-1] = ' ', output; } -void app_spawn( const char *cmd ) { - if( !cmd[0] ) return; +int app_spawn( const char *cmd ) { + if( !cmd[0] ) return -1; cmd = file_normalize(cmd); - system(cmd); + return system(cmd); } #if is(osx) diff --git a/engine/split/v4k_system.h b/engine/split/v4k_system.h index 0fb8197..84f4d41 100644 --- a/engine/split/v4k_system.h +++ b/engine/split/v4k_system.h @@ -22,7 +22,7 @@ API void tty_attach(); API void tty_detach(); API const char* app_exec(const char *command); // returns ("%15d %s", retcode, output_last_line) -API void app_spawn(const char *command); +API int app_spawn(const char *command); API int app_cores(); API int app_battery(); /// return battery level [1..100]. also positive if charging (+), negative if discharging (-), and 0 if no battery is present. diff --git a/engine/split/v4k_ui.c b/engine/split/v4k_ui.c index df5cc53..643d329 100644 --- a/engine/split/v4k_ui.c +++ b/engine/split/v4k_ui.c @@ -127,7 +127,7 @@ static void nk_config_custom_fonts() { // nk_style_load_all_cursors(ctx, atlas->cursors); glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); } -static void nk_config_custom_style() { +static void nk_config_custom_theme() { #ifdef UI_HUE float default_hue = UI_HUE; #else @@ -176,13 +176,6 @@ table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = hover_hue; // nk_rgba(255, 0, 0, 255); // table[NK_COLOR_SELECT] = nk_rgba(57, 67, 61, 255); // table[NK_COLOR_SELECT_ACTIVE] = main; - // @transparent - #if !is(ems) - if( glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE ) - for(int i = 0; i < countof(table); ++i) table[i].a = 255; // table[i].a ? 255 : 0; - #endif - // @transparent - nk_style_default(ui_ctx); nk_style_from_table(ui_ctx, table); @@ -407,7 +400,7 @@ static map(char*,unsigned) ui_windows = 0; static void ui_init() { do_once { nk_config_custom_fonts(); - nk_config_custom_style(); + nk_config_custom_theme(); map_init(ui_windows, less_str, hash_str); } @@ -757,71 +750,6 @@ int ui_enable_(int enabled) { off.window.header.normal.data.color.a *= alpha; off.window.header.hover.data.color.a *= alpha; off.window.header.active.data.color.a *= alpha; - - // @transparent { - // fixes for transparent windows - #if !is(ems) - float hsva[4]; - if( glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE ) { - #define fix(col) off.col = nk_rgba_cf(nk_hsva_colorfv( (nk_colorf_hsva_fv(hsva, nk_color_cf(on.col)),hsva[1] *= alpha,hsva[2] *= alpha, hsva) )) - fix(contextual_button.normal.data.color); - fix(menu_button.normal.data.color); - fix(option.normal.data.color); - fix(option.cursor_normal.data.color); - fix(checkbox.normal.data.color); - fix(checkbox.cursor_normal.data.color); - fix(selectable.normal.data.color); - fix(selectable.normal_active.data.color); - fix(slider.normal.data.color); - fix(slider.bar_normal); - fix(slider.cursor_normal.data.color); - fix(slider.dec_button.normal.data.color); - fix(slider.inc_button.normal.data.color); - fix(progress.normal.data.color); - fix(progress.cursor_normal.data.color); - fix(property.normal.data.color); - fix(property.label_normal); - fix(property.edit.normal.data.color); - fix(property.edit.cursor_normal); - fix(property.edit.selected_normal); - fix(property.dec_button.normal.data.color); - fix(property.inc_button.normal.data.color); - fix(edit.normal.data.color); - fix(edit.cursor_normal); - fix(edit.selected_normal); - fix(scrollh.normal.data.color); - fix(scrollh.cursor_normal.data.color); - fix(scrollv.normal.data.color); - fix(scrollv.cursor_normal.data.color); - fix(combo.normal.data.color); - fix(combo.label_normal); - fix(combo.symbol_normal); - fix(combo.button.normal.data.color); - fix(window.header.normal.data.color); - fix(button.normal.data.color); - #undef fix - #define fix(field) on.field.a = off.field.a = 0 - fix(button.border_color); - fix(button.border_color); - fix(button.border_color); - fix(contextual_button.border_color); - fix(menu_button.border_color); - fix(option.border_color); - fix(checkbox.border_color); - fix(slider.border_color); - fix(progress.border_color); - fix(property.border_color); - fix(edit.border_color); - fix(chart.border_color); - fix(scrollh.border_color); - fix(scrollv.border_color); - fix(tab.border_color); - fix(combo.border_color); - fix(window.border_color); - #undef fix - } - #endif - // } @transparent } static struct nk_input input; if (!enabled) { @@ -838,11 +766,11 @@ int ui_enable_(int enabled) { } static int ui_is_enabled = 1; -int ui_enable() { - return ui_is_enabled ? 0 : ui_enable_(ui_is_enabled = 1); +int ui_enable(int on) { + return ui_is_enabled == on ? 0 : ui_enable_(ui_is_enabled = on); } -int ui_disable() { - return ui_is_enabled ? ui_enable_(ui_is_enabled = 0) ^ 1 : 0; +int ui_enabled() { + return ui_is_enabled; } static @@ -860,7 +788,7 @@ void ui_create() { nk_glfw3_new_frame(&nk_glfw); //g->nk_glfw); ui_dirty = 0; - ui_enable(); + ui_enable(1); } } @@ -935,7 +863,11 @@ void ui_render() { * Make sure to either a.) save and restore or b.) reset your own state after * rendering the UI. */ //nk_sdl_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); + + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); // @transparent nk_glfw3_render(&nk_glfw, NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); // @transparent + #if is(ems) glFinish(); #endif @@ -1644,13 +1576,6 @@ int ui_button_transparent(const char *text) { static int ui_button_(const char *text) { - // @transparent - static bool transparency_fix_needed = 0; ifndef(ems, do_once transparency_fix_needed = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); - const float dim = transparency_fix_needed && ui_alpha < 1 ? 0.5 : 1; - const float dim_alpha = transparency_fix_needed ? 1.0 : 0.90*ui_alpha; - const float text_alpha = transparency_fix_needed ? 1.0 : ui_alpha; - // @transparent - if( 1 ) { #if UI_BUTTON_MONOCHROME nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba(0,0,0,ui_alpha)); @@ -1669,13 +1594,13 @@ int ui_button_(const char *text) { nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,1.00,1.0*ui_alpha)); nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.60,0.4*ui_alpha)); #else // new - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba_f(0.00,0.00,0.00,text_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_hover, nk_rgba_f(0.11,0.11,0.11,text_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_active, nk_rgba_f(0.00,0.00,0.00,text_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba_f(0.00,0.00,0.00,ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_hover, nk_rgba_f(0.11,0.11,0.11,ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_active, nk_rgba_f(0.00,0.00,0.00,ui_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.normal.data.color, nk_hsva_f(ui_hue,0.80*dim,0.6*dim,dim_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,0.85*dim,0.9*dim,dim_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.80*dim,0.6*dim,dim_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.normal.data.color, nk_hsva_f(ui_hue,0.80,0.6,0.90*ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,0.85,0.9,0.90*ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.80,0.6,0.90*ui_alpha)); #endif } @@ -2336,7 +2261,7 @@ int ui_demo(int do_windows) { if(choice == 2) ui_notify(va("My random toast (%d)", rand()), va("This is notification #%d", ++hits)); if(choice == 3) disable_all ^= 1; - if( disable_all ) ui_disable(); + if( disable_all ) ui_enable(0); if( ui_browse(&browsed_file, &show_browser) ) puts(browsed_file); @@ -2385,7 +2310,7 @@ int ui_demo(int do_windows) { if( ui_buttons(3, "yes", "no", "maybe") ) { puts("button clicked"); } if( ui_dialog("my dialog", __FILE__ "\n" __DATE__ "\n" "Public Domain.", 2/*two buttons*/, &show_dialog) ) {} - if( disable_all ) ui_enable(); + if( disable_all ) ui_enable(1); ui_panel_end(); } diff --git a/engine/split/v4k_ui.h b/engine/split/v4k_ui.h index 9b10676..6c71ec7 100644 --- a/engine/split/v4k_ui.h +++ b/engine/split/v4k_ui.h @@ -68,8 +68,8 @@ API int ui_window_end(); API int ui_show(const char *panel_or_window_title, int enabled); API int ui_dims(const char *panel_or_window_title, float width, float height); API int ui_visible(const char *panel_or_window_title); // @todo: include ui_collapse() items that are open as well? -API int ui_enable(); -API int ui_disable(); +API int ui_enable(int on); +API int ui_enabled(); API vec2 ui_get_dims(); API int ui_has_menubar(); diff --git a/engine/split/v4k_window.c b/engine/split/v4k_window.c index 0803b7f..1cd151a 100644 --- a/engine/split/v4k_window.c +++ b/engine/split/v4k_window.c @@ -501,6 +501,8 @@ int window_frame_begin() { ui_create(); profile_render(); + + ui_shaders(); #if 0 // deprecated // run user-defined hooks diff --git a/engine/v4k.c b/engine/v4k.c index 4932ce8..bee664d 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -4803,10 +4803,6 @@ const char *vfs_resolve(const char *pathfile) { return pathfile; } -#ifndef VFS_ALWAYS_PACK -#define VFS_ALWAYS_PACK flag("--vfs-always-pack") -#endif - char* vfs_load(const char *pathfile, int *size_out) { // @todo: fix leaks, vfs_unpack() // @fixme: handle \\?\ absolute path (win) if (!pathfile[0]) return file_load(pathfile, size_out); @@ -4878,7 +4874,8 @@ if( found && *found == 0 ) { ptr = vfs_unpack(pathfile, &size); // asset not found? maybe it has not been cooked yet at this point (see --cook-on-demand) - if( (!ptr && COOK_ON_DEMAND) || VFS_ALWAYS_PACK ) { + if( !ptr && COOK_ON_DEMAND ) { + static thread_mutex_t mutex, *init = 0; if(!init) thread_mutex_init(init = &mutex); thread_mutex_lock(&mutex); @@ -8232,6 +8229,54 @@ void input_demo() { #include #include +vec2 atof2(const char *s) { + vec2 v = {0}; + sscanf(s, "%f,%f", &v.x, &v.y); + return v; +} +vec3 atof3(const char *s) { + vec3 v = {0}; + sscanf(s, "%f,%f,%f", &v.x, &v.y, &v.z); + return v; +} +vec4 atof4(const char *s) { + vec4 v = {0}; + sscanf(s, "%f,%f,%f,%f", &v.x, &v.y, &v.z, &v.w); + return v; +} + +char* ftoa(float f) { + return va("%f", f); +} +char* ftoa2(vec2 v) { + return va("%f,%f", v.x, v.y); +} +char* ftoa3(vec3 v) { + return va("%f,%f,%f", v.x, v.y, v.z); +} +char* ftoa4(vec4 v) { + return va("%f,%f,%f,%f", v.x, v.y, v.z, v.w); +} + +void swapf(float *a, float *b) { + float t = *a; *a = *b; *b = *a; +} +void swapf2(vec2 *a, vec2 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; +} +void swapf3(vec3 *a, vec3 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; + float z = a->z; a->z = b->z; b->z = a->z; +} +void swapf4(vec4 *a, vec4 *b) { + float x = a->x; a->x = b->x; b->x = a->x; + float y = a->y; a->y = b->y; b->y = a->y; + float z = a->z; a->z = b->z; b->z = a->z; + float w = a->w; a->w = b->w; b->w = a->w; +} + static uint64_t rand_xoro256(uint64_t x256_s[4]) { // xoshiro256+ 1.0 by David Blackman and Sebastiano Vigna (PD) const uint64_t result = x256_s[0] + x256_s[3]; const uint64_t t = x256_s[1] << 17; @@ -8429,7 +8474,8 @@ vec2 norm2 (vec2 a ) { return len2sq(a) == 0 ? a : scale2(a, 1 / vec2 norm2sq (vec2 a ) { return len2sq(a) == 0 ? a : scale2(a, 1 / len2sq(a)); } int finite2 (vec2 a ) { return FINITE(a.x) && FINITE(a.y); } vec2 mix2 (vec2 a,vec2 b,float t) { return add2(scale2((a),1-(t)), scale2((b), t)); } -vec2 clamp2(vec2 v,float a,float b){ return vec2(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a)); } +vec2 clamp2(vec2 v, vec2 a, vec2 b){ return vec2(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y)); } +vec2 clamp2f(vec2 v,float a,float b){ return vec2(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a)); } // ---------------------------------------------------------------------------- vec3 ptr3 (const float *a ) { return vec3(a[0],a[1],a[2]); } @@ -8459,7 +8505,8 @@ vec3 norm3 (vec3 a ) { return len3sq(a) == 0 ? a : scale3(a, 1 / vec3 norm3sq (vec3 a ) { return len3sq(a) == 0 ? a : scale3(a, 1 / len3sq(a)); } int finite3 (vec3 a ) { return finite2(vec2(a.x,a.y)) && FINITE(a.z); } vec3 mix3 (vec3 a,vec3 b,float t) { return add3(scale3((a),1-(t)), scale3((b), t)); } -vec3 clamp3(vec3 v,float a,float b){ return vec3(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a)); } +vec3 clamp3(vec3 v, vec3 a, vec3 b){ return vec3(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y),maxf(minf(b.z,v.z),a.z)); } +vec3 clamp3f(vec3 v,float a,float b){ return vec3(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a)); } //vec3 tricross3 (vec3 a, vec3 b, vec3 c) { return cross3(a,cross3(b,c)); } // useful? void ortho3 (vec3 *left, vec3 *up, vec3 v) { #if 0 @@ -8513,7 +8560,8 @@ vec4 norm4 (vec4 a ) { return len4sq(a) == 0 ? a : scale4(a, 1 / vec4 norm4sq (vec4 a ) { return len4sq(a) == 0 ? a : scale4(a, 1 / len4sq(a)); } int finite4 (vec4 a ) { return finite3(vec3(a.x,a.y,a.z)) && FINITE(a.w); } vec4 mix4 (vec4 a,vec4 b,float t) { return add4(scale4((a),1-(t)), scale4((b), t)); } -vec4 clamp4(vec4 v,float a,float b){ return vec4(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a),maxf(minf(b,v.w),a)); } +vec4 clamp4(vec4 v, vec4 a, vec4 b){ return vec4(maxf(minf(b.x,v.x),a.x),maxf(minf(b.y,v.y),a.y),maxf(minf(b.z,v.z),a.z),maxf(minf(b.w,v.w),a.w)); } +vec4 clamp4f(vec4 v,float a,float b){ return vec4(maxf(minf(b,v.x),a),maxf(minf(b,v.y),a),maxf(minf(b,v.z),a),maxf(minf(b,v.w),a)); } // vec4 cross4(vec4 v0, vec4 v1) { return vec34(cross3(v0.xyz, v1.xyz), (v0.w + v1.w) * 0.5f); } // may fail // ---------------------------------------------------------------------------- @@ -10326,6 +10374,9 @@ void shader_print(const char *source) { } } +// sorted by shader handle. an array of properties per shader. properties are plain strings. +static __thread map(unsigned, array(char*)) shader_reflect; + static GLuint shader_compile( GLenum type, const char *source ) { GLuint shader = glCreateShader(type); @@ -10451,9 +10502,140 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char } */ + // shader compiled fine, before returning, let's parse the source and reflect the uniforms + array(char*) props = 0; + do_once map_init_int( shader_reflect ); + if(vs) for each_substring(vs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if(fs) for each_substring(fs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if(gs) for each_substring(gs, "\r\n", line) { + if( strstr(line, "/""//") && !strbeg(line,"//") ) { + array_push(props, STRDUP(line)); + } + } + if( props ) { + map_insert(shader_reflect, program, props); + } + return program; } +unsigned shader_properties(unsigned shader) { + array(char*) *found = map_find(shader_reflect, shader); + return found ? array_count(*found) : 0; +} + +char** shader_property(unsigned shader, unsigned property) { + array(char*) *found = map_find(shader_reflect, shader); + return found ? &(*found)[property] : NULL; +} + +int ui_shader(unsigned shader) { + int changed = 0; + + unsigned num_properties = shader_properties(shader); + for( unsigned i = 0; i < num_properties; ++i ) { + char **ptr = shader_property(shader,i); + + const char *line = *ptr; // debug: ui_label(line); + char uniform[32], type[32], name[32]; + if( sscanf(line, "%s %s %s", uniform, type, name) != 3) continue; + + int is_color = !!strstri(name, "color"), top = is_color ? 1 : 10; + vec4 minv = strstr(line, "min:") ? atof4(strstr(line, "min:") + 4) : vec4(0,0,0,0); + vec4 setv = strstr(line, "set:") ? atof4(strstr(line, "set:") + 4) : vec4(0,0,0,0); + vec4 maxv = strstr(line, "max:") ? atof4(strstr(line, "max:") + 4) : vec4(top,top,top,top); + char* tip = strstr(line, "tip:"); tip = tip && tip[4] ? tip + 4 : 0; + char *label = !tip ? va("%c%s", name[0] - 32 * !!(name[0] >= 'a'), name+1) : + va("%c%s " ICON_MD_HELP "@%s", name[0] - 32 * !!(name[0] >= 'a'), name+1, tip); + + if(minv.x > maxv.x) swapf(&minv.x, &maxv.x); + if(minv.y > maxv.y) swapf(&minv.y, &maxv.y); + if(minv.z > maxv.z) swapf(&minv.z, &maxv.z); + if(minv.w > maxv.w) swapf(&minv.w, &maxv.w); + + // supports int,float,vec2/3/4,color3/4 + int touched = 0; + if( type[0] == 'i' ) { + int v = setv.x; + + if( (touched = ui_int(label, &v)) != 0 ) { + setv.x = clampi(v, minv.x, maxv.x); // min..max range + } + } + else if( type[0] == 'f' ) { + setv.x = (clampf(setv.x, minv.x, maxv.x) - minv.x) / (maxv.x - minv.x); + + if( (touched = ui_slider2(label, &setv.x, va("%5.2f", setv.x))) != 0 ) { + setv.x = clampf(minv.x + setv.x * (maxv.x-minv.x), minv.x, maxv.x); // min..max range + } + } + else if( type[0] == 'v' && type[3] == '2' ) { + setv.xy = clamp2(setv.xy,minv.xy,maxv.xy); + + if( (touched = ui_float2(label, &setv.x)) != 0 ) { + setv.xy = clamp2(setv.xy,minv.xy,maxv.xy); + } + } + else if( type[0] == 'v' && type[3] == '3' ) { + setv.xyz = clamp3(setv.xyz,minv.xyz,maxv.xyz); + + if( (touched = (is_color ? ui_color3f : ui_float3)(label, &setv.x)) != 0 ) { + setv.xyz = clamp3(setv.xyz,minv.xyz,maxv.xyz); + } + } + else if( type[0] == 'v' && type[3] == '4' ) { + setv = clamp4(setv,minv,maxv); + + if( (touched = (is_color ? ui_color4f : ui_float4)(label, &setv.x)) != 0 ) { + setv = clamp4(setv,minv,maxv); + } + } + + if( touched ) { + // send to shader + GLint shader_bak; glGetIntegerv(GL_CURRENT_PROGRAM, &shader_bak); + glUseProgram(shader); + /**/ if(type[0] == 'i') glUniform1i(glGetUniformLocation(shader, name), setv.x); + else if(type[0] == 'f') glUniform1f(glGetUniformLocation(shader, name), setv.x); + else if(type[3] == '2') glUniform2fv(glGetUniformLocation(shader, name), 1, &setv.x); + else if(type[3] == '3') glUniform3fv(glGetUniformLocation(shader, name), 1, &setv.x); + else if(type[3] == '4') glUniform4fv(glGetUniformLocation(shader, name), 1, &setv.x); + glUseProgram(shader_bak); + + // upgrade value + *ptr = FREE(*ptr); + *ptr = stringf("%s %s %s ///set:%s min:%s max:%s tip:%s", uniform,type,name,ftoa4(setv),ftoa4(minv),ftoa4(maxv),tip?tip:""); + + changed = 1; + } + } + + if(num_properties) ui_separator(); + + return changed; +} + +int ui_shaders() { + int changed = 0; + int has_menu = ui_has_menubar(); + if( (has_menu ? ui_window("Shaders", 0) : ui_panel("Shaders", 0) ) ) { + for each_map_ptr(shader_reflect, unsigned, k, array(char*), v) { + ui_section(va("Shader %d",*k)); + changed |= ui_shader(*k); + } + (has_menu ? ui_window_end : ui_panel_end)(); + } + return changed; +} + unsigned compute(const char *cs){ #if is(ems) return 0; @@ -13111,16 +13293,6 @@ void* screenshot_async( int n ) { // 3 RGB, 4 RGBA, -3 BGR, -4 BGRA // ----------------------------------------------------------------------------- // viewports -void viewport_color3(vec3 color3) { - glClearColor(color3.x, color3.y, color3.z, 1); -} -void viewport_color(uint32_t rgba) { - float b = ((rgba >> 0) & 255) / 255.f; - float g = ((rgba >> 8) & 255) / 255.f; - float r = ((rgba >> 16) & 255) / 255.f; - glClearColor(r, g, b, 1); -} - void viewport_clear(bool color, bool depth) { glClearDepthf(1); glClearStencil(0); @@ -13221,6 +13393,8 @@ void postfx_clear(postfx *fx); char* postfx_name(postfx *fx, int slot); +int ui_postfx(postfx *fx, int slot); + struct passfx { mesh_t m; char *name; @@ -13363,6 +13537,14 @@ void postfx_clear(postfx *fx) { fx->mask = fx->enabled = 0; } +int ui_postfx(postfx *fx, int pass) { + int on = ui_enabled(); + ui_enable( postfx_enabled(fx,pass) ); + int rc = ui_shader(fx->pass[pass].program); + ui_enable( on ); + return rc; +} + static __thread array(handle) last_fb; bool postfx_begin(postfx *fx, int width, int height) { @@ -13488,6 +13670,9 @@ bool postfx_end(postfx *fx) { if(is_depth_test_enabled); glEnable(GL_DEPTH_TEST); + // restore clear color: needed in case transparent window is being used (alpha != 0) + glClearColor(0,0,0,1); // @transparent + return true; } @@ -13530,6 +13715,9 @@ char *fx_name(int pass) { int fx_find(const char *name) { return postfx_find(&fx, name); } +int ui_fx(int pass) { + return ui_postfx(&fx, pass); +} // ----------------------------------------------------------------------------- // brdf @@ -14794,7 +14982,7 @@ anims_t animations(const char *pathfile, int flags) { char anim_name[128] = {0}; if( sscanf(anim, "%*s %d-%d %127[^\r\n]", &from, &to, anim_name) != 3) continue; array_push(a.anims, !!strstri(anim_name, "loop") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] - array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); + array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); // @leak } a.speed = 1.0; return a; @@ -14899,7 +15087,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) { vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f}; glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x); // config vertex data - glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); // feed vertex data glDrawArrays(mode, 0, count); @@ -14931,7 +15119,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) { vec3 rgbf = {((rgb>>16)&255)/255.f,((rgb>>8)&255)/255.f,((rgb>>0)&255)/255.f}; glUniform3fv(dd_u_color, GL_TRUE, &rgbf.x); // config vertex data - glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * 3 * 4, list, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); // feed vertex data glDrawArrays(mode, 0, count); @@ -15017,7 +15205,7 @@ void ddraw_ground_(float scale) { // 10x10 ddraw_line(vec3(-scale,0,i), vec3(+scale,0,i)); // horiz ddraw_line(vec3(i,0,-scale), vec3(i,0,+scale)); // vert } - ddraw_color( GRAY ); // inner + ddraw_color( RGB3(149,149,149) ); // inner, light grey for( float i = -scale + scale/10, c = 1; c < 20; ++c, i += (scale/10) ) { ddraw_line_thin(vec3(-scale,0,i), vec3(+scale,0,i)); // horiz ddraw_line_thin(vec3(i,0,-scale), vec3(i,0,+scale)); // vert @@ -15561,7 +15749,7 @@ void ddraw_init() { do_once { for( int i = 0; i < 2; ++i ) for( int j = 0; j < 3; ++j ) map_init(dd_lists[i][j], less_int, hash_int); - dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", ""); + dd_program = shader(dd_vs,dd_fs,"att_position","fragcolor", NULL); dd_u_color = glGetUniformLocation(dd_program, "u_color"); ddraw_flush(); // alloc vao & vbo, also resets color } @@ -16448,11 +16636,11 @@ const char * app_exec( const char *cmd ) { return snprintf(output, 16, "%-15d", rc), buf[-1] = ' ', output; } -void app_spawn( const char *cmd ) { - if( !cmd[0] ) return; +int app_spawn( const char *cmd ) { + if( !cmd[0] ) return -1; cmd = file_normalize(cmd); - system(cmd); + return system(cmd); } #if is(osx) @@ -17545,7 +17733,7 @@ static void nk_config_custom_fonts() { // nk_style_load_all_cursors(ctx, atlas->cursors); glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); } -static void nk_config_custom_style() { +static void nk_config_custom_theme() { #ifdef UI_HUE float default_hue = UI_HUE; #else @@ -17594,13 +17782,6 @@ table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = hover_hue; // nk_rgba(255, 0, 0, 255); // table[NK_COLOR_SELECT] = nk_rgba(57, 67, 61, 255); // table[NK_COLOR_SELECT_ACTIVE] = main; - // @transparent - #if !is(ems) - if( glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE ) - for(int i = 0; i < countof(table); ++i) table[i].a = 255; // table[i].a ? 255 : 0; - #endif - // @transparent - nk_style_default(ui_ctx); nk_style_from_table(ui_ctx, table); @@ -17825,7 +18006,7 @@ static map(char*,unsigned) ui_windows = 0; static void ui_init() { do_once { nk_config_custom_fonts(); - nk_config_custom_style(); + nk_config_custom_theme(); map_init(ui_windows, less_str, hash_str); } @@ -18175,71 +18356,6 @@ int ui_enable_(int enabled) { off.window.header.normal.data.color.a *= alpha; off.window.header.hover.data.color.a *= alpha; off.window.header.active.data.color.a *= alpha; - - // @transparent { - // fixes for transparent windows - #if !is(ems) - float hsva[4]; - if( glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE ) { - #define fix(col) off.col = nk_rgba_cf(nk_hsva_colorfv( (nk_colorf_hsva_fv(hsva, nk_color_cf(on.col)),hsva[1] *= alpha,hsva[2] *= alpha, hsva) )) - fix(contextual_button.normal.data.color); - fix(menu_button.normal.data.color); - fix(option.normal.data.color); - fix(option.cursor_normal.data.color); - fix(checkbox.normal.data.color); - fix(checkbox.cursor_normal.data.color); - fix(selectable.normal.data.color); - fix(selectable.normal_active.data.color); - fix(slider.normal.data.color); - fix(slider.bar_normal); - fix(slider.cursor_normal.data.color); - fix(slider.dec_button.normal.data.color); - fix(slider.inc_button.normal.data.color); - fix(progress.normal.data.color); - fix(progress.cursor_normal.data.color); - fix(property.normal.data.color); - fix(property.label_normal); - fix(property.edit.normal.data.color); - fix(property.edit.cursor_normal); - fix(property.edit.selected_normal); - fix(property.dec_button.normal.data.color); - fix(property.inc_button.normal.data.color); - fix(edit.normal.data.color); - fix(edit.cursor_normal); - fix(edit.selected_normal); - fix(scrollh.normal.data.color); - fix(scrollh.cursor_normal.data.color); - fix(scrollv.normal.data.color); - fix(scrollv.cursor_normal.data.color); - fix(combo.normal.data.color); - fix(combo.label_normal); - fix(combo.symbol_normal); - fix(combo.button.normal.data.color); - fix(window.header.normal.data.color); - fix(button.normal.data.color); - #undef fix - #define fix(field) on.field.a = off.field.a = 0 - fix(button.border_color); - fix(button.border_color); - fix(button.border_color); - fix(contextual_button.border_color); - fix(menu_button.border_color); - fix(option.border_color); - fix(checkbox.border_color); - fix(slider.border_color); - fix(progress.border_color); - fix(property.border_color); - fix(edit.border_color); - fix(chart.border_color); - fix(scrollh.border_color); - fix(scrollv.border_color); - fix(tab.border_color); - fix(combo.border_color); - fix(window.border_color); - #undef fix - } - #endif - // } @transparent } static struct nk_input input; if (!enabled) { @@ -18256,11 +18372,11 @@ int ui_enable_(int enabled) { } static int ui_is_enabled = 1; -int ui_enable() { - return ui_is_enabled ? 0 : ui_enable_(ui_is_enabled = 1); +int ui_enable(int on) { + return ui_is_enabled == on ? 0 : ui_enable_(ui_is_enabled = on); } -int ui_disable() { - return ui_is_enabled ? ui_enable_(ui_is_enabled = 0) ^ 1 : 0; +int ui_enabled() { + return ui_is_enabled; } static @@ -18278,7 +18394,7 @@ void ui_create() { nk_glfw3_new_frame(&nk_glfw); //g->nk_glfw); ui_dirty = 0; - ui_enable(); + ui_enable(1); } } @@ -18353,7 +18469,11 @@ void ui_render() { * Make sure to either a.) save and restore or b.) reset your own state after * rendering the UI. */ //nk_sdl_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); + + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); // @transparent nk_glfw3_render(&nk_glfw, NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); // @transparent + #if is(ems) glFinish(); #endif @@ -19062,13 +19182,6 @@ int ui_button_transparent(const char *text) { static int ui_button_(const char *text) { - // @transparent - static bool transparency_fix_needed = 0; ifndef(ems, do_once transparency_fix_needed = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); - const float dim = transparency_fix_needed && ui_alpha < 1 ? 0.5 : 1; - const float dim_alpha = transparency_fix_needed ? 1.0 : 0.90*ui_alpha; - const float text_alpha = transparency_fix_needed ? 1.0 : ui_alpha; - // @transparent - if( 1 ) { #if UI_BUTTON_MONOCHROME nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba(0,0,0,ui_alpha)); @@ -19087,13 +19200,13 @@ int ui_button_(const char *text) { nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,1.00,1.0*ui_alpha)); nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.60,0.4*ui_alpha)); #else // new - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba_f(0.00,0.00,0.00,text_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_hover, nk_rgba_f(0.11,0.11,0.11,text_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_active, nk_rgba_f(0.00,0.00,0.00,text_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba_f(0.00,0.00,0.00,ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_hover, nk_rgba_f(0.11,0.11,0.11,ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_active, nk_rgba_f(0.00,0.00,0.00,ui_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.normal.data.color, nk_hsva_f(ui_hue,0.80*dim,0.6*dim,dim_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,0.85*dim,0.9*dim,dim_alpha)); - nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.80*dim,0.6*dim,dim_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.normal.data.color, nk_hsva_f(ui_hue,0.80,0.6,0.90*ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.hover.data.color, nk_hsva_f(ui_hue,0.85,0.9,0.90*ui_alpha)); + nk_style_push_color(ui_ctx, &ui_ctx->style.button.active.data.color, nk_hsva_f(ui_hue,0.80,0.6,0.90*ui_alpha)); #endif } @@ -19754,7 +19867,7 @@ int ui_demo(int do_windows) { if(choice == 2) ui_notify(va("My random toast (%d)", rand()), va("This is notification #%d", ++hits)); if(choice == 3) disable_all ^= 1; - if( disable_all ) ui_disable(); + if( disable_all ) ui_enable(0); if( ui_browse(&browsed_file, &show_browser) ) puts(browsed_file); @@ -19803,7 +19916,7 @@ int ui_demo(int do_windows) { if( ui_buttons(3, "yes", "no", "maybe") ) { puts("button clicked"); } if( ui_dialog("my dialog", __FILE__ "\n" __DATE__ "\n" "Public Domain.", 2/*two buttons*/, &show_dialog) ) {} - if( disable_all ) ui_enable(); + if( disable_all ) ui_enable(1); ui_panel_end(); } @@ -20699,6 +20812,8 @@ int window_frame_begin() { ui_create(); profile_render(); + + ui_shaders(); #if 0 // deprecated // run user-defined hooks diff --git a/engine/v4k.h b/engine/v4k.h index 1aa4eeb..6eb8221 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -988,7 +988,8 @@ API float len2 (vec2 a ); API vec2 norm2 (vec2 a ); API int finite2 (vec2 a ); API vec2 mix2 (vec2 a,vec2 b,float t); -API vec2 clamp2(vec2 v,float a,float b); +API vec2 clamp2(vec2 v,vec2 a,vec2 b); +API vec2 clamp2f(vec2 v,float a,float b); // ---------------------------------------------------------------------------- API vec3 rnd3 (void); // @todo: rnd2,rnd4,rndq @@ -1019,7 +1020,8 @@ API vec3 norm3 (vec3 a ); API vec3 norm3sq (vec3 a ); API int finite3 (vec3 a ); API vec3 mix3 (vec3 a,vec3 b,float t); -API vec3 clamp3(vec3 v,float a,float b); +API vec3 clamp3(vec3 v,vec3 a,vec3 b); +API vec3 clamp3f(vec3 v,float a,float b); //vec3 tricross3 (vec3 a, vec3 b, vec3 c); API void ortho3 (vec3 *left, vec3 *up, vec3 v); @@ -1055,7 +1057,8 @@ API vec4 norm4 (vec4 a ); API vec4 norm4sq (vec4 a ); API int finite4 (vec4 a ); API vec4 mix4 (vec4 a,vec4 b,float t); -API vec4 clamp4(vec4 v,float a,float b); +API vec4 clamp4(vec4 v,vec4 a,vec4 b); +API vec4 clamp4f(vec4 v,float a,float b); // vec4 cross4(vec4 v0, vec4 v1); // ---------------------------------------------------------------------------- @@ -1157,7 +1160,7 @@ API vec4 transform444(const mat44 m, const vec4 p); API bool unproject44(vec3 *out, vec3 xyd, vec4 viewport, mat44 mvp); // ---------------------------------------------------------------------------- -// !!! for debugging +// debugging and utils API void print2( vec2 v ); API void print3( vec3 v ); @@ -1166,6 +1169,21 @@ API void printq( quat q ); API void print33( float *m ); API void print34( float *m ); API void print44( float *m ); + +API vec2 atof2(const char *s); +API vec3 atof3(const char *s); +API vec4 atof4(const char *s); + +API char* ftoa(float f); +API char* ftoa2(vec2 v); +API char* ftoa3(vec3 v); +API char* ftoa4(vec4 v); + +API void swapf(float *a, float *b); +API void swapf2(vec2 *a, vec2 *b); +API void swapf3(vec3 *a, vec3 *b); +API void swapf4(vec4 *a, vec4 *b); + #line 0 @@ -2473,7 +2491,8 @@ API float alpha( unsigned rgba ); #define ORANGE RGB3( 255,144,48 ) #define PURPLE RGB3( 102,77,102 ) // 178,128,255 ) #define YELLOW RGB3( 255,224,0 ) -#define GRAY RGB3( 32, 32, 32 ) // 149,149,149 ) +#define GRAY RGB3( 32,32,32 ) // dark gray +#define SILVER RGB3( 149,149,149 ) // dark white, gray-ish #define PINK RGB3( 255,48,144 ) #define AQUA RGB3( 48,255,144 ) @@ -2770,6 +2789,14 @@ API void shader_colormap(const char *name, colormap_t cm); API unsigned shader_get_active(); API void shader_destroy(unsigned shader); +// reflection. [0..N] are shader properties + +API unsigned shader_properties(unsigned shader); +API char** shader_property(unsigned shader, unsigned property_no); + +API int ui_shader(unsigned shader); +API int ui_shaders(); + // compute shaders enum BUFFER_MODE { BUFFER_READ, @@ -3096,8 +3123,6 @@ API int skybox_pop_state(); // @to deprecate // ----------------------------------------------------------------------------- // post-fxs -API void viewport_color(uint32_t color); // background(uint32_t) instead? -API void viewport_color3(vec3 color); // background3(vec3) instead? API void viewport_clear(bool color, bool depth); API void viewport_clip(vec2 from, vec2 to); @@ -3112,6 +3137,8 @@ API void fx_enable_all(int enabled); API char * fx_name(int pass); API int fx_find(const char *name); +API int ui_fx(int pass); + // ----------------------------------------------------------------------------- // utils @@ -3435,7 +3462,7 @@ API void tty_attach(); API void tty_detach(); API const char* app_exec(const char *command); // returns ("%15d %s", retcode, output_last_line) -API void app_spawn(const char *command); +API int app_spawn(const char *command); API int app_cores(); API int app_battery(); /// return battery level [1..100]. also positive if charging (+), negative if discharging (-), and 0 if no battery is present. @@ -3579,8 +3606,8 @@ API int ui_window_end(); API int ui_show(const char *panel_or_window_title, int enabled); API int ui_dims(const char *panel_or_window_title, float width, float height); API int ui_visible(const char *panel_or_window_title); // @todo: include ui_collapse() items that are open as well? -API int ui_enable(); -API int ui_disable(); +API int ui_enable(int on); +API int ui_enabled(); API vec2 ui_get_dims(); API int ui_has_menubar(); diff --git a/tools/cook.ini b/tools/cook.ini index 969fb7d..501682a 100644 --- a/tools/cook.ini +++ b/tools/cook.ini @@ -1,4 +1,4 @@ -; this is where you specify and configure the FWK pipeline. +; this is where you specify and configure the V4K pipeline. ; tweak the pipeline and add new importers just by editing this file. ; there is no flow control in this script file: lines are parsed and evaluated, from top to bottom.