diff --git a/MAKE.bat b/MAKE.bat index 971cdb9..78e0735 100644 --- a/MAKE.bat +++ b/MAKE.bat @@ -372,7 +372,7 @@ set other= set v4k=yes set hello=no set demos=no -set extras=no +set lab=no set editor=no set vis=no set proj=no @@ -402,12 +402,12 @@ set run=no if "%1"=="nov4k" set "v4k=no" && goto loop if "%1"=="nodemos" set "demos=no" && goto loop if "%1"=="demos" set "demos=yes" && set "hello=no" && goto loop - if "%1"=="extras" set "extras=yes" && set "hello=no" && goto loop + if "%1"=="lab" set "lab=yes" && set "hello=no" && goto loop if "%1"=="noeditor" set "editor=no" && goto loop if "%1"=="hello" set "hello=yes" && goto loop if "%1"=="editor" set "editor=yes" && set "v4k=no" && set "hello=no"&& goto loop if "%1"=="run" set "run=yes" && goto loop - if "%1"=="all" set "v4k=yes" && set "demos=yes" && set "extras=yes" && set "editor=yes" && set "hello=yes" && goto loop + if "%1"=="all" set "v4k=yes" && set "demos=yes" && set "lab=yes" && set "editor=yes" && set "hello=yes" && goto loop if "%1"=="tcc" set "cc=%1" && goto loop if "%1"=="cl" set "cc=%1" && goto loop @@ -646,8 +646,8 @@ if "!demos!"=="yes" ( !echo! 07-network && !cc! !o! 07-network.exe demos\07-network.c !import! !args! || set rc=1 ) -rem extras -if "!extras!"=="yes" ( +rem lab +if "!lab!"=="yes" ( for %%f in ("demos\99-*") do ( !echo! %%~nf && !cc! !o! %%~nf.exe demos\%%~nf.c !import! !args! || set rc=1 ) diff --git a/demos/00-loop.c b/demos/00-loop.c new file mode 100644 index 0000000..5ae1497 --- /dev/null +++ b/demos/00-loop.c @@ -0,0 +1,9 @@ +#include "v4k.h" // Minimal C sample + +int main() { + window_create(75.0, 0); // 75% size, no extra flags + + while( window_swap() && !input(KEY_ESC) ) { // game loop + puts("hello V4K from C!"); + } +} \ No newline at end of file diff --git a/demos/99-script.c b/demos/00-script.c similarity index 82% rename from demos/99-script.c rename to demos/00-script.c index dc0c3af..175090d 100644 --- a/demos/99-script.c +++ b/demos/00-script.c @@ -25,4 +25,7 @@ int main() { end; end; )); + + // script test (lua) + script_run( "-- Bye.lua\nio.write(\"script test: Bye world!, from \", _VERSION, \"\\n\")" ); } diff --git a/demos/00-ui.c b/demos/00-ui.c index 0287248..7035670 100644 --- a/demos/00-ui.c +++ b/demos/00-ui.c @@ -2,8 +2,8 @@ // - rlyeh, public domain. // // Compile with: -// `make demos\00-ui.c` (windows) -// `sh MAKE.bat demos/00-ui.c` (linux, osx) +// `make demos\01-ui.c` (windows) +// `sh MAKE.bat demos/01-ui.c` (linux, osx) #include "v4k.h" @@ -19,7 +19,7 @@ int main() { window_fps_lock(app_target_fps); // load video - video_t *v = video( "pexels-pachon-in-motion-17486489.mp4", VIDEO_RGB ); + video_t *v = video( "pexels-pachon-in-motion-17486489.mp4", VIDEO_RGB | VIDEO_LOOP ); // app loop while( window_swap() ) { diff --git a/demos/01-demo2d.c b/demos/01-demo2d.c new file mode 100644 index 0000000..53ceab8 --- /dev/null +++ b/demos/01-demo2d.c @@ -0,0 +1,159 @@ +// 2d demo: window, audio, camera, font, tiled, render, fx, spritesheet, input, ui. @todo: spine +// - rlyeh, public domain. +// +// Compile with: +// `make demos\01-demo2d.c` (windows) +// `sh MAKE.bat demos/01-demo2d.c` (linux, osx) + +#include "v4k.h" + +void demo_kids(vec3 offs) { + // init + static texture_t kids; do_once kids = texture( "spriteSheetExample.png", TEXTURE_LINEAR ); + static vec3 pos[2] = {{490,362},{442,362}}, vel[2] = {0}; + static int row[2] = {0,3}, frame[2] = {0}; + static int inputs[2][4] = {{KEY_W,KEY_A,KEY_S,KEY_D},{KEY_UP,KEY_LEFT,KEY_DOWN,KEY_RIGHT}}; + + // move + for( int i = 0; i < countof(pos); ++i ) { + vel[i].x = input(inputs[i][3]) - input(inputs[i][1]); + vel[i].y = input(inputs[i][2]) - input(inputs[i][0]); + pos[i].x = fmod(pos[i].x + vel[i].x, window_width() + 128); + pos[i].y = fmod(pos[i].y + vel[i].y, window_height() + 128); + frame[i] += vel[i].x || vel[i].y; + } + + // render + for( int i = 0; i < countof(pos); ++i ) { + int col = frame[i] / 10, num_frame = row[i] * 4 + col % 4; // 4x4 tilesheet + float position[3] = {pos[i].x,pos[i].y,pos[i].y}, offset[2]={0,0}, scale[2]={0.5,0.5}; + float spritesheet[3]={num_frame,4,4}; + sprite_sheet(kids, + spritesheet, // num_frame in a 4x4 spritesheet + position, 0, // position(x,y,depth:sort-by-Y), angle + offset, scale, // offset(x,y), scale(x,y) + false, WHITE, false // is_additive, tint color, resolution-independent + ); + } +} + +void demo_hud() { + // draw pixel-art hud, 16x16 ui element, scaled and positioned in resolution-independant way + static texture_t inputs; do_once inputs = texture( "prompts_tilemap_34x24_16x16x1.png", TEXTURE_LINEAR ); + float spritesheet[3] = {17,34,24}, offset[2] = {0, - 2*absf(sin(window_time()*5))}; // sprite cell and animation + float scale[2] = {3, 3}, tile_w = 16 * scale[0], tile_h = 16 * scale[1]; // scaling + float position[3] = {window_width() - tile_w, window_height() - tile_h, window_height() }; // position in screen-coordinates (x,y,z-index) + sprite_sheet(inputs, spritesheet, position, 0/*deg*/, offset, scale, false, WHITE, 1); +} + +int main() { + // window (80% sized, MSAA x4 flag) + window_create(80.0, WINDOW_MSAA4); + window_title(__FILE__); + + // tiled map + tiled_t tmx = tiled(vfs_read("castle.tmx")); + // tmx.parallax = true; + + // spine model + //spine_t *spn = spine("goblins.json", "goblins.atlas", 0); + + // camera 2d + camera_t cam = camera(); + cam.position = vec3(window_width()/2, window_height()/2, 3); // at(CX,CY) zoom(x3) + camera_enable(&cam); + + // audio (both clips & streams) + audio_t clip1 = audio_clip( "coin.wav" ); + audio_t clip2 = audio_clip( "pew.sfxr" ); + audio_t stream1 = audio_stream( "larry.mid" ); + audio_t stream2 = audio_stream( "waterworld-map.fur" ); + audio_t BGM = stream1; + audio_play(BGM, 0); + + // font config: faces (6 max) and colors (10 max) + #define FONT_CJK FONT_FACE3 + #define FONT_YELLOW FONT_COLOR2 + #define FONT_LIME FONT_COLOR3 + font_face(FONT_CJK, "mplus-1p-medium.ttf", 48.f, FONT_JP|FONT_2048); // CJK|FONT_2048|FONT_OVERSAMPLE_Y); + font_color(FONT_YELLOW, RGB4(255,255,0,255)); + font_color(FONT_LIME, RGB4(128,255,0,255)); + + // fx: load all post fx files in all subdirs. enable a few filters by default + fx_load("fx**.fs"); + fx_enable(fx_find("fxCRT2.fs"), 1); + fx_enable(fx_find("fxGrain.fs"), 1); + fx_enable(fx_find("fxContrast.fs"), 1); + fx_enable(fx_find("fxVignette.fs"), 1); + + // demo loop + while (window_swap() && !input_down(KEY_ESC)) { + + // handle input + if( input_down(KEY_F5) ) window_reload(); + if( input_down(KEY_F11) ) window_fullscreen( !window_has_fullscreen() ); + + // camera panning (x,y) & zooming (z) + if( !ui_hover() && !ui_active() ) { + if( input(MOUSE_L) ) cam.position.x += input_diff(MOUSE_X); + if( input(MOUSE_L) ) cam.position.y += input_diff(MOUSE_Y); + cam.position.z += input_diff(MOUSE_W) * 0.1; + } + + // apply post-fxs from here + fx_begin(); + + profile("Rendering") { + vec3 center = add3(cam.position,vec3(-window_width()/1,-window_height()/2,0)); + // render tiled map + tiled_render(tmx, center); + // + demo_kids(vec3(0,0,1)); + demo_hud(); + // render spine model + // spine_animate(spn, !window_has_pause() * window_delta()); + // spine_render(spn, vec3(cam.position.x, cam.position.y, 1), true ); + // sprite_flush(); + } + + // subtitle sample + font_print( + FONT_BOTTOM FONT_CENTER + FONT_CJK FONT_H1 + FONT_YELLOW "私はガラスを食べられます。" FONT_LIME "それは私を傷つけません。\n" + ); + + // post-fxs end here + fx_end(); + + // ui + if( ui_panel("Audio", 0)) { + static float bgm = 1, sfx = 1, master = 1; + if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm); + if( ui_slider2("SFX", &sfx, va("%.2f", sfx))) audio_volume_clip(sfx); + if( ui_slider2("Master", &master, va("%.2f", master))) audio_volume_master(master); + if( ui_label2_toolbar("BGM: Track #1", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream1, AUDIO_SINGLE_INSTANCE); + if( ui_label2_toolbar("BGM: Track #2", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream2, AUDIO_SINGLE_INSTANCE); + if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(clip1, 0); + if( ui_label2_toolbar("SFX: Pew", ICON_MD_VOLUME_UP)) audio_play(clip2, 0); + ui_panel_end(); + } + if( ui_panel("Tiled", 0)) { + ui_float("Zoom in", &cam.position.z); + tiled_ui(&tmx); + ui_panel_end(); + } + /*if( ui_panel("Spine", 0)) { + spine_ui(spn); + ui_panel_end(); + }*/ + } +} + +// this demo supersedes following old sources: +// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-audio.c +// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-font.c +// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-spine.c +// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-sprite.c +// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-tiled.c +// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-tilemap.c diff --git a/demos/99-easing.c b/demos/01-easing.c similarity index 100% rename from demos/99-easing.c rename to demos/01-easing.c diff --git a/demos/99-font.c b/demos/01-font.c similarity index 91% rename from demos/99-font.c rename to demos/01-font.c index a81399b..747e74e 100644 --- a/demos/99-font.c +++ b/demos/01-font.c @@ -1,7 +1,7 @@ #include "v4k.h" int main() { - window_create(0.75, WINDOW_MSAA8); + window_create(75.0, WINDOW_MSAA8); // style: our aliases #define FONT_REGULAR FONT_FACE1 @@ -24,11 +24,11 @@ int main() { #define FONT_TINY FONT_H6 // style: atlas size, unicode ranges and font faces (up to 6 faces) - font_face(FONT_REGULAR, "Carlito-Regular.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048); - font_face(FONT_ITALIC, "Carlito-Italic.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048); - font_face(FONT_BOLD, "Carlito-Bold.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048); + font_face(FONT_REGULAR, "B612""-Regular.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048); + font_face(FONT_ITALIC, "B612""-Italic.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048); + font_face(FONT_BOLD, "B612""-Bold.ttf", 48.f, FONT_EU|FONT_AR|FONT_RU|FONT_2048); font_face(FONT_JAPANESE, "mplus-1p-medium.ttf", 48.f, FONT_JP|FONT_2048); // CJK|FONT_2048|FONT_OVERSAMPLE_Y); - font_face(FONT_MONOSPACE, "Inconsolata-Regular.ttf", 24.f, FONT_EU|FONT_512); + font_face(FONT_MONOSPACE, "B612Mono""-Regular.ttf", 24.f, FONT_EU|FONT_512); // style: colors (up to 10 colors) font_color(FONT_GRAY, RGB4(100,100,100,255)); diff --git a/demos/01-sprite.c b/demos/01-sprite.c index 121dcf4..4e65c4d 100644 --- a/demos/01-sprite.c +++ b/demos/01-sprite.c @@ -1,167 +1,218 @@ -// sprite demo: window, audio, camera, font, tiled, render, fx, spritesheet, input, ui. @todo: finish spine -// - rlyeh, public domain. +// sprite routines +// - rlyeh, // -// Compile with: -// `make demos\01-sprite.c` (windows) -// `sh MAKE.bat demos/01-sprite.c` (linux, osx) +// credits: original lovely demo by rxi (MIT License). +// see https://github.com/rxi/autobatch/tree/master/demo/cats #include "v4k.h" -void demo_kids(vec3 offs) { +texture_t kids, catImage, shadowImage, inputs; +int NUM_SPRITES = 100, NUM_SPRITES_CHANGED = 1; + +typedef struct Cat { + int cat, flip; + double x, y; + double vx, vy; + double animSpeed; + double moveTimer; + double elapsed; +} Cat; + +void demo_cats() { + static array(Cat) cats = 0; + // init - static texture_t kids; do_once kids = texture( "spriteSheetExample.png", TEXTURE_LINEAR ); - static vec3 pos[2] = {{490,362},{442,362}}, vel[2] = {0}; - static int row[2] = {0,3}, frame[2] = {0}; - static int inputs[2][4] = {{KEY_W,KEY_A,KEY_S,KEY_D},{KEY_UP,KEY_LEFT,KEY_DOWN,KEY_RIGHT}}; + if( NUM_SPRITES_CHANGED ) { + NUM_SPRITES_CHANGED = 0; + + array_resize(cats, NUM_SPRITES); int i = 0; + for each_array_ptr(cats, Cat, c) { + randset(i++); + c->x = randf() * window_width(); + c->y = randf() * window_height(); + c->vx = c->vy = 0; + c->cat = randi(0, 4); + c->flip = randf() < 0.5; + c->animSpeed = 0.8 + randf() * 0.3; + c->moveTimer = 0; + c->elapsed = 0; + } + } // move - for( int i = 0; i < countof(pos); ++i ) { - vel[i].x = input(inputs[i][3]) - input(inputs[i][1]); - vel[i].y = input(inputs[i][2]) - input(inputs[i][0]); - pos[i].x = fmod(pos[i].x + vel[i].x, window_width() + 128); - pos[i].y = fmod(pos[i].y + vel[i].y, window_height() + 128); - frame[i] += vel[i].x || vel[i].y; + const float dt = 1/120.f; + const int appw = window_width(), apph = window_height(); + + enum { yscale = 1 }; + for( int i = 0; i < NUM_SPRITES; ++i ) { + Cat *c = &cats[i]; + // Add velocity to position //and wrap to screen + c->x += yscale * c->vx * dt; // % ; + c->y += yscale * c->vy * dt; // % (int)window_height(); + if( c->x < 0 ) c->x += appw; else if( c->x > appw ) c->x -= appw; + if( c->y < 0 ) c->y += apph; else if( c->y > apph ) c->y -= apph; + // Faster animation if walking + int boost = c->vx == 0 && c->vy == 0 ? 1 : 3; + // Update elapsed time + c->elapsed += dt * boost; + // Update move timer -- if we hit zero then change or zero velocity + c->moveTimer -= dt * boost; + if (c->moveTimer < 0) { + if (randf() < .2) { + c->vx = (randf() * 2 - 1) * 30 * 2; + c->vy = (randf() * 2 - 1) * 15 * 2; + c->flip = c->vx < 0; + } else { + c->vx = c->vy = 0; + } + c->moveTimer = 1 + randf() * 5; + } } // render - for( int i = 0; i < countof(pos); ++i ) { - int col = frame[i] / 10, num_frame = row[i] * 4 + col % 4; // 4x4 tilesheet - float position[3] = {pos[i].x,pos[i].y,pos[i].y}, offset[2]={0,0}, scale[2]={0.5,0.5}; - float spritesheet[3]={num_frame,4,4}; - sprite_sheet(kids, - spritesheet, // num_frame in a 4x4 spritesheet - position, 0, // position(x,y,depth:sort-by-Y), angle - offset, scale, // offset(x,y), scale(x,y) - false, WHITE, false // is_additive, tint color, resolution-independent + uint32_t white = rgba(255,255,255,255); + uint32_t alpha = rgba(255,255,255,255*0.6); + for( int i = 0; i < NUM_SPRITES; ++i ) { + Cat *c = &cats[i]; + // Get current animation frame (8x4 tilesheet) + double e = c->elapsed * c->animSpeed; + double frame_num = c->cat * 8 + floor( ((int)(e * 8)) % 4 ); + frame_num = c->vx != 0 || c->vy != 0 ? frame_num + 4 : frame_num; + // Get x scale based on flip flag + int xscale = yscale * (c->flip ? -1 : 1); + // Draw + float angle = 0; //fmod(window_time()*360/5, 360); + float scale[2] = { 2*xscale, 2*yscale }; + float position[3] = { c->x,c->y,c->y }, no_offset[2] = {0,0}, spritesheet[3] = { frame_num,8,4 }; + sprite_sheet(catImage, + spritesheet, // frame_number in a 8x4 spritesheet + position, angle, // position(x,y,depth: sort by Y), angle + no_offset, scale, // offset(x,y), scale(x,y) + 0,white,0 // is_additive, tint color, resolution independant + ); + float position_neg_sort[3] = { c->x,c->y,-c->y }, offset[2] = {-1,5}, no_spritesheet[3] = {0,0,0}; + sprite_sheet(shadowImage, + no_spritesheet, // no frame_number (0x0 spritesheet) + position_neg_sort, angle, // position(x,y,depth: sort by Y), angle + offset, scale, // offset(x,y), scale(x,y) + 0,alpha,0 // is_additive, tint color, resolution independant ); } } -void demo_hud() { - // draw pixel-art hud, 16x16 ui element, scaled and positioned in resolution-independant way - static texture_t inputs; do_once inputs = texture( "prompts_tilemap_34x24_16x16x1.png", TEXTURE_LINEAR ); - float spritesheet[3] = {17,34,24}, offset[2] = {0, - 2*absf(sin(window_time()*5))}; // sprite cell and animation - float scale[2] = {3, 3}, tile_w = 16 * scale[0], tile_h = 16 * scale[1]; // scaling - float position[3] = {window_width() - tile_w, window_height() - tile_h, window_height() }; // position in screen-coordinates (x,y,z-index) - sprite_sheet(inputs, spritesheet, position, 0/*deg*/, offset, scale, false, WHITE, 1); +void demo_kids() { + static int angle; //++angle; + static int *x, *y, *v; + + // init + if( NUM_SPRITES_CHANGED ) { + NUM_SPRITES_CHANGED = 0; + + y = (int*)REALLOC(y, 0 ); + x = (int*)REALLOC(x, NUM_SPRITES * sizeof(int) ); + y = (int*)REALLOC(y, NUM_SPRITES * sizeof(int) ); + v = (int*)REALLOC(v, NUM_SPRITES * sizeof(int) ); + for( int i = 0; i < NUM_SPRITES; ++i ) { + randset(i); + x[i] = randi(0, window_width()); + y[i] = randi(0, window_height()); + v[i] = randi(1, 3); + } + } + + // config + const int appw = window_width(), apph = window_height(); + + // move & render + for( int i = 0; i < NUM_SPRITES; ++i ) { + y[i] = (y[i] + v[i]) % (apph + 128); + int col = ((x[i] / 10) % 4); // 4x4 tilesheet + int row = ((y[i] / 10) % 4); + int num_frame = col * 4 + row; + float position[3] = {x[i],y[i],y[i]}, offset[2]={0,0}, scale[2]={1,1}, spritesheet[3]={num_frame,4,4}; + sprite_sheet(kids, + spritesheet, // num_frame in a 4x4 spritesheet + position, angle, // position(x,y,depth: sort by Y), angle + offset, scale, // offset(x,y), scale(x,y) + 0, ~0u, 0 // is_additive, tint color, resolution independant + ); + } } -int main() { - // window (80% sized, MSAA x4 flag) - window_create(80.0, WINDOW_MSAA4); - window_title(__FILE__); +int main(int argc, char **argv) { + window_create(75.f, 0); + window_title("V4K - Sprite"); + window_color( SILVER ); - // tiled map - tiled_t tmx = tiled(vfs_read("castle.tmx")); - // tmx.parallax = true; + // options + int do_cats = 1; + NUM_SPRITES = optioni("--num_sprites,-N", NUM_SPRITES); + if(do_cats) NUM_SPRITES/=2; // cat-sprite+cat-shadow == 2 sprites - // spine model - //spine_t *spn = spine("goblins.json", "goblins.atlas", 0); + // load sprites and sheets + kids = texture( "spriteSheetExample.png", TEXTURE_LINEAR ); + catImage = texture( "cat.png", TEXTURE_LINEAR ); // + shadowImage = texture( "cat-shadow.png", TEXTURE_LINEAR ); + inputs = texture( "prompts_tilemap_34x24_16x16x1.png", TEXTURE_LINEAR ); - // camera 2d + // load all fx files, including subdirs + fx_load("fx**.fs"); + + // init camera (x,y) (z = zoom) camera_t cam = camera(); - cam.position = vec3(window_width()/2, window_height()/2, 3); // at(CX,CY) zoom(x3) + cam.position = vec3(window_width()/2,window_height()/2,1); camera_enable(&cam); - // audio (both clips & streams) - audio_t clip1 = audio_clip( "coin.wav" ); - audio_t clip2 = audio_clip( "pew.sfxr" ); - audio_t stream1 = audio_stream( "larry.mid" ); - audio_t stream2 = audio_stream( "monkey1.mid" ); - audio_t BGM = stream1; - audio_play(BGM, 0); - - // font config: faces (6 max) and colors (10 max) - #define FONT_CJK FONT_FACE3 - #define FONT_YELLOW FONT_COLOR2 - #define FONT_LIME FONT_COLOR3 - font_face(FONT_CJK, "mplus-1p-medium.ttf", 48.f, FONT_JP|FONT_2048); // CJK|FONT_2048|FONT_OVERSAMPLE_Y); - font_color(FONT_YELLOW, RGB4(255,255,0,255)); - font_color(FONT_LIME, RGB4(128,255,0,255)); - - // fx: load all post fx files in all subdirs. enable a few filters by default - fx_load("fx**.fs"); - fx_enable(fx_find("fxCRT2.fs"), 1); - fx_enable(fx_find("fxGrain.fs"), 1); - fx_enable(fx_find("fxContrast.fs"), 1); - fx_enable(fx_find("fxVignette.fs"), 1); - - // demo loop - while (window_swap() && !input_down(KEY_ESC)) { - - // handle input - if( input_down(KEY_F5) ) window_reload(); - if( input_down(KEY_F11) ) window_fullscreen( !window_has_fullscreen() ); + while(window_swap()) { + if( input(KEY_F5)) window_reload(); + if( input(KEY_F11)) window_fullscreen( window_has_fullscreen() ^ 1); + if( input(KEY_ESC) ) break; // camera panning (x,y) & zooming (z) if( !ui_hover() && !ui_active() ) { - if( input(MOUSE_L) ) cam.position.x += input_diff(MOUSE_X); - if( input(MOUSE_L) ) cam.position.y += input_diff(MOUSE_Y); - cam.position.z += input_diff(MOUSE_W) * 0.1; + if( input(MOUSE_L) ) cam.position.x -= input_diff(MOUSE_X); + if( input(MOUSE_L) ) cam.position.y -= input_diff(MOUSE_Y); + cam.position.z += input_diff(MOUSE_W) * 0.1; // cam.p.z += 0.001f; for tests } // apply post-fxs from here fx_begin(); - profile("Rendering") { - vec3 center = add3(cam.position,vec3(-window_width()/1,-window_height()/2,0)); - // render tiled map - tiled_render(tmx, center); - // - demo_kids(vec3(0,0,1)); - demo_hud(); - // render spine model - // spine_animate(spn, !window_has_pause() * window_delta()); - // spine_render(spn, vec3(cam.position.x, cam.position.y, 1), true ); - // sprite_flush(); + profile("Sprite batching") { + if(do_cats) demo_cats(); else demo_kids(); } - // subtitle sample - font_print( - FONT_BOTTOM FONT_CENTER - FONT_CJK FONT_H1 - FONT_YELLOW "私はガラスを食べられます。" FONT_LIME "それは私を傷つけません。\n" - ); + // flush retained renderer, so we ensure the fbos are up to date before fx_end() + profile("Sprite flushing") { + sprite_flush(); + } // post-fxs end here fx_end(); - // ui - if( ui_panel("Audio", 0)) { - static float bgm = 1, sfx = 1, master = 1; - if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm); - if( ui_slider2("SFX", &sfx, va("%.2f", sfx))) audio_volume_clip(sfx); - if( ui_slider2("Master", &master, va("%.2f", master))) audio_volume_master(master); - if( ui_label2_toolbar("BGM: Leisure Suit Larry", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream1, AUDIO_SINGLE_INSTANCE); - if( ui_label2_toolbar("BGM: Monkey Island", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream2, AUDIO_SINGLE_INSTANCE); - if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(clip1, 0); - if( ui_label2_toolbar("SFX: Pew", ICON_MD_VOLUME_UP)) audio_play(clip2, 0); - ui_panel_end(); + // draw pixel-art hud, 16x16 ui element, scaled and positioned in resolution-independant way + { + vec3 old_pos = camera_get_active()->position; + + sprite_flush(); + camera_get_active()->position = vec3(window_width()/2,window_height()/2,1); + + float zindex = window_height(); // large number, on top + float spritesheet[3] = {17,34,24}, offset[2] = {0, - 2*absf(sin(window_time()*5))}; // sprite cell and animation + float scale[2] = {3, 3}, tile_w = 16 * scale[0], tile_h = 16 * scale[1]; // scaling + float position[3] = {window_width() - tile_w, window_height() - tile_h, zindex }; // position in screen-coordinates + sprite_sheet(inputs, spritesheet, position, 0/*rotation*/, offset, scale, false/*is_additive*/, WHITE/*color*/, false/*resolution_independant*/); + + sprite_flush(); + camera_get_active()->position = old_pos; } - if( ui_panel("Tiled", 0)) { - ui_float("Zoom in", &cam.position.z); - tiled_ui(&tmx); - ui_panel_end(); - } - /*if( ui_panel("Spine", 0)) { - spine_ui(spn); - ui_panel_end(); - }*/ - if( ui_panel("FX", 0) ) { - for( int i = 0; i < 64; ++i ) { - 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); - } + + if( ui_panel("Sprite", 0) ) { + const char *labels[] = {"Kids","Cats"}; + if( ui_list("Sprite type", labels, countof(labels), &do_cats) ) NUM_SPRITES_CHANGED = 1; + if( ui_int("Number of Sprites", &NUM_SPRITES) ) NUM_SPRITES_CHANGED = 1; + if( ui_clampf("Zoom", &cam.position.z, 0.1, 10)); ui_panel_end(); } } } - -// this demo supersedes following old sources: -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-audio.c -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-font.c -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-spine.c -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-sprite.c -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-tiled.c -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-tilemap.c diff --git a/demos/02-ddraw.c b/demos/02-ddraw.c index 501a517..46359d5 100644 --- a/demos/02-ddraw.c +++ b/demos/02-ddraw.c @@ -51,44 +51,40 @@ int main() { } } - fx_begin(); + // draw skybox + skybox_render(&sky, cam.proj, cam.view); - // draw skybox - skybox_render(&sky, cam.proj, cam.view); + // world + ddraw_grid(0); - // world - ddraw_grid(0); + // boids + static swarm_t sw; + if( do_boids_demo ) profile("boids") { + do_once sw = swarm(); + do_once array_push(sw.steering_targets, vec3(0,0,0)); + do_once for(int i = 0; i < 100; ++i) + array_push(sw.boids, boid(scale3(rnd3(),10), rnd3())); // pos,vel - // boids - static swarm_t sw; - if( do_boids_demo ) profile("boids") { - do_once sw = swarm(); - do_once array_push(sw.steering_targets, vec3(0,0,0)); - do_once for(int i = 0; i < 100; ++i) - array_push(sw.boids, boid(scale3(rnd3(),10), rnd3())); // pos,vel + // move + sw.steering_targets[0] = cam.position; + swarm_update(&sw, window_delta()); - // move - sw.steering_targets[0] = cam.position; - swarm_update(&sw, window_delta()); - - // draw - for (int j = 0, end = array_count(sw.boids); j < end; ++j) { - vec3 dir = norm3(sub3(sw.boids[j].position, sw.boids[j].prev_position)); - ddraw_boid(sw.boids[j].position, dir); - } + // draw + for (int j = 0, end = array_count(sw.boids); j < end; ++j) { + vec3 dir = norm3(sub3(sw.boids[j].position, sw.boids[j].prev_position)); + ddraw_boid(sw.boids[j].position, dir); } + } - // showcase many debugdraw shapes - if( do_debugdraw_demo ) { - ddraw_demo(); - } + // showcase many debugdraw shapes + if( do_debugdraw_demo ) { + ddraw_demo(); + } - // showcase many colliding tests - if( do_colliders_demo ) { - collide_demo(); - } - - fx_end(); + // showcase many colliding tests + if( do_colliders_demo ) { + collide_demo(); + } // ui if( ui_panel("App", 0) ) { @@ -106,15 +102,6 @@ int main() { if( ui_float3("Position", cam.position.v3) ) {} ui_panel_end(); } - if( ui_panel("FX", 0) ) { - for( int i = 0; i < 64; ++i ) { - 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 a8b5b33..65f1c9e 100644 --- a/demos/03-anims.c +++ b/demos/03-anims.c @@ -32,10 +32,10 @@ int main() { 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); + vec3 pos = vec3(-x*3,0,-z*3); + vec3 rot = vec3(0,-90,0); // kgirl: 0,0,0 + vec3 sca = vec3(1,1,1); // kgirl: 2,2,2 + compose44(M[i], pos, eulerq(rot), sca); } } @@ -167,15 +167,6 @@ int main() { shader_vec3("u_rimrange", rimrange); ui_panel_end(); } - if( ui_panel("FX", 0) ) { - for( int i = 0; i < 64; ++i ) { - 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/04-lod.c b/demos/04-lod.c index 270ea9a..0804b32 100644 --- a/demos/04-lod.c +++ b/demos/04-lod.c @@ -130,7 +130,7 @@ void DrawModel(mesh_t *m) { "fragcolor = vec4(v_normal, 1.0);\n" // diffuse "}"; - static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor", ""); + static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor", NULL); shader_bind(program); shader_mat44("VP", VP); shader_mat44("M", M); diff --git a/demos/05-scene.c b/demos/05-scene.c index ad1dc22..dcfc682 100644 --- a/demos/05-scene.c +++ b/demos/05-scene.c @@ -142,14 +142,6 @@ int main() { if(ui_bool("Two sided", &do_twosided)) {} ui_panel_end(); } - if( ui_panel("FX", 0) ) { - for( int i = 0; i < 64; ++i ) { - 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_panel_end(); - } } } @@ -164,7 +156,7 @@ int main() { // create camera camera_t cam = camera(); // load video, RGB texture, no audio -video_t *v = video( "bjork-all-is-full-of-love.mp4", VIDEO_RGB | VIDEO_NO_AUDIO ); video_seek(v, 30); +video_t *v = video( "pexels-pachon-in-motion-17486489.mp4", VIDEO_RGB | VIDEO_NO_AUDIO | VIDEO_LOOP ); video_seek(v, 30); // load texture texture_t t1 = texture("kgirl/g01_texture.png", TEXTURE_RGB); texture_t t2 = texture("matcaps/material3", 0); diff --git a/demos/06-controller.c b/demos/06-controller.c index 7fd439e..f697ffa 100644 --- a/demos/06-controller.c +++ b/demos/06-controller.c @@ -2,14 +2,14 @@ // - rlyeh, public domain. // // Compile with: -// `make demos\04-controller.c` (windows) -// `sh MAKE.bat demos/04-controller.c` (linux, osx) +// `make demos\99-controller.c` (windows) +// `sh MAKE.bat demos/99-controller.c` (linux, osx) #include "v4k.h" int main() { // 75% window, MSAAx2 flag - window_create(75, WINDOW_MSAA8); + window_create(75, WINDOW_MSAA2); // fx: load all post fx files in all subdirs fx_load("fx**.fs"); @@ -262,14 +262,6 @@ int main() { ui_label("Keys I/J/K/L + Z/X"); ui_panel_end(); } - if( ui_panel("FX", 0) ) { - for( int i = 0; i < 64; ++i ) { - char *name = fx_name(i); if( !name ) break; - bool b = fx_enabled(i); - if( ui_bool(name, &b) ) fx_enable(i, b); - } - ui_panel_end(); - } } } diff --git a/demos/99-material.c b/demos/06-material.c similarity index 90% rename from demos/99-material.c rename to demos/06-material.c index f5e16ef..d23f79c 100644 --- a/demos/99-material.c +++ b/demos/06-material.c @@ -1,8 +1,14 @@ +// material demo +// - rlyeh, public domain +// +// @todo: object_print(obj, ""); + #include "v4k.h" int main() { // create the window window_create( 0.75f, WINDOW_MSAA8 ); + window_color( GRAY ); // create camera camera_t cam = camera(); @@ -41,22 +47,17 @@ int main() { // create point light light_t* l = scene_spawn_light(); - light_type(l, LIGHT_SPOT); - light_ambient(l, vec3(0.03,0.03,0.06)); - light_specular(l, scale3(vec3(1,1.0,0.2), 2.5f)); - light_power(l, 56.f); + light_type(l, LIGHT_POINT); while(window_swap() && !input(KEY_ESC)) { // draw environment - viewport_color( RGB3(22,22,32) ); ddraw_grid(0); // update video video_decode( v ); - // update light data + // update light position light_teleport(l, cam.position); - light_dir(l, cam.look); // draw scene scene_render(SCENE_FOREGROUND|SCENE_BACKGROUND|SCENE_UPDATE_SH_COEF); diff --git a/demos/99-syncdemo.c b/demos/07-netsync.c similarity index 100% rename from demos/99-syncdemo.c rename to demos/07-netsync.c diff --git a/demos/99-audio.c b/demos/08-audio.c similarity index 68% rename from demos/99-audio.c rename to demos/08-audio.c index 3593c16..5ffb0c6 100644 --- a/demos/99-audio.c +++ b/demos/08-audio.c @@ -8,10 +8,8 @@ int main() { window_create(80, WINDOW_MSAA4 | WINDOW_SQUARE); // audio (both streams & clips) - audio_t stream1 = audio_stream( "wrath_of_the_djinn.xm" ); - audio_t stream2 = audio_stream( "larry.mid" ); - audio_t stream3 = audio_stream( "monkey1.mid" ); - audio_t stream4 = audio_stream( "waterworld-map.fur" ); + audio_t stream1 = audio_stream( "larry.mid" ); + audio_t stream2 = audio_stream( "waterworld-map.fur" ); audio_t BGM = stream1; audio_play(BGM, 0); @@ -27,10 +25,8 @@ int main() { if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm); if( ui_slider2("SFX", &sfx, va("%.2f", sfx))) audio_volume_clip(sfx); if( ui_slider2("Master", &master, va("%.2f", master))) audio_volume_master(master); - if( ui_label2_toolbar("BGM: Wrath of the Djinn", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream1, AUDIO_SINGLE_INSTANCE); - if( ui_label2_toolbar("BGM: Leisure Suit Larry", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream2, AUDIO_SINGLE_INSTANCE); - if( ui_label2_toolbar("BGM: Monkey Island", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream3, AUDIO_SINGLE_INSTANCE); - if( ui_label2_toolbar("BGM: Waterworld Map", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream4, AUDIO_SINGLE_INSTANCE); + if( ui_label2_toolbar("BGM: Leisure Suit Larry", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream1, AUDIO_SINGLE_INSTANCE); + if( ui_label2_toolbar("BGM: Waterworld Map", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = stream2, AUDIO_SINGLE_INSTANCE); if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(SFX1, 0); if( ui_label2_toolbar("SFX: Pew", ICON_MD_VOLUME_UP)) audio_play(SFX2, 0); ui_window_end(); diff --git a/demos/99-video.c b/demos/08-video.c similarity index 94% rename from demos/99-video.c rename to demos/08-video.c index 9efc475..aa7e933 100644 --- a/demos/99-video.c +++ b/demos/08-video.c @@ -5,8 +5,7 @@ int main() { // 75% window, msaa x2 - window_create( 35, WINDOW_MSAA2 ); - window_aspect_lock(910, 540); + window_create( 75, WINDOW_MSAA2 ); // load video int is_rgb = flag("--rgb") ? 1 : 0; diff --git a/demos/99-cubemap.c b/demos/09-cubemap.c similarity index 91% rename from demos/99-cubemap.c rename to demos/09-cubemap.c index 73296fc..50a1592 100644 --- a/demos/99-cubemap.c +++ b/demos/09-cubemap.c @@ -5,12 +5,7 @@ const char *SKY_DIRS[] = { "cubemaps/bridge3/", "cubemaps/colors/", "cubemaps/colors2/", - "cubemaps/mountain/", - "cubemaps/room/", - "cubemaps/stardust/", - "hdr/MonValley_G_DirtRoad_1k.hdr", - "hdr/Factory_Catwalk_1k.hdr", - "hdr/Shiodome_Stairs_1k.hdr", + "hdr/Tokyo_BigSight_1k.hdr", }; int OBJ_MDL = 0; @@ -62,17 +57,17 @@ int main(int argc, char** argv) { if (flag("--mie")) { // skybox_sh_reset(&sky); skybox_mie_calc_sh(&sky, 4.0f); - // float x = cosf((float)window_time())*4; + // float x = cosf((float)window_time())*4; // skybox_sh_add_light(&sky, vec3(0.3,0.3,0.3), vec3(0,1,0), 16*absf(cosf((float)window_time()*2))+2); // skybox_sh_add_light(&sky, vec3(0.6,0,0), vec3(x,1,0), 2); } skybox_render(&sky, cam.proj, cam.view); - + shader_bind(mdl.program); shader_vec3v("u_coefficients_sh", 9, sky.cubemap.sh); shader_int("u_textured", false); - + model_render(mdl, cam.proj, cam.view, mdl.pivot, 0); } diff --git a/demos/09-shadertoy.c b/demos/09-shadertoy.c new file mode 100644 index 0000000..3804c11 --- /dev/null +++ b/demos/09-shadertoy.c @@ -0,0 +1,38 @@ +// shadertoy viewer +// - rlyeh, public domain + +#include "v4k.h" + +int main() { + window_create(75, 0); // WINDOW_MSAA8); + + array(char*) list = 0; + for( const char **dir = file_list("demos/art/shadertoys/", "**.fs"); *dir; dir++ ) { + array_push(list, STRDUP(file_name(*dir))); + } + + shadertoy_t sh = shadertoy(*list, 0); // 0:no flags + + while(window_swap()) { + // selector + static int selected = 0; + int prev = input_down(KEY_UP) || input_down(KEY_LEFT); + int next = input_down(KEY_DOWN) || input_down(KEY_RIGHT); + if( prev ) if( selected > 0 ) sh = shadertoy( list[--selected], 0 ); + if( next ) if( selected < array_count(list) - 1 ) sh = shadertoy( list[++selected], 0 ); + + // draw + shadertoy_render(&sh, window_delta()); + + // UI + if( ui_panel("Shadertoy", 1)) { + for( int i = 0; i < array_count(list); ++i ) { + bool in_use = i == selected; + if( ui_bool(list[i], &in_use) ) { + sh = shadertoy( list[selected = i], 0 ); + } + } + ui_panel_end(); + } + } +} diff --git a/demos/99-bytebeat.c b/demos/99-bytebeat.c deleted file mode 100644 index 0ab7c7a..0000000 --- a/demos/99-bytebeat.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -/* -https://www.tastyfish.cz/lrs/bytebeat.html -Outputting the variable i creates a periodical saw-shaped beat, multiplication/division decreases/increases the speed, addition/subtraction shifts the phase backward/forward. -Squaring (and other powers) create a wah-wah effect. -Crazier patterns can be achieved by using the variable in places of numerical constants, e.g. i << ((i / 512) % 8) (shifting by a value that depends on the variable). -Modulo (%) increases the frequency and decreases volume (limits the wave peak). -So called Sierpinski harmonies are often used melodic expressions of the form i*N & i >> M. -Bitwise and (&) can add distortion (create steps in the wave). -A macro structure of the song (silent/louds parts, verse/chorus, ...) can be achieved by combining multiple patterns with some low-frequency pattern, e.g. this alternates a slower and faster beat: int cond = (i & 0x8000) == 0;, cond * (i / 16) + !cond * (i / 32) -Extra variables can add more complexity (e.g. precompute some variable a which will subsequently be used multiple times in the final formula). -*/ - -int main(void) { - for (int t = 0;; ++t) { - putchar( - t|(t<<((t/920)%16))|(t/3*t&(t<<13)*t)|(t%16386?123:t&203?148:3)&(t/920) - // (t/8)>>(t>>9)*t/((t>>14&3)+4) - // ((1-(((t+10)>>((t>>9)&((t>>14))))&(t>>4&-2)))*2)*(((t>>10)^((t+((t>>6)&127))>>10))&1)*32+128 - // t*((0xbadbea75>>((t>>12)&30)&3)*0.25*(0x5afe5>>((t>>16)&28)&3)) - // ((t>>4)*(13&(0x8898a989>>(t>>11&30)))&255)+((((t>>9|(t>>2)|t>>8)*10+4*((t>>2)&t>>15|t>>8))&255)>>1) - // t*((t>>12|t>>8)&63&t>>4) - // ((0x47 >> ((t >> 9) % 32)) & (t >> (t % 32))) | (0x57 >> ((t >> 7) % 32)) | (0x06 >> ((t >> ((((t * 11) >> 14) & 0x0e) % 32)) % 32)) - ); - } - - return 0; -} diff --git a/demos/99-compute.c b/demos/99-compute.c index a352497..8fc0e84 100644 --- a/demos/99-compute.c +++ b/demos/99-compute.c @@ -27,7 +27,7 @@ int main() { ssbo_update(0, sizeof(data), &data); compute_dispatch(TEX_WIDTH/10, TEX_WIDTH/10, 1); - image_write_barrier(); + write_barrier_image(); fullscreen_quad_rgb(tex, 2.2); } diff --git a/demos/99-demo.c b/demos/99-demo.c new file mode 100644 index 0000000..8061ea0 --- /dev/null +++ b/demos/99-demo.c @@ -0,0 +1,268 @@ +// framework demo +// - rlyeh, public domain + +#include "v4k.h" + +int main() { + // options + bool do_about = 0; + float do_scale = 0.10f; + bool do_debugdraw = 0; + float do_gamepad_deadzone = 0.15f; + vec2 do_gamepad_polarity = vec2(+1,+1); + vec2 do_gamepad_sensitivity = vec2(0.1f,0.1f); + vec2 do_mouse_polarity = vec2(+1,-1); + vec2 do_mouse_sensitivity = vec2(0.2f,0.2f); + bool do_billboard_x = 0, do_billboard_y = 0, do_billboard_z = 0; + + // window (80% sized, MSAA x4 flag) + window_create(80, WINDOW_MSAA4); + window_title(__FILE__); + + // load all fx files, including subdirs + fx_load("fx**.fs"); + + // load skybox + skybox_t sky = skybox(flag("--mie") ? 0 : "cubemaps/stardust", 0); // --mie for rayleigh/mie scattering + + // load static scene + model_t sponza; + int do_sponza = flag("--sponza"); + if( do_sponza ) { + sponza = model("sponza.obj", 0); // MODEL_NO_TEXTURES); + translation44(sponza.pivot, 0,-1,0); + rotate44(sponza.pivot, -90,1,0,0); + scale44(sponza.pivot, 10,10,10); + } + + model_t shaderball; + int do_shaderball = flag("--shaderball"); + if( do_shaderball ) { + shaderball = model("shaderball.glb", 0); + translation44(shaderball.pivot, 0,0,-10); + rotate44(shaderball.pivot, -90,1,0,0); + scale44(shaderball.pivot, 0.02,0.02,0.02); + } + + // animated models loading + int model_flags = flag("--matcaps") ? MODEL_MATCAPS : 0; + model_t girl = model("kgirl/kgirls01.fbx", model_flags); + model_t alien = model("alien/alien_helmet.fbx", model_flags); rotation44(alien.pivot, -90,1,0,0); + model_t george = model("robots/george.fbx", model_flags); + model_t leela = model("robots/leela.fbx", model_flags); + model_t mike = model("robots/mike.fbx", model_flags); + model_t stan = model("robots/stan.fbx", model_flags); + model_t robots[4] = { george, leela, mike, stan }; + for( int i = 0; i < countof(robots); ++i ) { + rotation44(robots[i].pivot, -90,1,0,0); + } + + if( flag("--matcaps") ) { + // patch models to use matcaps + model_set_texture(george, texture("matcaps/3B6E10_E3F2C3_88AC2E_99CE51-256px", 0)); // green + model_set_texture(leela, texture("matcaps/39433A_65866E_86BF8B_BFF8D8-256px", 0)); + model_set_texture(mike, texture("matcaps/394641_B1A67E_75BEBE_7D7256-256px.png", 0)); + model_set_texture(stan, texture("matcaps/test_steel", 0)); + model_set_texture(girl, texture("matcaps/material3", 0)); + model_set_texture(alien, texture("matcaps/material3", 0)); + + if( flag("--shaderball") ) + model_set_texture(shaderball, texture("matcaps/normals", 0)); + } + + // camera + camera_t cam = camera(); + cam.speed = 0.2f; + + // audio (both clips & streams) + audio_t SFX1 = audio_clip( "coin.wav" ); + audio_t SFX2 = audio_clip( "pew.sfxr" ); + audio_t BGM1 = audio_stream( "waterworld-map.fur"); // wrath_of_the_djinn.xm" ); + audio_t BGM2 = audio_stream( "larry.mid" ); + audio_t BGM3 = audio_stream( "monkey1.mid" ), BGM = BGM1; + audio_play(SFX1, 0); + audio_play(BGM, 0); + + // demo loop + while (window_swap()) + { + // input + if( input_down(KEY_ESC) ) break; + if( input_down(KEY_F5) ) window_reload(); + if( input_down(KEY_W) && input_held(KEY_LCTRL) ) break; + if( input_down(KEY_F11) ) window_fullscreen( window_has_fullscreen() ^ 1 ); + if( input_down(KEY_X) ) window_screenshot(__FILE__ ".png"); + if( input_down(KEY_Z) ) window_record(__FILE__ ".mp4"); + + // vec2 filtered_lpad = input_filter_deadzone(input2(GAMEPAD_LPAD), do_gamepad_deadzone + 1e-3); + // vec2 filtered_rpad = input_filter_deadzone(input2(GAMEPAD_RPAD), do_gamepad_deadzone + 1e-3); + + // fps camera + bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); + if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); + vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); + vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); + camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_fps(&cam, mouse.x,mouse.y); + window_cursor( !active ); + + // apply post-fxs from here + fx_begin(); + + // queue debug drawcalls + profile("Debugdraw") { + ddraw_grid(0); + ddraw_color(YELLOW); + ddraw_text(vec3(+1,+1,-1), 0.04f, va("(%f,%f,%f)", cam.position.x,cam.position.y,cam.position.z)); + if(do_debugdraw) ddraw_demo(); // showcase many debugdraw shapes + ddraw_color(YELLOW); + ddraw_flush(); + } + + // draw skybox + profile("Skybox") { + skybox_render(&sky, cam.proj, cam.view); + } + + profile("Skeletal update") if(!window_has_pause()) { + float delta = window_delta() * 30; // 30fps anim + + // animate girl & alien + girl.curframe = model_animate(girl, girl.curframe + delta); + alien.curframe = model_animate(alien, alien.curframe + delta); + + // animate robots + for(int i = 0; i < countof(robots); ++i) { + robots[i].curframe = model_animate(robots[i], robots[i].curframe + delta); + } + } + + profile("Skeletal render") { + static vec3 p = {-10,0,-10}, r = {0,0,0}, s = {2,2,2}; + gizmo(&p, &r, &s); + mat44 M; rotationq44(M, eulerq(r)); scale44(M, s.x,s.y,s.z); relocate44(M, p.x,p.y,p.z); + + model_render(girl, cam.proj, cam.view, M, 0); + + aabb box = model_aabb(girl, M); + ddraw_color(YELLOW); + ddraw_aabb(box.min, box.max); + } + + profile("Skeletal render") { + static vec3 p = {+10,0,-10}, r = {0,-90,0}, s = {1,1,1}; + //gizmo(&p, &r, &s); + mat44 M; rotationq44(M, eulerq(r)); scale44(M, s.x,s.y,s.z); relocate44(M, p.x,p.y,p.z); + + model_render(alien, cam.proj, cam.view, M, 0); + + aabb box = model_aabb(alien, M); // @fixme: neg Y + ddraw_color(YELLOW); + //ddraw_aabb(box.min, box.max); + } + + profile("Skeletal render") for(int i = 0; i < countof(robots); ++i) { + float scale = 0.50; + mat44 M; copy44(M, robots[i].pivot); translate44(M, i*3,0,0); scale44(M, scale,scale,scale); + model_render(robots[i], cam.proj, cam.view, M, 0); + } + + if(do_sponza) profile("Sponza") { + float scale = 1.00; + mat44 M; copy44(M, sponza.pivot); translate44(M, 0,0,0); scale44(M, scale,scale,scale); + model_render(sponza, cam.proj, cam.view, M, 0); + } + + if(do_shaderball) profile("Shaderball") { + float scale = 1.00; + mat44 M; copy44(M, shaderball.pivot); translate44(M, 0,0,0); scale44(M, scale,scale,scale); + model_render(shaderball, cam.proj, cam.view, M, 0); + } + + // post-fxs end here + fx_end(); + + // font demo + do_once font_scales(FONT_FACE1, 48, 24, 18, 12, 9, 6); + font_print(va(FONT_RIGHT FONT_BOTTOM FONT_H4 "%5.2f FPS", window_fps())); + + // queue ui + if( ui_panel("App", 0)) { + if(ui_bool("Show debugdraw demo", &do_debugdraw)) {} + if(ui_separator()) {} + if(ui_slider("Gamepad deadzone", &do_gamepad_deadzone)) {} + if(ui_float2("Gamepad polarity", do_gamepad_polarity.v2)) {} + if(ui_float2("Gamepad sensitivity", do_gamepad_sensitivity.v2)) {} + if(ui_separator()) {} + if(ui_float2("Mouse polarity", do_mouse_polarity.v2)) {} + if(ui_float2("Mouse sensitivity", do_mouse_sensitivity.v2)) {} + if(ui_separator()) {} + if(ui_button("About...")) { do_about = 1; audio_play(SFX1, 0); } + if(ui_dialog("About", __FILE__ "\n" __DATE__ "\n" "Public Domain.", 0, &do_about)) {} + ui_panel_end(); + } + if( ui_panel("Camera", 0)) { + if( ui_float("Speed", &cam.speed) ) {} + if( ui_float3("Position", cam.position.v3) ) {} + ui_panel_end(); + } + if( ui_panel("Audio", 0)) { + static float bgm = 1, sfx = 1, master = 1; + if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm); + if( ui_slider2("SFX", &sfx, va("%.2f", sfx))) audio_volume_clip(sfx); + if( ui_slider2("Master", &master, va("%.2f", master))) audio_volume_master(master); + if( ui_label2_toolbar("BGM: Waterworld Map" /*Wrath of the Djinn"*/, ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = BGM1, AUDIO_SINGLE_INSTANCE); + if( ui_label2_toolbar("BGM: Leisure Suit Larry", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = BGM2, AUDIO_SINGLE_INSTANCE); + if( ui_label2_toolbar("BGM: Monkey Island", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = BGM3, AUDIO_SINGLE_INSTANCE); + if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(SFX1, 0); + if( ui_label2_toolbar("SFX: Pew", ICON_MD_VOLUME_UP)) audio_play(SFX2, 0); + ui_panel_end(); + } + + input_demo(); // show some keyboard/mouse/gamepad UI tabs + ui_demo(1); // show all UI widgets in a tab + } + + // data tests (json5) + const char json5[] = + " /* json5 */ // comment\n" + " abc: 42.67, def: true, integer:0x100 \n" + " huge: 2.2239333e5, \n" + " hello: 'world /*comment in string*/ //again', \n" + " children : { a: 1, b: 2, c: 3 },\n" + " array: [+1,2,-3,4,5], \n" + " invalids : [ nan, NaN, -nan, -NaN, inf, Infinity, -inf, -Infinity ],"; + if( json_push(json5) ) { + assert( json_float("/abc") == 42.67 ); + assert( json_int("/def") == 1 ); + assert( json_int("/integer") == 0x100 ); + assert( json_float("/huge") > 2.22e5 ); + assert( strlen(json_string("/hello")) == 35 ); + assert( json_int("/children/a") == 1 ); + assert( json_int("/children.b") == 2 ); + assert( json_int("/children[c]") == 3 ); + assert( json_int("/array[%d]", 2) == -3 ); + assert( json_count("/invalids") == 8 ); + assert( isnan(json_float("/invalids[0]")) ); + assert( !json_find("/non_existing") ); + assert( PRINTF("json5 tests OK\n") ); + json_pop(); + } + + // data tests (xml) + const char *xml = vfs_read("test1.xml"); + if( xml_push(xml) ) { + puts( xml ); + puts( xml_string("/person/firstName/$") ); + puts( xml_string("/person/lastName/$") ); + puts( xml_string("/person/address/@type") ); + xml_pop(); + } + + // network test (https) + array(char) webfile = download("https://www.google.com/"); + printf("Network test: %d bytes downloaded from google.com\n", array_count(webfile)); + + // script test (lua) + script_run( "-- Bye.lua\nio.write(\"script test: Bye world!, from \", _VERSION, \"\\n\")" ); +} diff --git a/demos/99-dung.c b/demos/99-dung.c deleted file mode 100644 index b0af255..0000000 --- a/demos/99-dung.c +++ /dev/null @@ -1,176 +0,0 @@ -#include "v4k.h" - -#define WS 32 - -enum { - WALL=2, DOOR=4 -}; - -typedef struct { - int16_t id:8; - int16_t flags:8; -} cell_t; - -#define cell_t(...) C_CAST(cell_t, __VA_ARGS__) - -typedef struct { - cell_t grid[WS*WS]; - mesh_t level; -} world_t; - -static world_t world; - -void world_init() { - int i, j; - for (i = 0; i < WS; ++i) { - for (j = 0; j < WS; ++j) { - if (i == 0 || i == WS-1 || j == 0 || j == WS-1) { - // Border cells - world.grid[i*WS + j] = cell_t(0, WALL); - } else { - // Interior cells - world.grid[i*WS + j] = cell_t(rand()%3, 0); - } - } - } - - world.level = mesh(); - - - const int cube_vertices = 24; - const int cube_triangles = 12; - const int vertex_count = WS * WS * cube_vertices; - const int index_count = WS * WS * cube_triangles * 3; - - struct vert { - vec3 pos; - vec3 normal; - }; - - struct vert verts[vertex_count]; - - unsigned index_data[index_count]; - - int vertex_index = 0; - int index_index = 0; - - static vec3 normals[6] = { - {1, 0, 0}, {-1, 0, 0}, - {0, 1, 0}, {0, -1, 0}, - {0, 0, 1}, {0, 0, -1} - }; - - for(int z = 0; z < WS; ++z) { - for(int x = 0; x < WS; ++x) { - if(world.grid[z*WS + x].id >= 0) { - for(int face = 0; face < 6; ++face) { - for(int i = 0; i < 4; ++i) { - - vertex_index++; - } - } - - // Create 12 triangles for the cube - static unsigned indices[12][3] = { - {0, 1, 2}, {2, 1, 3}, {4, 5, 6}, {6, 5, 7}, - {0, 4, 1}, {1, 4, 5}, {2, 6, 3}, {3, 6, 7}, - {0, 2, 4}, {4, 2, 6}, {1, 3, 5}, {5, 3, 7} - }; - for(int i = 0; i < 12; ++i) { - for(int j = 0; j < 3; ++j) { - index_data[index_index++] = vertex_index - 24 + indices[i][j]; - } - } - } - } - } - - mesh_update(&world.level, "p3 n3", sizeof(struct vert), vertex_count, verts, index_count, index_data, 0); -} - -void draw_world() { - static mat44 M; do_once id44(M); - static mat44 VP; multiply44x2(VP, camera_get_active()->proj, camera_get_active()->view); - - static const char *vs = - "#version 130\n" - "//" FILELINE "\n" - "uniform mat4 M,VP;\n" - "in vec3 att_position;\n" - "in vec3 att_normal;\n" - "out vec3 v_normal;\n" - "void main() {\n" - " v_normal = normalize(att_position);\n" - " gl_Position = M * VP * vec4( att_position, 1.0 );\n" - "}\n"; - static const char *fs = - "#version 130\n" - "//" FILELINE "\n" - "in vec3 v_normal;\n" - "out vec4 fragcolor;\n" - "void main() {\n" - "fragcolor = vec4(v_normal, 1.0);\n" // diffuse - "}"; - - static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor", ""); - shader_bind(program); - shader_mat44("VP", VP); - shader_mat44("M", M); - - mesh_render(&world.level); -} - - -int main() { - window_create(80, WINDOW_MSAA8); - window_title(__FILE__); - - // init world - world_init(); - - // load all fx files - fx_load("fx**.fs"); - - // load skybox - skybox_t sky = skybox(flag("--mie") ? 0 : "cubemaps/stardust", 0); // --mie for rayleigh/mie scattering - - // camera - camera_t cam = camera(); - cam.speed = 0.2f; - - // audio (both clips & streams) - // audio_t SFX1 = audio_clip( "coin.wav" ); - // audio_t SFX2 = audio_clip( "pew.sfxr" ); - // audio_t BGM1 = audio_stream( "waterworld-map.fur"); // wrath_of_the_djinn.xm" ); - // audio_t BGM2 = audio_stream( "larry.mid" ); - // audio_t BGM3 = audio_stream( "monkey1.mid" ), BGM = BGM1; - // audio_play(SFX1, 0); - // audio_play(BGM1, 0); - - while (window_swap()) { - // input - if( input_down(KEY_ESC) ) break; - if( input_down(KEY_F5) ) window_reload(); - if( input_down(KEY_W) && input_held(KEY_LCTRL) ) break; - if( input_down(KEY_F11) ) window_fullscreen( window_has_fullscreen() ^ 1 ); - if( input_down(KEY_X) ) window_screenshot(__FILE__ ".png"); - if( input_down(KEY_Z) ) window_record(__FILE__ ".mp4"); - - // fps camera - bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); - if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); - vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); - vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); - camera_fps(&cam, mouse.x,mouse.y); - window_cursor( !active ); - - fx_begin(); - skybox_render(&sky, cam.proj, cam.view); - - draw_world(); - fx_end(); - } - - return 0; -} diff --git a/demos/99-instanced.c b/demos/99-instanced.c deleted file mode 100644 index c3b00b8..0000000 --- a/demos/99-instanced.c +++ /dev/null @@ -1,62 +0,0 @@ -// instanced models demo -// - rlyeh, public domain. - -#include "v4k.h" - -int main() { - window_create(75, WINDOW_MSAA2); - window_title(__FILE__); - - camera_t cam = camera(); - skybox_t sky = skybox("cubemaps/stardust", 0); - model_t girl = model("kgirls01.fbx", 0); - - while( window_swap() ) { - if(input(KEY_F5)) window_reload(); - if(input(KEY_ESC)) break; - - // fps camera - bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); - window_cursor( !active ); - - if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); - vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); - vec3 wasdec = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-input(KEY_C),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdec.x,wasdec.y,wasdec.z); - camera_fps(&cam, mouse.x,mouse.y); - - // ground rendering - ddraw_ground(0); - ddraw_flush(); - - // skeletal - profile("Skeletal update") { - float delta = window_has_pause() ? 0 : window_delta() * 30; // 30fps anim - girl.curframe = model_animate(girl, girl.curframe + delta); - } - - profile("Skeletal render") { - enum { ROW = 32, MAX_INSTANCES = ROW * ROW }; - static mat44 M[MAX_INSTANCES]; - - do_once { - int i = 0; - for(int z = 0; z < ROW; ++z) { - for(int x = 0; x < ROW; ++x, ++i) { - vec3 p = vec3(-x*3,0,-z*3); - vec3 r = vec3(0,0,0); - vec3 s = vec3(2,2,2); - rotationq44(M[i], eulerq(r)); scale44(M[i], s.x,s.y,s.z); relocate44(M[i], p.x,p.y,p.z); - } - } - } - - model_render_instanced(girl, cam.proj, cam.view, M, 0, MAX_INSTANCES); - } - - // skybox - profile("Skybox") { - skybox_render(&sky, cam.proj, cam.view); - } - } -} diff --git a/demos/99-pathfind.c b/demos/99-pathfind.c index cace76b..5492ae4 100644 --- a/demos/99-pathfind.c +++ b/demos/99-pathfind.c @@ -1,3 +1,8 @@ +// pathfind demo +// - rlyeh, public domain +// +// @todo: use 2d sprites instead, will shorten things + #include "v4k.h" bool topdown_cam = 1; @@ -5,7 +10,7 @@ bool topdown_cam = 1; void move_players(); int main() { - window_create(75, 0); // WINDOW_MSAA4); + window_create(85, 0); // WINDOW_MSAA4); window_title(__FILE__); window_fps_lock(60); @@ -49,6 +54,10 @@ void draw_scene() { float dd = randi(1,10); float hh = randi(3,10); aabb b = { vec3(ox,0,oz), vec3(ox+ww,hh,oz+dd) }; + + static aabb spawn_zone = { {-10,-10,-10},{10,10,10} }; + if( aabb_hit_aabb(b, spawn_zone) ) continue; + array_push(blockers, b); for( int y = oz; y < (oz+dd); ++y ) @@ -248,7 +257,9 @@ void move_players() { // ui if( ui_panel("Controls", 0) ) { - ui_label2("Girl", ICON_MD_MOUSE " Set Waypoint"); + ui_label2("[F1]", ICON_MD_KEYBOARD " Debug traversal visualization"); + ui_label2("[Left mouse]", ICON_MD_MOUSE " Set Waypoint"); + ui_label2("[Right mouse]", ICON_MD_MOUSE " Toggle camera"); ui_label2("Girl", ICON_MD_GAMEPAD " CURSOR keys"); ui_label2("Alien", ICON_MD_GAMEPAD " W,A,S,D keys"); ui_label2("Robot", ICON_MD_GAMEPAD " I,J,K,L keys"); diff --git a/demos/99-pbr.c b/demos/99-pbr.c index f8214fc..e2b1c9c 100644 --- a/demos/99-pbr.c +++ b/demos/99-pbr.c @@ -648,16 +648,6 @@ int main( int argc, const char *argv[] ) { ui_panel_end(); } - if( ui_panel("FX", 0) ) { - for( int i = 0; i < 64; ++i ) { - 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(); - } - if( ui_panel("Help", 0)) { if( fps_mode ) { ui_label("TAB: switch to Orbit camera mode"); diff --git a/demos/99-rpc_demo.c b/demos/99-rpc_demo.c deleted file mode 100644 index 6b845e9..0000000 --- a/demos/99-rpc_demo.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "v4k.h" - -typedef void* (*rpc_function)(); - -typedef struct rpc_call { - char *method; - rpc_function function; - uint64_t function_hash; -} rpc_call; - -#define RPC_SIGNATURE_i_iii UINT64_C(0x78409099752fa48a) // printf("%llx\n, HASH_STR("int(int,int,int)")); -#define RPC_SIGNATURE_i_ii UINT64_C(0x258290edf43985a5) // printf("%llx\n, HASH_STR("int(int,int)")); -#define RPC_SIGNATURE_s_s UINT64_C(0x97deedd17d9afb12) // printf("%llx\n, HASH_STR("char*(char*)")); -#define RPC_SIGNATURE_s_v UINT64_C(0x09c16a1242049b80) // printf("%llx\n, HASH_STR("char*(void)")); - -static -rpc_call rpc_new_call(const char *signature, rpc_function function) { - if( signature && function ) { - array(char*)tokens = strsplit(signature, "(,)"); - if( array_count(tokens) >= 1 ) { - char *method = strrchr(tokens[0], ' ')+1; - char *rettype = va("%.*s", (int)(method - tokens[0] - 1), tokens[0]); - int num_args = array_count(tokens) - 1; - char* hash_sig = va("%s(%s)", rettype, num_args ? (array_pop_front(tokens), strjoin(tokens, ",")) : "void"); - uint64_t hash = hash_str(hash_sig); - method = va("%s%d", method, num_args ); -#if RPC_DEBUG - printf("%p %p %s `%s` %s(", function, (void*)hash, rettype, hash_sig, method); for(int i = 0, end = array_count(tokens); i < end; ++i) printf("%s%s", tokens[i], i == (end-1)? "":", "); puts(");"); -#endif - return (rpc_call) { strdup(method), function, hash }; // LEAK - } - } - return (rpc_call) {0}; -} - -static map(char*, rpc_call) rpc_calls = 0; - -static -void rpc_insert(const char *signature, void *function ) { - rpc_call call = rpc_new_call(signature, function); - if( call.method ) { - if( !rpc_calls ) map_init(rpc_calls, less_str, hash_str); - if( map_find(rpc_calls, call.method)) { - map_erase(rpc_calls, call.method); - } - map_insert(rpc_calls, call.method, call); - } -} - -static -char *rpc_full(unsigned id, const char* method, unsigned num_args, char *args[]) { -#if RPC_DEBUG - printf("id:%x method:%s args:", id, method ); - for( int i = 0; i < num_args; ++i ) printf("%s,", args[i]); puts(""); -#endif - - method = va("%s%d", method, num_args); - rpc_call *found = map_find(rpc_calls, (char*)method); - if( found ) { - switch(found->function_hash) { - case RPC_SIGNATURE_i_iii: return va("%d %d", id, (int)(uintptr_t)found->function(atoi(args[0]), atoi(args[1]), atoi(args[2])) ); - case RPC_SIGNATURE_i_ii: return va("%d %d", id, (int)(uintptr_t)found->function(atoi(args[0]), atoi(args[1])) ); - case RPC_SIGNATURE_s_s: return va("%d %s", id, (char*)found->function(args[0]) ); - case RPC_SIGNATURE_s_v: return va("%d %s", id, (char*)found->function() ); - default: break; - } - } - return va("%d -1", id); -} - -static -array(char*) rpc_parse_args( const char *cmdline, bool quote_whitespaces ) { // parse cmdline arguments. must array_free() after use - // - supports quotes: "abc" "abc def" "abc \"def\"" "abc \"def\"""ghi" etc. - // - #comments removed - array(char*) args = 0; // LEAK - for( int i = 0; cmdline[i]; ) { - char buf[256] = {0}, *ptr = buf; - while(cmdline[i] && isspace(cmdline[i])) ++i; - bool quoted = cmdline[i] == '\"'; - if( quoted ) { - while(cmdline[++i]) { - char ch = cmdline[i]; - /**/ if (ch == '\\' && cmdline[i + 1] == '\"') *ptr++ = '\"', ++i; - else if (ch == '\"' && cmdline[i + 1] == '\"') ++i; - else if (ch == '\"' && (!cmdline[i + 1] || isspace(cmdline[i + 1]))) { - ++i; break; - } - else *ptr++ = ch; - } - } else { - while(cmdline[i] && !isspace(cmdline[i])) *ptr++ = cmdline[i++]; - } - if (buf[0] && buf[0] != '#') { // exclude empty args + comments - if( quote_whitespaces && quoted ) - array_push(args, va("\"%s\"",buf)); - else - array_push(args, va("%s",buf)); - } - } - return args; -} - -static -char* rpc(unsigned id, const char* cmdline) { - array(char*) args = rpc_parse_args(cmdline, false); - int num_args = array_count(args); - char *ret = num_args ? rpc_full(id, args[0], num_args - 1, &args[1]) : rpc_full(id, "", 0, NULL); - array_free(args); - return ret; -} - -static void enet_quit(void) { - do_once { - // enet_deinitialize(); - } -} -static void enet_init() { - do_once { - if( enet_initialize() != 0 ) { - PANIC("cannot initialize enet"); - } - atexit( enet_quit ); - } -} - -// ----------------------------------------------------------------------------- -// demo - -int rpc_add2(int num1, int num2) { - return num1+num2; -} -int rpc_add3(int num1, int num2, int num3) { - return num1+num2+num3; -} -char *rpc_echo(char *text) { - return text; -} - -int main() { - rpc_insert("int add(int,int)", rpc_add2); - rpc_insert("int add(int,int,int)", rpc_add3); - rpc_insert("char* echo(char*)", rpc_echo); - puts(rpc(0,"add 1 2")); // -> 3 - puts(rpc(1,"add 100 3 -3")); // -> 100 - puts(rpc(2,"echo \"hello world\"")); // -> hello world -} diff --git a/demos/99-shadertoy.c b/demos/99-shadertoy.c deleted file mode 100644 index f4e8778..0000000 --- a/demos/99-shadertoy.c +++ /dev/null @@ -1,44 +0,0 @@ -// shadertoy viewer -// - rlyeh, public domain - -#include "v4k.h" - -int main() { - window_create(75, 0); // WINDOW_MSAA8); - window_title(__FILE__); - - const char **list = file_list("demos/art/shadertoys/", "**.fs"); - if(!list[0]) exit(-1); - array(char*) browser = 0; - while(*list) array_push(browser, STRDUP(file_name(*list++))); - int browser_count = array_count(browser); - - shadertoy_t sh = {0}; - - while(window_swap() && !input(KEY_ESC)) { - if( input_down(KEY_F11) ) window_fullscreen( window_has_fullscreen() ^ 1 ); - // selector - int next = input_down(KEY_UP) || input_down(KEY_LEFT); - int prev = input_down(KEY_DOWN) || input_down(KEY_RIGHT); - static int selector = 0; - static int reload = 1; - if( next ) if( selector > 0 ) --selector, reload = 1; - if( prev ) if( selector < browser_count - 1 ) ++selector, reload = 1; - if( reload ) { - reload = 0; - window_title(va("V4K - %s", browser[selector])); - sh = shadertoy( browser[selector], 0 ); - } - - // draw - shadertoy_render(&sh, window_delta()); - - // UI - if( ui_panel("Shadertoy", 0)) { - if( ui_list("In use", (const char**)browser, browser_count, &selector) ) { - reload = 1; - } - ui_panel_end(); - } - } -} diff --git a/demos/99-sponza.c b/demos/99-sponza.c index f15765a..d6a54dc 100644 --- a/demos/99-sponza.c +++ b/demos/99-sponza.c @@ -11,7 +11,7 @@ int main() { fx_load("fx**.fs"); // load skybox - skybox_t sky = skybox(flag("--mie") ? 0 : "cubemaps/stardust", 0); // --mie for rayleigh/mie scattering + skybox_t sky = skybox(flag("--mie") ? 0 : "hdr/Tokyo_BigSight_1k.hdr", 0); // --mie for rayleigh/mie scattering // load static scene model_t sponza; @@ -70,6 +70,6 @@ int main() { model_render(sponza, cam.proj, cam.view, M, 0); // post-fxs end here - fx_end(); + fx_end(0); } } diff --git a/demos/99-spot.c b/demos/99-spot.c deleted file mode 100644 index 24cad90..0000000 --- a/demos/99-spot.c +++ /dev/null @@ -1,554 +0,0 @@ -// [ref] http://fabiensanglard.net/shadowmappingVSM/index.php -// [ref] http://www.opengl-tutorial.org/es/intermediate-tutorials/tutorial-16-shadow-mapping/ -// [ref] https://github.com/cforfang/opengl-shadowmapping -// [ref] https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping - -// @todo: spotlight (cone light) -// @todo: pointlight (cubemap light) -// @todo: area light (rect or circle light) -// @todo: directional light (sunlight) - -// further reading (in order): -// DPSM [3] Brabec, Annen: Shadow mapping for hemispherical and omnidirectional light sources (2002) -// DPSM* [4] Osman, Bukowski: Practical implementation of dual paraboloid shadow maps (2006) -// IPSM [5] Vanek, Herout: High-quality Shadows with Improved Paraboloid Mapping (2011) -// LiSPSMs -// CSMs - -// status: CUBE(0)+BLUR(0): ok -// status: CUBE(0)+BLUR(1): ok -// status: CUBE(1)+BLUR(1): ok -// status: CUBE(1)+BLUR(0): ok -// status: CUBE(?)+BLUR(?): no { -// 003.470s|!cannot find uniform 'shadowMap' in shader program 21 |shader_uniform|v4k_render.c:772 -// 001: 00007FF7AF6A3FDA callstack (C:\prj\thread\V4K\v4k_system.c:250) -// 002: 00007FF7AF8E7CBC shader_uniform (C:\prj\thread\V4K\v4k_render.c:772) -// 003: 00007FF7AF691C27 shader_int (C:\prj\thread\V4K\v4k_render.c:777) -// 004: 00007FF7AF8F54EF color_begin (C:\prj\thread\V4K\spot.c:525) -// 005: 00007FF7AF8F5BF7 main (C:\prj\thread\V4K\spot.c:607) -// } - -#ifndef VSMCUBE -#define VSMCUBE 0 -#endif -#ifndef VSMBLUR -#define VSMBLUR 1 -#endif - -#include "v4k.h" -#include "split/v4k_shaders.c" - -model_t sponza; - -typedef struct Mesh -{ - GLuint vao; - GLuint vbo; -} Mesh; - -static float quadVertices[] = { - // Front-face - // Pos // Color //Tex // Norm - -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top-left - 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top-right - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // Bottom-right - - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // Bottom-right - -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, //Bottom-left - -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top-left -}; - -static Mesh create_mesh(float* verts, int size) { - Mesh mesh; - - // Create VAO - glGenVertexArrays(1, &mesh.vao); - glBindVertexArray(mesh.vao); - - // Create VBO and copy the vertex data to it - glGenBuffers(1, &mesh.vbo); - glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo); - glBufferData(GL_ARRAY_BUFFER, size, verts, GL_STATIC_DRAW); - - // Enable attribs - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), 0); - // Color - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(3 * sizeof(float))); - // Texcoords - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(6 * sizeof(float))); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(8 * sizeof(float))); - - return mesh; -} - -Mesh create_quad() { - return create_mesh(quadVertices, sizeof(quadVertices)); -} - -struct shadow { - // Resources - GLuint shadowProgram, blurProgram; - Mesh quadMesh; - GLuint shadowMapFBO, shadowMapTex, shadowMapTexDepth; - GLuint blurFBO, blurTex; - // Options - bool do_blur; - bool do_debugshadow; - float BLUR_SCALE; // Amount of blurring [0..100] - GLuint SHADOWMAP_WIDTH; // 256,512,1024,2048 - // State - int shadow_active; - vec3 lightPos; - vec3 lightAimPos; - - // VSM cubemap - GLuint cubeTex, cubeDepthTex, cubeFBOs[6]; - GLuint currentSideTex, currentSideDepthTex; - GLuint toCurrentSideFBO; -} shadow; - -#define shadowProgram shadow.shadowProgram -#define blurProgram shadow.blurProgram -#define quadMesh shadow.quadMesh -#define shadowMapFBO shadow.shadowMapFBO -#define shadowMapTex shadow.shadowMapTex -#define shadowMapTexDepth shadow.shadowMapTexDepth -#define blurFBO shadow.blurFBO -#define blurTex shadow.blurTex -#define do_blur shadow.do_blur -#define do_debugshadow shadow.do_debugshadow -#define BLUR_SCALE shadow.BLUR_SCALE -#define SHADOWMAP_WIDTH shadow.SHADOWMAP_WIDTH -#define shadow_active shadow.shadow_active -#define lightPos shadow.lightPos -#define lightAimPos shadow.lightAimPos -// vsm cubemap -#define cubeTex shadow.cubeTex -#define cubeDepthTex shadow.cubeDepthTex -#define cubeFBOs shadow.cubeFBOs -#define currentSideTex shadow.currentSideTex -#define currentSideDepthTex shadow.currentSideDepthTex -#define toCurrentSideFBO shadow.toCurrentSideFBO - - - -static GLuint cubemap_create(GLsizei size, int flags) { - GLenum texel = flags & TEXTURE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGB32F; - GLenum pixel = flags & TEXTURE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGB; - GLenum storage = flags & TEXTURE_DEPTH ? GL_FLOAT : GL_UNSIGNED_BYTE; // swap? - GLuint id; - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_CUBE_MAP, id); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, texel, size, size, 0, pixel, storage, NULL); - glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, texel, size, size, 0, pixel, storage, NULL); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, texel, size, size, 0, pixel, storage, NULL); - glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, texel, size, size, 0, pixel, storage, NULL); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, texel, size, size, 0, pixel, storage, NULL); - glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, texel, size, size, 0, pixel, storage, NULL); - if( flags & TEXTURE_DEPTH ) { - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - } else { - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); - } - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - return id; -} -static void framebuffer_cube_create(GLuint cube_fbo[6], GLuint cube_texture, GLuint cube_texture_depth) { - glGenFramebuffers(6, cube_fbo); - for (int i = 0; i < 6; i++) { - glBindFramebuffer(GL_FRAMEBUFFER, cube_fbo[i]); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cube_texture, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cube_texture_depth, 0); - GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (GL_FRAMEBUFFER_COMPLETE != result) { - printf("ERROR: Framebuffer is not complete.\n"); - } - } - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} -static void set_shadow_matrix_uniform(const GLuint program, int dir) { - if(dir<0) return; - mat44 P, V, PV; - perspective44(P, 90.0f, 1.0f, 0.5f, 100.0f); - - /**/ if(dir == 0) lookat44(V, lightPos, add3(lightPos, vec3(+1, 0, 0)), vec3(0, -1, 0)); // +X - else if(dir == 1) lookat44(V, lightPos, add3(lightPos, vec3(-1, 0, 0)), vec3(0, -1, 0)); // -X - else if(dir == 2) lookat44(V, lightPos, add3(lightPos, vec3( 0, +1, 0)), vec3(0, 0, +1)); // +Y - else if(dir == 3) lookat44(V, lightPos, add3(lightPos, vec3( 0, -1, 0)), vec3(0, 0, -1)); // -Y - else if(dir == 4) lookat44(V, lightPos, add3(lightPos, vec3( 0, 0, +1)), vec3(0, -1, 0)); // +Z - else /*dir == 5*/ lookat44(V, lightPos, add3(lightPos, vec3( 0, 0, -1)), vec3(0, -1, 0)); // -Z - multiply44x2(PV, P, V); // -Z - - shader_bind(program); shader_mat44("cameraToShadowView", V); - shader_bind(program); shader_mat44("cameraToShadowProjector", PV); -} - -void shadow_create(int RESOLUTION) { - do_blur = 1; - do_debugshadow = 0; - BLUR_SCALE = 0.5; // Amount of blurring [0..1] - SHADOWMAP_WIDTH = RESOLUTION; // 256,512,1024,2048 - lightPos = vec3(-2, 2.0, -2); - lightAimPos = vec3(0.0, 0, -5.0); - - // Create programs - shadowProgram = shader(vs_shadow_vsm, fs_shadow_vsm, "position", "outColor", ""); - blurProgram = shader(vs_shadow_blur, fs_shadow_blur, "position,,texcoord", "outColor", ""); - - // ShadowMap-textures and FBO // @todo: GL_RG32F+GL_RG also GL_CLAMP to remove artifacts - shadowMapTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 2, NULL, TEXTURE_FLOAT).id; - shadowMapTexDepth = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 0, NULL, TEXTURE_DEPTH | TEXTURE_FLOAT).id; - shadowMapFBO = fbo(shadowMapTex, shadowMapTexDepth, 0); - - // Textures and FBO to perform blurring - blurTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 2, NULL, TEXTURE_FLOAT).id; - blurFBO = fbo(blurTex, 0, 0); - -#if VSMCUBE - // Create cubemap - cubeTex = cubemap_create(SHADOWMAP_WIDTH, 0); - cubeDepthTex = cubemap_create(SHADOWMAP_WIDTH, TEXTURE_DEPTH); - framebuffer_cube_create(cubeFBOs, cubeTex, cubeDepthTex); - // Temporary storage - currentSideTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 2, NULL, TEXTURE_FLOAT /*| TEXTURE_EDGE*/ ).id; - currentSideDepthTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 0, NULL, TEXTURE_DEPTH | TEXTURE_FLOAT).id; - toCurrentSideFBO = fbo(currentSideTex, currentSideDepthTex, 0); -#endif -} -void shadow_destroy() { - glDeleteProgram(shadowProgram); - glDeleteProgram(blurProgram); - - glDeleteTextures(1, &blurTex); - glDeleteFramebuffers(1, &blurFBO); - - glDeleteTextures(1, &shadowMapTex); - glDeleteTextures(1, &shadowMapTexDepth); - glDeleteFramebuffers(1, &shadowMapFBO); -} -bool shadow_is_active() { - return shadow_active; -} -void shadow_pv_matrix(mat44 PV) { - mat44 P,V; -// perspective44(P, 45.0f, 1.0f, 2.0f, 100.0f); -perspective44(P, 45*2, window_width() / ((float)window_height()+!window_height()), 1.f, 100.f); - - lookat44(V, lightPos, lightAimPos, vec3(0, 1, 0)); // Point toward object regardless of position - multiply44x2(PV, P, V); -} -void shadow_position(vec3 p) { - lightPos = p; -} -void shadow_target(vec3 p) { - lightAimPos = p; -} -void shadow_begin() { - shadow_active = 1; - - // shadow_state() { - glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); - glEnable(GL_CULL_FACE); glCullFace(GL_BACK); - glFrontFace(GL_CW); - glBlendFunc(1, 0); -#if VSMCUBE - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); -#endif - // } - - glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO); - - glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_WIDTH); - //glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - mat44 PV; shadow_pv_matrix(PV); - shader_bind(shadowProgram);shader_mat44("cameraToShadowProjector", PV); -} -static void draw_fullscreen_quad() { - //delete_mesh(quadMesh); - if(!quadMesh.vao) quadMesh = create_quad(); - - glBindVertexArray(quadMesh.vao); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); -} -static void shadow_blur() { - // remap 0(min)..1(max) -> 2(min)..epsilon(max) - float blur_scale = 1.999 * (1 - BLUR_SCALE) + 0.001; - - glDisable(GL_DEPTH_TEST); - - // Blur shadowMapTex (horizontally) to blurTex - glBindFramebuffer(GL_FRAMEBUFFER, blurFBO); - glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_WIDTH); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, shadowMapTex); //Input-texture - shader_bind(blurProgram); shader_vec2("ScaleU", vec2(1.0 / (SHADOWMAP_WIDTH*blur_scale), 0)); - shader_int("textureSource",0); -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - draw_fullscreen_quad(); - - // Blur blurTex vertically and write to shadowMapTex - glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO); - glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_WIDTH); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, blurTex); - shader_bind(blurProgram); shader_vec2("ScaleU", vec2(0, 1.0 / (SHADOWMAP_WIDTH*blur_scale))); - shader_int("textureSource",0); -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - draw_fullscreen_quad(); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - glEnable(GL_DEPTH_TEST); -} -void shadow_end() { - // Reset - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - - if(do_blur) shadow_blur(); - shadow_active = 0; - - glViewport(0, 0, window_width(), window_height()); -} -void shadow_ui() { - // UI - if( ui_panel("Shadow", 0) ) { - if(ui_toggle("Debug", &do_debugshadow)) {} - if(ui_toggle("Blur shadow", &do_blur)) {} - if(ui_slider("Blur amount", &BLUR_SCALE)) {} - ui_panel_end(); - } - - if(do_debugshadow) { - // Blur and draw to screen - shader_bind(blurProgram); shader_vec2("ScaleU", vec2(0, 0)); // ... but make sure we don't actually blur - glBindTexture(GL_TEXTURE_2D, shadowMapTex); - draw_fullscreen_quad(); - glBindTexture(GL_TEXTURE_2D, 0); - } -} - -#define USER_DRAWCALL(shader) do { \ - model_render(sponza, camera_get_active()->proj, camera_get_active()->view, sponza.pivot, shader); \ -} while(0) - - -static void vsm_cube_draw() -{ - glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_WIDTH); - - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - shader_bind(shadowProgram); - - // For each side of cubemap - for (int i = 0; i < 6; ++i) { -#if VSMBLUR - // Draw to temp. storage - shader_bind(shadowProgram); - glBindFramebuffer(GL_FRAMEBUFFER, toCurrentSideFBO); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - set_shadow_matrix_uniform(shadowProgram, i); - USER_DRAWCALL(shadowProgram); - - // Blur horizontally to blurTex - glDisable(GL_DEPTH_TEST); - - shader_bind(blurProgram); - shader_vec2("ScaleU", vec2(1.0 / SHADOWMAP_WIDTH, 0)); - - glBindFramebuffer(GL_FRAMEBUFFER, blurFBO); - glBindTexture(GL_TEXTURE_2D, currentSideTex); - glClear(GL_COLOR_BUFFER_BIT); - draw_fullscreen_quad(); - - // Blur vertically to actual cubemap - glBindFramebuffer(GL_FRAMEBUFFER, cubeFBOs[i]); - - glBindTexture(GL_TEXTURE_2D, blurTex); - shader_bind(blurProgram); - shader_vec2("ScaleU", vec2(0, 1.0 / SHADOWMAP_WIDTH)); - - draw_fullscreen_quad(); - - glEnable(GL_DEPTH_TEST); -#else - // Draw directly to cubemap - glBindFramebuffer(GL_FRAMEBUFFER, cubeFBOs[i]); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - set_shadow_matrix_uniform(shadowProgram, i); - USER_DRAWCALL(shadowProgram); -#endif - } - - // Reset state - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); -} - -#undef shadowProgram -#undef blurProgram -#undef quadMesh -#undef shadowMapFBO -#undef shadowMapTex -#undef shadowMapTexDepth -#undef blurFBO -#undef blurTex -#undef do_blur -#undef do_debugshadow -#undef BLUR_SCALE -#undef SHADOWMAP_WIDTH -#undef shadow_active -#undef lightPos -#undef lightAimPos - - - - - -// Geometry (world coordinates) -static bool do_animate = 1; - -static void color_begin(const GLuint program) { - glCullFace(GL_BACK); - -#if 1 // VSMCUBE -glViewport(0, 0, window_width(), window_height()); -glClearColor(0.5f, 0.5f, 0.5f, 1.0f); -glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -#endif - - // Upload uniforms - shader_bind(program); - shader_mat44("view", camera_get_active()->view); -// shader_mat44("proj", camera_get_active()->proj); - shader_vec3("lightPos", shadow.lightPos); - -#if VSMCUBE - set_shadow_matrix_uniform(program, -1); -#else - mat44 PV; shadow_pv_matrix(PV); - shader_mat44("cameraToShadowProjector", PV); -#endif - - glActiveTexture(GL_TEXTURE0+1); -#if VSMCUBE - glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex); -#else - glBindTexture(GL_TEXTURE_2D, shadow.shadowMapTex); //Input-texture -#endif - shader_int("shadowMap",1); -} -static void color_end() { -#if VSMCUBE - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); -#else - glBindTexture(GL_TEXTURE_2D, 0); -#endif -} - - -int main(int argc, char **argv) -{ - window_create(0.75f, 0); - - camera_t cam = camera(); - - // init shadowing 384x384 // 512x512 - shadow_create(argc > 1 ? atoi(argv[1]) : 384); - - sponza = model("sponza.obj", 0); - translation44(sponza.pivot, 0,-1,0); - rotate44(sponza.pivot, -90,1,0,0); - scale44(sponza.pivot, 10,10,10); - - model_t suzanne = model("suzanne.obj", 0); - - // create geometry - GLuint vsm_program = sponza.program; - #if 1 - const char *tpl[] = { - "{{include-shadowmap}}", fs_0_0_shadowmap_lit, - }; - vsm_program = shader(strlerp(1,tpl,vs_323444143_16_332_model), strlerp(1,tpl,fs_32_4_model), "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent", "fragColor", ""); - #endif - - while (window_swap()) - { - // input - if (input(KEY_ESC)) - break; - - // fps camera - bool active = ui_active() ? 0 : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); - vec3 wasdec = scale3( vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-input(KEY_C),input(KEY_W)-input(KEY_S)), 0.2f); - vec2 mouse = scale2( vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); - camera_move(&cam, wasdec.x,wasdec.y,wasdec.z); - camera_fps(&cam, mouse.x,mouse.y); - window_cursor( !active ); - -#if 1 - // animate light - if( do_animate ) { - static vec3 lightPos; - do_once { - lightPos = cam.position; - }; - vec3 offs = vec3(sin(window_time()) * 15, 0, cos(window_time()) * 15); - shadow_position(add3(lightPos, offs)); -// shadow_target(vec3(0,0,0)); // good for pointlight - shadow_target(add3(add3(lightPos, offs), vec3(0,0,-1))); - } -#else - shadow_position(cam.position); - shadow_target(add3(cam.position, cam.look)); -#endif - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // render - -#if VSMCUBE - shadow_begin(); - vsm_cube_draw(); - shadow_end(); -#else - shadow_begin(); - model_render(sponza, camera_get_active()->proj, camera_get_active()->view, sponza.pivot, shadow.shadowProgram); //< typo!, but works! - shadow_end(); -#endif - - color_begin(vsm_program); - model_render(sponza, camera_get_active()->proj, camera_get_active()->view, sponza.pivot, vsm_program); // does not work without program - color_end(); - - -// // light bulb (suzanne) -// { -// mat44 M; scaling44(M, 10,10,10); relocate44(M, shadow.lightPos.x, shadow.lightPos.y, shadow.lightPos.z ); -// model_render(suzanne, camera_get_active()->proj, camera_get_active()->view, M, 0); -// } - - -// if( ui_panel("App", 0) ) { -// if(ui_toggle("Animate light", &do_animate)) {} -// ui_panel_end(); -// } - -// shadow_ui(); - } -} diff --git a/demos/99-sprite.c b/demos/99-sprite.c deleted file mode 100644 index a3da64b..0000000 --- a/demos/99-sprite.c +++ /dev/null @@ -1,227 +0,0 @@ -// sprite routines -// - rlyeh, -// -// credits: original lovely demo by rxi (MIT License). -// see https://github.com/rxi/autobatch/tree/master/demo/cats - -#include "v4k.h" - -texture_t kids, catImage, shadowImage, inputs; -int NUM_SPRITES = 100, NUM_SPRITES_CHANGED = 1; - -typedef struct Cat { - int cat, flip; - double x, y; - double vx, vy; - double animSpeed; - double moveTimer; - double elapsed; -} Cat; - -void demo_cats() { - static array(Cat) cats = 0; - - // init - if( NUM_SPRITES_CHANGED ) { - NUM_SPRITES_CHANGED = 0; - - array_resize(cats, NUM_SPRITES); int i = 0; - for each_array_ptr(cats, Cat, c) { - randset(i++); - c->x = randf() * window_width(); - c->y = randf() * window_height(); - c->vx = c->vy = 0; - c->cat = randi(0, 4); - c->flip = randf() < 0.5; - c->animSpeed = 0.8 + randf() * 0.3; - c->moveTimer = 0; - c->elapsed = 0; - } - } - - // move - const float dt = 1/120.f; - const int appw = window_width(), apph = window_height(); - - enum { yscale = 1 }; - for( int i = 0; i < NUM_SPRITES; ++i ) { - Cat *c = &cats[i]; - // Add velocity to position //and wrap to screen - c->x += yscale * c->vx * dt; // % ; - c->y += yscale * c->vy * dt; // % (int)window_height(); - if( c->x < 0 ) c->x += appw; else if( c->x > appw ) c->x -= appw; - if( c->y < 0 ) c->y += apph; else if( c->y > apph ) c->y -= apph; - // Faster animation if walking - int boost = c->vx == 0 && c->vy == 0 ? 1 : 3; - // Update elapsed time - c->elapsed += dt * boost; - // Update move timer -- if we hit zero then change or zero velocity - c->moveTimer -= dt * boost; - if (c->moveTimer < 0) { - if (randf() < .2) { - c->vx = (randf() * 2 - 1) * 30 * 2; - c->vy = (randf() * 2 - 1) * 15 * 2; - c->flip = c->vx < 0; - } else { - c->vx = c->vy = 0; - } - c->moveTimer = 1 + randf() * 5; - } - } - - // render - uint32_t white = rgba(255,255,255,255); - uint32_t alpha = rgba(255,255,255,255*0.6); - for( int i = 0; i < NUM_SPRITES; ++i ) { - Cat *c = &cats[i]; - // Get current animation frame (8x4 tilesheet) - double e = c->elapsed * c->animSpeed; - double frame_num = c->cat * 8 + floor( ((int)(e * 8)) % 4 ); - frame_num = c->vx != 0 || c->vy != 0 ? frame_num + 4 : frame_num; - // Get x scale based on flip flag - int xscale = yscale * (c->flip ? -1 : 1); - // Draw - float angle = 0; //fmod(window_time()*360/5, 360); - float scale[2] = { 2*xscale, 2*yscale }; - float position[3] = { c->x,c->y,c->y }, no_offset[2] = {0,0}, spritesheet[3] = { frame_num,8,4 }; - sprite_sheet(catImage, - spritesheet, // frame_number in a 8x4 spritesheet - position, angle, // position(x,y,depth: sort by Y), angle - no_offset, scale, // offset(x,y), scale(x,y) - 0,white,0 // is_additive, tint color, resolution independant - ); - float position_neg_sort[3] = { c->x,c->y,-c->y }, offset[2] = {-1,5}, no_spritesheet[3] = {0,0,0}; - sprite_sheet(shadowImage, - no_spritesheet, // no frame_number (0x0 spritesheet) - position_neg_sort, angle, // position(x,y,depth: sort by Y), angle - offset, scale, // offset(x,y), scale(x,y) - 0,alpha,0 // is_additive, tint color, resolution independant - ); - } -} - -void demo_kids() { - static int angle; //++angle; - static int *x, *y, *v; - - // init - if( NUM_SPRITES_CHANGED ) { - NUM_SPRITES_CHANGED = 0; - - y = (int*)REALLOC(y, 0 ); - x = (int*)REALLOC(x, NUM_SPRITES * sizeof(int) ); - y = (int*)REALLOC(y, NUM_SPRITES * sizeof(int) ); - v = (int*)REALLOC(v, NUM_SPRITES * sizeof(int) ); - for( int i = 0; i < NUM_SPRITES; ++i ) { - randset(i); - x[i] = randi(0, window_width()); - y[i] = randi(0, window_height()); - v[i] = randi(1, 3); - } - } - - // config - const int appw = window_width(), apph = window_height(); - - // move & render - for( int i = 0; i < NUM_SPRITES; ++i ) { - y[i] = (y[i] + v[i]) % (apph + 128); - int col = ((x[i] / 10) % 4); // 4x4 tilesheet - int row = ((y[i] / 10) % 4); - int num_frame = col * 4 + row; - float position[3] = {x[i],y[i],y[i]}, offset[2]={0,0}, scale[2]={1,1}, spritesheet[3]={num_frame,4,4}; - sprite_sheet(kids, - spritesheet, // num_frame in a 4x4 spritesheet - position, angle, // position(x,y,depth: sort by Y), angle - offset, scale, // offset(x,y), scale(x,y) - 0, ~0u, 0 // is_additive, tint color, resolution independant - ); - } -} - -int main(int argc, char **argv) { - window_create(75.f, 0); - window_title("V4K - Sprite"); - window_color( SILVER ); - - // options - int do_cats = 1; - NUM_SPRITES = optioni("--num_sprites,-N", NUM_SPRITES); - if(do_cats) NUM_SPRITES/=2; // cat-sprite+cat-shadow == 2 sprites - - // load sprites and sheets - kids = texture( "spriteSheetExample.png", TEXTURE_LINEAR ); - catImage = texture( "cat.png", TEXTURE_LINEAR ); // - shadowImage = texture( "cat-shadow.png", TEXTURE_LINEAR ); - inputs = texture( "prompts_tilemap_34x24_16x16x1.png", TEXTURE_LINEAR ); - - // load all fx files, including subdirs - fx_load("fx**.fs"); - - // init camera (x,y) (z = zoom) - camera_t cam = camera(); - cam.position = vec3(window_width()/2,window_height()/2,1); - camera_enable(&cam); - - while(window_swap()) { - if( input(KEY_F5)) window_reload(); - if( input(KEY_F11)) window_fullscreen( window_has_fullscreen() ^ 1); - if( input(KEY_ESC) ) break; - - // camera panning (x,y) & zooming (z) - if( !ui_hover() && !ui_active() ) { - if( input(MOUSE_L) ) cam.position.x -= input_diff(MOUSE_X); - if( input(MOUSE_L) ) cam.position.y -= input_diff(MOUSE_Y); - cam.position.z += input_diff(MOUSE_W) * 0.1; // cam.p.z += 0.001f; for tests - } - - // apply post-fxs from here - fx_begin(); - - profile("Sprite batching") { - if(do_cats) demo_cats(); else demo_kids(); - } - - // flush retained renderer, so we ensure the fbos are up to date before fx_end() - profile("Sprite flushing") { - sprite_flush(); - } - - // post-fxs end here - fx_end(); - - // draw pixel-art hud, 16x16 ui element, scaled and positioned in resolution-independant way - { - vec3 old_pos = camera_get_active()->position; - - sprite_flush(); - camera_get_active()->position = vec3(window_width()/2,window_height()/2,1); - - float zindex = window_height(); // large number, on top - float spritesheet[3] = {17,34,24}, offset[2] = {0, - 2*absf(sin(window_time()*5))}; // sprite cell and animation - float scale[2] = {3, 3}, tile_w = 16 * scale[0], tile_h = 16 * scale[1]; // scaling - float position[3] = {window_width() - tile_w, window_height() - tile_h, zindex }; // position in screen-coordinates - sprite_sheet(inputs, spritesheet, position, 0/*rotation*/, offset, scale, false/*is_additive*/, WHITE/*color*/, false/*resolution_independant*/); - - sprite_flush(); - camera_get_active()->position = old_pos; - } - - if( ui_panel("Sprite", 0) ) { - const char *labels[] = {"Kids","Cats"}; - if( ui_list("Sprite type", labels, countof(labels), &do_cats) ) NUM_SPRITES_CHANGED = 1; - if( ui_int("Number of Sprites", &NUM_SPRITES) ) NUM_SPRITES_CHANGED = 1; - if( ui_clampf("Zoom", &cam.position.z, 0.1, 10)); - ui_panel_end(); - } - if( ui_panel("FX", 0) ) { - for( int i = 0; i < 64; ++i ) { - 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 c2e3d93..8d930b1 100644 --- a/demos/99-temperature.c +++ b/demos/99-temperature.c @@ -76,7 +76,7 @@ int main() { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, TEX_WIDTH, TEX_WIDTH, 0, GL_RGBA, GL_FLOAT, img); shader_bind(comp); compute_dispatch(TEX_WIDTH/16, TEX_WIDTH/16, 1); - image_write_barrier(); + write_barrier_image(); } else { temp_calc(img); texture_update(&tex, TEX_WIDTH, TEX_WIDTH, 4, img, TEXTURE_LINEAR|TEXTURE_FLOAT); diff --git a/demos/art/fx/fxAberration.fs b/demos/art/fx/fxAberration.fs index 3d3c498..b35bfad 100644 --- a/demos/art/fx/fxAberration.fs +++ b/demos/art/fx/fxAberration.fs @@ -1,9 +1,9 @@ -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 +uniform float separation; /// min:-0.10 max:0.10 set:0.003 +uniform float angle; /// min:0 max:6.28 set:0 void main() { vec2 uv = TEXCOORD.st; - vec2 offset = intensity * vec2( cos(angle), sin(angle) ); + vec2 offset = separation * vec2( cos(angle), sin(angle) ); vec4 color = texture( iChannel0, uv); color.r = texture( iChannel0, uv + offset ).x; color.b = texture( iChannel0, uv - offset ).z; diff --git a/demos/art/fx/fxBloom.fs b/demos/art/fx/fxBloom.fs index dc4e07e..004c4db 100644 --- a/demos/art/fx/fxBloom.fs +++ b/demos/art/fx/fxBloom.fs @@ -1,4 +1,4 @@ -uniform float intensity = 2.0; /// set:2.0 +uniform float intensity; /// set:2.0 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; diff --git a/demos/art/fx/fxBlurHorizontal.fs b/demos/art/fx/fxBlurHorizontal.fs new file mode 100644 index 0000000..0796237 --- /dev/null +++ b/demos/art/fx/fxBlurHorizontal.fs @@ -0,0 +1,15 @@ +// [ref] https://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ + +uniform float intensity; /// set:4 + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) { + vec2 uv = fragCoord.xy / iResolution.xy; + + vec4 base = texture(iChannel0, uv), color = vec4(0.0); + vec2 offset = vec2(intensity,0) / iResolution; + color += base * 0.30; + color += texture(iChannel0, uv + offset) * 0.35; + color += texture(iChannel0, uv - offset) * 0.35; + + fragColor = vec4( color.rgb, base.a ); +} diff --git a/demos/art/fx/fxBlurVertical.fs b/demos/art/fx/fxBlurVertical.fs new file mode 100644 index 0000000..c405d5f --- /dev/null +++ b/demos/art/fx/fxBlurVertical.fs @@ -0,0 +1,15 @@ +// [ref] https://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ + +uniform float intensity; /// set:4 + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) { + vec2 uv = fragCoord.xy / iResolution.xy; + + vec4 base = texture(iChannel0, uv), color = vec4(0.0); + vec2 offset = vec2(0,intensity) / iResolution; + color += base * 0.30; + color += texture(iChannel0, uv + offset) * 0.35; + color += texture(iChannel0, uv - offset) * 0.35; + + fragColor = vec4( color.rgb, base.a ); +} diff --git a/demos/art/fx/fxColorblind.fs b/demos/art/fx/fxColorblind.fs index aabc31f..51633c5 100644 --- a/demos/art/fx/fxColorblind.fs +++ b/demos/art/fx/fxColorblind.fs @@ -1,6 +1,6 @@ // [ref] https://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulation.html -uniform int colorblind_mode = 2; /// min:0 max:4 set:2 tip:"off, achromatopsia, protanomaly, deuteranomaly, tritanomaly" +uniform int colorblind_mode; /// set:2 min:0 max:4 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) diff --git a/demos/art/fx/fxContrast.fs b/demos/art/fx/fxContrast.fs index 0489b72..4975a85 100644 --- a/demos/art/fx/fxContrast.fs +++ b/demos/art/fx/fxContrast.fs @@ -1,5 +1,5 @@ -uniform float contrast = 1.5; /// set:1.5 tip:"bleach-to-gray < 1 > saturate" -uniform float brightness = 0; /// set:0 max:2 +uniform float contrast; /// set:1.5 tip:"bleach-to-gray < 1 > saturate" +uniform float brightness; /// 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 fdbe96e..0a6bc4a 100644 --- a/demos/art/fx/fxDissolve.fs +++ b/demos/art/fx/fxDissolve.fs @@ -1,4 +1,4 @@ -uniform float intensity = 0.004; /// set:0.004 max:0.03 +uniform float intensity; /// set:0.004 max:0.03 highp float rand(vec2 co) { highp float a = 12.9898; diff --git a/demos/art/fx/fxFXAA.fs b/demos/art/fx/fxFXAA.fs index c034695..ca3fa2f 100644 --- a/demos/art/fx/fxFXAA.fs +++ b/demos/art/fx/fxFXAA.fs @@ -1,3 +1,5 @@ +/// tip:"Requires MSAA off for best results" + // FXAA fragment shader by Timothy Lottes (public domain) // http://timothylottes.blogspot.com/ diff --git a/demos/art/fx/fxFXAA3.fs b/demos/art/fx/fxFXAA3.fs index fabceb1..821e9f8 100644 --- a/demos/art/fx/fxFXAA3.fs +++ b/demos/art/fx/fxFXAA3.fs @@ -1,3 +1,5 @@ +/// tip:"Requires MSAA off for best results" + /***************************************** * FXAA 3.11 Implementation - effendiian * ------------------------------------- diff --git a/demos/art/fx/fxGrain.fs b/demos/art/fx/fxGrain.fs index dd044a0..4f1c9d7 100644 --- a/demos/art/fx/fxGrain.fs +++ b/demos/art/fx/fxGrain.fs @@ -1,4 +1,4 @@ -uniform float intensity = 16.0; /// set:16 max:32 +uniform float intensity; /// 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 3b49422..b993c45 100644 --- a/demos/art/fx/fxHSV.fs +++ b/demos/art/fx/fxHSV.fs @@ -1,6 +1,6 @@ -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" +uniform float h; /// set:1.58 tip:"hue color shift" +uniform float s; /// set:1.51 tip:"gray: <1, saturate: >1" +uniform float v; /// set:1.05 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 bbf5897..4dcb21f 100644 --- a/demos/art/fx/fxLetterbox.fs +++ b/demos/art/fx/fxLetterbox.fs @@ -1,10 +1,13 @@ +uniform float amount; /// min:0 set:0.10 max:0.5 + void mainImage( out vec4 fragColor, in vec2 fragCoord ) { + vec2 uv = fragCoord.xy / iResolution.xy; + // letterbox - if( abs(2.*fragCoord.y-iResolution.y) > iResolution.x * 0.42 ) { + if( uv.y < amount || (1.0-uv.y) < amount ) { fragColor = vec4( 0., 0., 0., 1. ); return; } - vec2 uv = fragCoord.xy / iResolution.xy; fragColor = texture(iChannel0, uv); } diff --git a/demos/art/fx/fxOutline.fs b/demos/art/fx/fxOutline.fs index 6f66d91..08de528 100644 --- a/demos/art/fx/fxOutline.fs +++ b/demos/art/fx/fxOutline.fs @@ -1,5 +1,7 @@ -uniform int thickness = 2; /// set:2 -uniform vec4 border_color = vec4(1,1,0,1); /// set:1,1,0,1 +/// tip:"Ensure colorbuffer is alpha clear before calling this one." + +uniform int thickness; /// set:2 +uniform vec4 border_color; /// 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 67c4a53..0391c5a 100644 --- a/demos/art/fx/fxPixelate.fs +++ b/demos/art/fx/fxPixelate.fs @@ -1,6 +1,6 @@ -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 +uniform float CellSize; /// min:1 set:2.5 max:16 +//uniform float xCellSize; /// min:1 set:2.5 +//uniform float yCellSize; /// min:1 set:2.5 void main() { float xPixels = iWidth/CellSize, yPixels = iHeight/CellSize; // iWidth/xCellSize, iHeight/yCellSize; diff --git a/demos/art/fx/fxQuantize.fs b/demos/art/fx/fxQuantize.fs index a17b08c..de39385 100644 --- a/demos/art/fx/fxQuantize.fs +++ b/demos/art/fx/fxQuantize.fs @@ -1,4 +1,4 @@ -uniform float factor = 3.0; /// min:1 max:255 set:3 +uniform float factor; /// 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/fxSSAO.fs b/demos/art/fx/fxSSAO.fs index b5a0470..6e97114 100644 --- a/demos/art/fx/fxSSAO.fs +++ b/demos/art/fx/fxSSAO.fs @@ -1,7 +1,7 @@ // based on code by arkano22. See: http://www.gamedev.net/forums/topic/550699-ssao-no-halo-artifacts/ // - rlyeh, public domain -uniform vec2 camerarange = vec2(1.0, 1024.0); +uniform vec2 camerarange; /// set:1,1024 // uniform sampler2D som; // Depth texture (iChannel1) diff --git a/demos/art/fx/fxScanlines.fs b/demos/art/fx/fxScanlines.fs index ff2cdf3..4910cdb 100644 --- a/demos/art/fx/fxScanlines.fs +++ b/demos/art/fx/fxScanlines.fs @@ -1,5 +1,5 @@ -uniform float hardness = 0.1; /// set:0.1 max:2 -uniform float flickering = 0.01; /// set:0.01 +uniform float hardness; /// set:0.1 max:2 +uniform float flickering; /// 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 996c8a7..f3bc93a 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; /// min:245 max:255 set:250 +uniform float intensity; /// 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 8bd23d3..2e348eb 100644 --- a/demos/art/fx/fxSepia.fs +++ b/demos/art/fx/fxSepia.fs @@ -1,13 +1,13 @@ -uniform float intensity = 1.0; /// set:1 +uniform float brightness; /// set:1 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; vec4 src = texture(iChannel0, uv); vec3 color = vec3( - dot(src.rgb, vec3(0.393 * intensity, 0.769 * intensity, 0.189 * intensity)), - dot(src.rgb, vec3(0.349 * intensity, 0.686 * intensity, 0.168 * intensity)), - dot(src.rgb, vec3(0.272 * intensity, 0.534 * intensity, 0.131 * intensity)) + dot(src.rgb, vec3(0.393 * brightness, 0.769 * brightness, 0.189 * brightness)), + dot(src.rgb, vec3(0.349 * brightness, 0.686 * brightness, 0.168 * brightness)), + dot(src.rgb, vec3(0.272 * brightness, 0.534 * brightness, 0.131 * brightness)) ); fragColor = vec4(color, src.a); diff --git a/demos/art/fx/fxSharpen.fs b/demos/art/fx/fxSharpen.fs index 41debf1..0ec9e95 100644 --- a/demos/art/fx/fxSharpen.fs +++ b/demos/art/fx/fxSharpen.fs @@ -1,4 +1,4 @@ -uniform float intensity = 0.25; /// set:0.25 max:2 +uniform float intensity; /// 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 6f213fe..d4028f0 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; // min:0.1 max:5 set:1 +uniform float exposure; // 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 b210514..3ad1a29 100644 --- a/demos/art/fx/fxTonemapZZGamma.fs +++ b/demos/art/fx/fxTonemapZZGamma.fs @@ -1,4 +1,4 @@ -uniform float gamma = 2.2; /// set:2.2 +uniform float gamma; /// set:2.2 out vec4 color; void main(void) { diff --git a/demos/art/fx/fxVignette.fs b/demos/art/fx/fxVignette.fs index 10d17a7..6fa088b 100644 --- a/demos/art/fx/fxVignette.fs +++ b/demos/art/fx/fxVignette.fs @@ -1,4 +1,4 @@ -uniform float radius = 0.75; /// set:0.75 +uniform float radius; /// set:0.75 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; diff --git a/demos/art/meshes/sphere.obj b/demos/art/meshes/sphere.obj new file mode 100644 index 0000000..8a1bf90 --- /dev/null +++ b/demos/art/meshes/sphere.obj @@ -0,0 +1,1833 @@ +v -1 0 1.40385e-007 +v -0.983024 -0.156077 0.0964607 +v -0.983024 0.156077 -0.0964604 +v -0.978148 -0.185961 -0.0929805 +v -0.978148 0 0.207911 +v -0.978148 0 -0.207911 +v -0.978148 0.185961 0.0929807 +v -0.939205 -0.343331 0.00428931 +v -0.939205 -0.157379 0.305166 +v -0.939205 0.157379 -0.305166 +v -0.939205 0.343331 -0.00428905 +v -0.934172 -0.187593 -0.303531 +v -0.934172 0.187593 0.303531 +v -0.93267 -0.306855 0.189647 +v -0.93267 0.306855 -0.189647 +v -0.913545 -0.363797 -0.181898 +v -0.913545 0 0.406737 +v -0.913545 0 -0.406737 +v -0.913545 0.363797 0.181899 +v -0.866018 -0.490334 0.0979075 +v -0.866018 -0.306855 0.394783 +v -0.866018 0.306855 -0.394782 +v -0.866018 0.490334 -0.0979072 +v -0.851981 -0.516806 -0.0839041 +v -0.851981 -0.156077 0.499769 +v -0.851981 0.156077 -0.499768 +v -0.851981 0.516806 0.0839044 +v -0.850651 -0.447214 0.276393 +v -0.850651 0.447214 -0.276393 +v -0.845991 -0.363797 -0.389809 +v -0.845991 -0.185961 -0.499718 +v -0.845991 0.185961 0.499718 +v -0.845991 0.363797 0.38981 +v -0.809017 -0.525731 -0.262865 +v -0.809017 0 0.587785 +v -0.809017 0 -0.587785 +v -0.809017 0.525731 0.262866 +v -0.762354 -0.644208 0.0617517 +v -0.762354 -0.343331 0.548581 +v -0.762354 0.343331 -0.548581 +v -0.762354 0.644208 -0.0617515 +v -0.758172 -0.60373 0.246345 +v -0.758172 -0.490334 0.429824 +v -0.758172 0.490334 -0.429824 +v -0.758172 0.60373 -0.246345 +v -0.757312 -0.343331 -0.555521 +v -0.757311 0.343331 0.555521 +v -0.738585 -0.516806 -0.432902 +v -0.738585 -0.156077 -0.655845 +v -0.738585 0.156077 0.655845 +v -0.738585 0.516806 0.432902 +v -0.736686 -0.664689 -0.124433 +v -0.736686 0.185961 -0.650164 +v -0.736685 -0.185961 0.650164 +v -0.736685 0.664689 0.124433 +v -0.669131 -0.664689 -0.332344 +v -0.669131 0 0.743144 +v -0.669131 0 -0.743144 +v -0.669131 0.664689 0.332344 +v -0.653054 -0.644208 0.398142 +v -0.653054 0.644208 -0.398142 +v -0.643075 -0.490334 -0.588241 +v -0.643075 -0.306855 -0.701637 +v -0.643075 0.306855 0.701637 +v -0.643075 0.490334 0.588241 +v -0.639949 -0.739749 0.207932 +v -0.639949 -0.516806 0.568662 +v -0.639949 0.516806 -0.568662 +v -0.639949 0.739749 -0.207932 +v -0.632156 -0.774597 0.0194389 +v -0.632156 -0.363797 0.684127 +v -0.632156 0.363797 -0.684127 +v -0.632156 0.774597 -0.0194387 +v -0.580461 -0.644208 -0.498058 +v -0.580461 -0.157379 -0.798935 +v -0.58046 0.157379 0.798935 +v -0.58046 0.644208 0.498058 +v -0.57735 -0.794654 -0.187592 +v -0.57735 -0.187593 0.794655 +v -0.57735 0.187593 -0.794654 +v -0.57735 0.794654 0.187593 +v -0.525731 -0.447214 -0.723607 +v -0.525731 0.447214 0.723607 +v -0.522851 -0.774597 0.355846 +v -0.522851 -0.664689 0.533682 +v -0.522851 0.664689 -0.533681 +v -0.522851 0.774597 -0.355846 +v -0.5 -0.850651 0.16246 +v -0.5 -0.525731 0.688191 +v -0.5 0.525731 -0.688191 +v -0.5 0.850651 -0.16246 +v -0.499999 -0.774597 -0.387298 +v -0.499999 0 0.866026 +v -0.499999 0 -0.866026 +v -0.499999 0.774597 0.387299 +v -0.468576 -0.60373 -0.644939 +v -0.468576 -0.306855 -0.828418 +v -0.468576 0.306855 0.828418 +v -0.468576 0.60373 0.644939 +v -0.455297 -0.889527 -0.0380263 +v -0.455297 -0.363797 0.812623 +v -0.455297 0.363797 -0.812623 +v -0.455297 0.889527 0.0380264 +v -0.395511 -0.739749 -0.544373 +v -0.395511 -0.156077 -0.905103 +v -0.39551 0.156077 0.905103 +v -0.39551 0.739749 0.544373 +v -0.390694 -0.889527 -0.236853 +v -0.390694 -0.185961 0.901541 +v -0.390694 0.185961 -0.901541 +v -0.390694 0.889527 0.236853 +v -0.36073 -0.490334 -0.793377 +v -0.36073 0.490334 0.793377 +v -0.356822 -0.794654 0.491123 +v -0.356822 0.794655 -0.491123 +v -0.345991 -0.889527 0.298381 +v -0.345991 -0.664689 0.662178 +v -0.345991 0.664689 -0.662178 +v -0.345991 0.889527 -0.298381 +v -0.343074 -0.93267 0.111472 +v -0.343074 -0.516806 0.784354 +v -0.343074 0.516806 -0.784354 +v -0.343074 0.93267 -0.111472 +v -0.309017 -0.850651 -0.425325 +v -0.309017 0 0.951057 +v -0.309017 0 -0.951056 +v -0.309017 0.850651 0.425325 +v -0.29431 -0.644208 -0.705959 +v -0.29431 -0.343331 -0.891911 +v -0.294309 0.343331 0.891911 +v -0.294309 0.644208 0.705959 +v -0.286151 -0.953663 -0.092976 +v -0.286151 -0.343331 0.894562 +v -0.286151 0.343331 -0.894562 +v -0.286151 0.953663 0.0929761 +v -0.213835 -0.774597 -0.595209 +v -0.213835 -0.185961 -0.959006 +v -0.213834 0.185961 0.959006 +v -0.213834 0.774597 0.595209 +v -0.212032 -0.93267 -0.291836 +v -0.212032 0.156077 -0.964719 +v -0.212032 0.93267 0.291836 +v -0.212031 -0.156077 0.964719 +v -0.183479 -0.516806 -0.83621 +v -0.183479 0.516806 0.83621 +v -0.17686 -0.889527 0.421262 +v -0.17686 -0.774597 0.607223 +v -0.17686 0.774597 -0.607223 +v -0.17686 0.889527 -0.421262 +v -0.176851 -0.953663 0.243415 +v -0.176851 -0.644208 0.744124 +v -0.176851 0.644208 -0.744124 +v -0.176851 0.953663 -0.243415 +v -0.174499 -0.983024 0.0566981 +v -0.174499 -0.490334 0.853887 +v -0.174499 0.490334 -0.853887 +v -0.174499 0.983024 -0.0566981 +v -0.109305 -0.664689 -0.739082 +v -0.109305 -0.363797 -0.925043 +v -0.109305 0.363797 0.925043 +v -0.109305 0.664689 0.739082 +v -0.107846 -0.983024 -0.148438 +v -0.107846 -0.306855 0.945626 +v -0.107846 0.306855 -0.945626 +v -0.107846 0.983024 0.148438 +v -0.104529 -0.889527 -0.444764 +v -0.104529 0 0.994522 +v -0.104529 0 -0.994522 +v -0.104529 0.889527 0.444764 +v -7.96122e-008 -0.525731 -0.850651 +v -5.98336e-008 -0.187593 -0.982247 +v -5.68148e-008 -0.794655 -0.607062 +v -3.18213e-008 0.157379 -0.987538 +v -2.8159e-008 -0.953663 -0.300877 +v 0 -1 -0 +v 0 0.447214 -0.894427 +v 0 0.60373 -0.797189 +v 0 0.739749 -0.672883 +v 0 0.850651 -0.525731 +v 0 0.93267 -0.36073 +v 0 0.983024 -0.183479 +v 0 1 -0 +v 1.71718e-008 -0.983024 0.183479 +v 2.8159e-008 0.953663 0.300877 +v 3.37606e-008 -0.93267 0.36073 +v 4.92031e-008 -0.850651 0.525731 +v 5.68148e-008 0.794654 0.607062 +v 6.29749e-008 -0.739749 0.672883 +v 7.46087e-008 -0.60373 0.797189 +v 7.96122e-008 0.525731 0.850651 +v 8.37093e-008 -0.447214 0.894427 +v 9.19283e-008 0.187593 0.982247 +v 9.24235e-008 -0.157379 0.987538 +v 0.104529 -0.889527 -0.444764 +v 0.104529 0 0.994522 +v 0.104529 0 -0.994522 +v 0.104529 0.889527 0.444764 +v 0.107846 -0.983024 -0.148438 +v 0.107846 -0.306855 0.945626 +v 0.107846 0.306855 -0.945626 +v 0.107846 0.983024 0.148438 +v 0.109305 -0.664689 -0.739082 +v 0.109305 -0.363797 -0.925043 +v 0.109305 0.363797 0.925043 +v 0.109305 0.664689 0.739082 +v 0.174499 -0.983024 0.0566981 +v 0.174499 -0.490334 0.853887 +v 0.174499 0.490334 -0.853887 +v 0.174499 0.983024 -0.0566981 +v 0.176851 -0.953663 0.243415 +v 0.176851 -0.644208 0.744124 +v 0.176851 0.644208 -0.744124 +v 0.176851 0.953663 -0.243415 +v 0.17686 -0.889527 0.421262 +v 0.17686 -0.774597 0.607223 +v 0.17686 0.774597 -0.607223 +v 0.17686 0.889527 -0.421262 +v 0.183479 -0.516806 -0.83621 +v 0.183479 0.516806 0.83621 +v 0.212032 -0.93267 -0.291836 +v 0.212032 -0.156077 0.964719 +v 0.212032 0.156077 -0.964719 +v 0.212032 0.93267 0.291836 +v 0.213834 -0.774597 -0.595209 +v 0.213834 -0.185961 -0.959006 +v 0.213834 0.774597 0.595209 +v 0.213835 0.185961 0.959006 +v 0.286151 -0.953663 -0.0929761 +v 0.286151 -0.343331 0.894562 +v 0.286151 0.343331 -0.894562 +v 0.286151 0.953663 0.0929761 +v 0.294309 -0.644208 -0.705959 +v 0.294309 -0.343331 -0.891911 +v 0.29431 0.343331 0.891911 +v 0.29431 0.644208 0.705959 +v 0.309017 -0.850651 -0.425325 +v 0.309017 0 0.951056 +v 0.309017 0 -0.951057 +v 0.309017 0.850651 0.425325 +v 0.343074 -0.93267 0.111472 +v 0.343074 -0.516806 0.784354 +v 0.343074 0.516806 -0.784354 +v 0.343074 0.93267 -0.111472 +v 0.345991 -0.889527 0.298381 +v 0.345991 -0.664689 0.662178 +v 0.345991 0.664689 -0.662178 +v 0.345991 0.889527 -0.298381 +v 0.356822 -0.794654 0.491123 +v 0.356822 0.794654 -0.491123 +v 0.36073 -0.490334 -0.793377 +v 0.36073 0.490334 0.793377 +v 0.390694 -0.889527 -0.236853 +v 0.390694 -0.185961 0.901541 +v 0.390694 0.185961 -0.901541 +v 0.390694 0.889527 0.236853 +v 0.39551 -0.739749 -0.544373 +v 0.39551 -0.156077 -0.905103 +v 0.39551 0.739749 0.544373 +v 0.395511 0.156077 0.905103 +v 0.455297 -0.889527 -0.0380264 +v 0.455297 -0.363797 0.812623 +v 0.455297 0.363797 -0.812623 +v 0.455297 0.889527 0.0380263 +v 0.468576 -0.60373 -0.644939 +v 0.468576 -0.306855 -0.828418 +v 0.468576 0.306855 0.828418 +v 0.468576 0.60373 0.644939 +v 0.499999 -0.774597 -0.387298 +v 0.499999 0 0.866026 +v 0.499999 0 -0.866026 +v 0.499999 0.774597 0.387298 +v 0.5 -0.850651 0.16246 +v 0.5 -0.525731 0.688191 +v 0.5 0.525731 -0.688191 +v 0.5 0.850651 -0.16246 +v 0.522851 -0.774597 0.355846 +v 0.522851 -0.664689 0.533681 +v 0.522851 0.664689 -0.533682 +v 0.522851 0.774597 -0.355846 +v 0.525731 -0.447214 -0.723607 +v 0.525731 0.447214 0.723607 +v 0.57735 -0.794654 -0.187592 +v 0.57735 -0.187593 0.794654 +v 0.57735 0.187593 -0.794654 +v 0.57735 0.794654 0.187592 +v 0.58046 -0.644208 -0.498058 +v 0.58046 -0.157379 -0.798935 +v 0.58046 0.644208 0.498058 +v 0.580461 0.157379 0.798935 +v 0.632156 -0.774597 0.0194388 +v 0.632156 -0.363797 0.684127 +v 0.632156 0.363797 -0.684127 +v 0.632156 0.774597 -0.0194389 +v 0.639949 -0.739749 0.207932 +v 0.639949 -0.516806 0.568662 +v 0.639949 0.516806 -0.568662 +v 0.639949 0.739749 -0.207932 +v 0.643075 -0.490334 -0.588241 +v 0.643075 -0.306855 -0.701637 +v 0.643075 0.306855 0.701637 +v 0.643075 0.490334 0.588241 +v 0.653054 -0.644208 0.398142 +v 0.653054 0.644208 -0.398142 +v 0.669131 -0.664689 -0.332344 +v 0.669131 0 0.743144 +v 0.669131 0 -0.743144 +v 0.669131 0.664689 0.332344 +v 0.736685 -0.664689 -0.124433 +v 0.736686 -0.185961 0.650164 +v 0.736686 0.185961 -0.650164 +v 0.736686 0.664689 0.124433 +v 0.738585 -0.516806 -0.432902 +v 0.738585 -0.156077 -0.655845 +v 0.738585 0.156077 0.655845 +v 0.738585 0.516806 0.432902 +v 0.757311 -0.343331 -0.555521 +v 0.757312 0.343331 0.555521 +v 0.758172 -0.60373 0.246345 +v 0.758172 -0.490334 0.429824 +v 0.758172 0.490334 -0.429824 +v 0.758172 0.60373 -0.246345 +v 0.762354 -0.644208 0.0617515 +v 0.762354 -0.343331 0.548581 +v 0.762354 0.343331 -0.548581 +v 0.762354 0.644208 -0.0617516 +v 0.809017 -0.525731 -0.262866 +v 0.809017 0 0.587785 +v 0.809017 0 -0.587785 +v 0.809017 0.525731 0.262865 +v 0.845991 -0.363797 -0.389809 +v 0.845991 -0.185961 -0.499718 +v 0.845991 0.185961 0.499718 +v 0.845991 0.363797 0.389809 +v 0.850651 -0.447214 0.276393 +v 0.850651 0.447214 -0.276393 +v 0.851981 -0.516806 -0.0839043 +v 0.851981 -0.156077 0.499768 +v 0.851981 0.156077 -0.499769 +v 0.851981 0.516806 0.0839042 +v 0.866018 -0.490334 0.0979073 +v 0.866018 -0.306855 0.394782 +v 0.866018 0.306855 -0.394782 +v 0.866018 0.490334 -0.0979074 +v 0.913545 -0.363797 -0.181898 +v 0.913545 0 0.406737 +v 0.913545 0 -0.406737 +v 0.913545 0.363797 0.181898 +v 0.93267 -0.306855 0.189647 +v 0.93267 0.306855 -0.189647 +v 0.934172 -0.187593 -0.303531 +v 0.934172 0.187593 0.303531 +v 0.939205 -0.343331 0.00428914 +v 0.939205 -0.157379 0.305166 +v 0.939205 0.157379 -0.305166 +v 0.939205 0.343331 -0.00428922 +v 0.978148 -0.185961 -0.0929806 +v 0.978148 0 0.207911 +v 0.978148 0 -0.207911 +v 0.978148 0.185961 0.0929806 +v 0.983024 -0.156077 0.0964605 +v 0.983024 0.156077 -0.0964606 +v 1 0 -4.67949e-008 +vt -0.05 0.0972793 +vt -0.05 0.941264 +vt -0.0156234 0.327121 +vt -0.0150836 0.44046 +vt -0.0132618 0.151034 +vt -0.0128636 0.722813 +vt -0.00489247 0.782047 +vt -0.000726819 0.611555 +vt 2.2343e-008 0.5 +vt 0.000726849 0.388445 +vt 0.0048925 0.217953 +vt 0.0128637 0.277187 +vt 0.0132618 0.848966 +vt 0.0150836 0.55954 +vt 0.0155675 0.450115 +vt 0.0156234 0.672879 +vt 0.0179172 0.336875 +vt 0.0266314 0.731436 +vt 0.0312808 0.61852 +vt 0.0319269 0.400723 +vt 0.0333332 0.5 +vt 0.0499999 0.0587359 +vt 0.05 0.352416 +vt 0.05 0.449696 +vt 0.05 0.234944 +vt 0.05 0.293681 +vt 0.05 0.902721 +vt 0.05 0.560069 +vt 0.05 0.176208 +vt 0.0500001 0.676208 +vt 0.0500001 0.792348 +vt 0.0500002 1 +vt 0.0500002 0.117472 +vt 0.0666667 0.5 +vt 0.0680732 0.400723 +vt 0.0687194 0.61852 +vt 0.0733685 0.731436 +vt 0.0820829 0.336875 +vt 0.0843766 0.672879 +vt 0.0844326 0.450115 +vt 0.0849164 0.55954 +vt 0.0867383 0.848966 +vt 0.0871363 0.277187 +vt 0.0951076 0.217953 +vt 0.0992732 0.388445 +vt 0.1 0.5 +vt 0.100727 0.611555 +vt 0.104893 0.782047 +vt 0.112864 0.722813 +vt 0.113262 0.151034 +vt 0.115084 0.44046 +vt 0.115567 0.549885 +vt 0.115623 0.327121 +vt 0.117917 0.663125 +vt 0.126632 0.268564 +vt 0.131281 0.38148 +vt 0.131927 0.599277 +vt 0.133333 0.5 +vt 0.15 0.882528 +vt 0.15 0.70632 +vt 0.15 0.823792 +vt 0.15 0.207652 +vt 0.15 0 +vt 0.15 0.323792 +vt 0.15 0.765056 +vt 0.15 0.550304 +vt 0.15 0.647584 +vt 0.15 0.439931 +vt 0.15 0.0972794 +vt 0.15 0.941264 +vt 0.166667 0.5 +vt 0.168073 0.599277 +vt 0.168719 0.38148 +vt 0.173369 0.268564 +vt 0.182083 0.663125 +vt 0.184377 0.327121 +vt 0.184433 0.549885 +vt 0.184916 0.44046 +vt 0.186738 0.151034 +vt 0.187136 0.722813 +vt 0.195108 0.782047 +vt 0.199273 0.611555 +vt 0.2 0.5 +vt 0.200727 0.388445 +vt 0.204892 0.217953 +vt 0.212864 0.277187 +vt 0.213262 0.848966 +vt 0.215084 0.55954 +vt 0.215568 0.450115 +vt 0.215623 0.672879 +vt 0.217917 0.336875 +vt 0.226632 0.731436 +vt 0.231281 0.61852 +vt 0.231927 0.400723 +vt 0.233333 0.5 +vt 0.25 0.0587359 +vt 0.25 0.117472 +vt 0.25 0.176208 +vt 0.25 0.234944 +vt 0.25 0.293681 +vt 0.25 0.352416 +vt 0.25 0.449696 +vt 0.25 0.560069 +vt 0.25 0.676208 +vt 0.25 0.792348 +vt 0.25 0.902721 +vt 0.25 1 +vt 0.266667 0.5 +vt 0.268073 0.400723 +vt 0.268719 0.61852 +vt 0.273369 0.731436 +vt 0.282083 0.336875 +vt 0.284377 0.672879 +vt 0.284433 0.450115 +vt 0.284916 0.55954 +vt 0.286738 0.848966 +vt 0.287136 0.277187 +vt 0.295108 0.217953 +vt 0.299273 0.388445 +vt 0.3 0.5 +vt 0.300727 0.611555 +vt 0.304892 0.782047 +vt 0.312864 0.722813 +vt 0.313262 0.151034 +vt 0.315084 0.44046 +vt 0.315568 0.549885 +vt 0.315623 0.327121 +vt 0.317917 0.663125 +vt 0.326631 0.268564 +vt 0.331281 0.38148 +vt 0.331927 0.599277 +vt 0.333333 0.5 +vt 0.35 0.941264 +vt 0.35 0.0972794 +vt 0.35 0.647584 +vt 0.35 0.765056 +vt 0.35 0.323792 +vt 0.35 0 +vt 0.35 0.439931 +vt 0.35 0.207652 +vt 0.35 0.70632 +vt 0.35 0.823792 +vt 0.35 0.550304 +vt 0.35 0.882528 +vt 0.366667 0.5 +vt 0.368073 0.599277 +vt 0.368719 0.38148 +vt 0.373369 0.268564 +vt 0.382083 0.663125 +vt 0.384377 0.327121 +vt 0.384433 0.549885 +vt 0.384916 0.44046 +vt 0.386738 0.151034 +vt 0.387136 0.722813 +vt 0.395108 0.782047 +vt 0.399273 0.611555 +vt 0.4 0.5 +vt 0.400727 0.388445 +vt 0.404892 0.217953 +vt 0.412864 0.277187 +vt 0.413262 0.848966 +vt 0.415084 0.55954 +vt 0.415568 0.450115 +vt 0.415623 0.672879 +vt 0.417917 0.336875 +vt 0.426631 0.731436 +vt 0.431281 0.61852 +vt 0.431927 0.400723 +vt 0.433333 0.5 +vt 0.45 0.117472 +vt 0.45 1 +vt 0.45 0.176208 +vt 0.45 0.293681 +vt 0.45 0.560069 +vt 0.45 0.902721 +vt 0.45 0.234944 +vt 0.45 0.449696 +vt 0.45 0.0587359 +vt 0.45 0.352416 +vt 0.45 0.676208 +vt 0.45 0.792348 +vt 0.466667 0.5 +vt 0.468073 0.400723 +vt 0.468719 0.61852 +vt 0.473369 0.731436 +vt 0.482083 0.336875 +vt 0.484377 0.672879 +vt 0.484433 0.450115 +vt 0.484916 0.55954 +vt 0.486738 0.848966 +vt 0.487136 0.277187 +vt 0.495108 0.217953 +vt 0.499273 0.388445 +vt 0.5 0.5 +vt 0.500727 0.611555 +vt 0.504893 0.782047 +vt 0.512864 0.722813 +vt 0.513262 0.151034 +vt 0.515084 0.44046 +vt 0.515567 0.549885 +vt 0.515623 0.327121 +vt 0.517917 0.663125 +vt 0.526631 0.268564 +vt 0.531281 0.38148 +vt 0.531927 0.599277 +vt 0.533333 0.5 +vt 0.55 0.207652 +vt 0.55 0.550304 +vt 0.55 0.647584 +vt 0.55 0.941264 +vt 0.55 0.0972793 +vt 0.55 0.439931 +vt 0.55 0.706319 +vt 0.55 0.765056 +vt 0.55 0.323792 +vt 0.55 0.823792 +vt 0.55 0 +vt 0.55 0.882528 +vt 0.566667 0.5 +vt 0.568073 0.599277 +vt 0.568719 0.38148 +vt 0.573369 0.268564 +vt 0.582083 0.663125 +vt 0.584377 0.327121 +vt 0.584433 0.549885 +vt 0.584916 0.44046 +vt 0.586738 0.151034 +vt 0.587136 0.722813 +vt 0.595108 0.782047 +vt 0.599273 0.611555 +vt 0.6 0.5 +vt 0.600727 0.388445 +vt 0.604892 0.217953 +vt 0.612864 0.277187 +vt 0.613262 0.848966 +vt 0.615084 0.55954 +vt 0.615567 0.450115 +vt 0.615623 0.672879 +vt 0.617917 0.336875 +vt 0.626631 0.731436 +vt 0.631281 0.61852 +vt 0.631927 0.400723 +vt 0.633333 0.5 +vt 0.65 0.117472 +vt 0.65 0.176208 +vt 0.65 0.29368 +vt 0.65 0.792348 +vt 0.65 0.560069 +vt 0.65 0.676208 +vt 0.65 1 +vt 0.65 0.234944 +vt 0.65 0.352416 +vt 0.65 0.449696 +vt 0.65 0.902721 +vt 0.65 0.058736 +vt 0.666667 0.5 +vt 0.668073 0.400723 +vt 0.668719 0.61852 +vt 0.673369 0.731436 +vt 0.682083 0.336875 +vt 0.684377 0.672879 +vt 0.684433 0.450115 +vt 0.684916 0.55954 +vt 0.686738 0.848966 +vt 0.687136 0.277187 +vt 0.695108 0.217953 +vt 0.699273 0.388445 +vt 0.7 0.5 +vt 0.700727 0.611555 +vt 0.704892 0.782047 +vt 0.712864 0.722813 +vt 0.713262 0.151034 +vt 0.715084 0.44046 +vt 0.715567 0.549885 +vt 0.715623 0.327121 +vt 0.717917 0.663125 +vt 0.726632 0.268564 +vt 0.731281 0.38148 +vt 0.731927 0.599277 +vt 0.733333 0.5 +vt 0.75 0 +vt 0.75 0.0972794 +vt 0.75 0.207652 +vt 0.75 0.323792 +vt 0.75 0.439931 +vt 0.75 0.550304 +vt 0.75 0.647584 +vt 0.75 0.706319 +vt 0.75 0.765056 +vt 0.75 0.823792 +vt 0.75 0.882528 +vt 0.75 0.941264 +vt 0.766667 0.5 +vt 0.768073 0.599277 +vt 0.768719 0.38148 +vt 0.773368 0.268564 +vt 0.782083 0.663125 +vt 0.784377 0.327121 +vt 0.784433 0.549885 +vt 0.784917 0.44046 +vt 0.786738 0.151034 +vt 0.787136 0.722813 +vt 0.795108 0.782047 +vt 0.799273 0.611555 +vt 0.8 0.5 +vt 0.800727 0.388445 +vt 0.804893 0.217953 +vt 0.812864 0.277187 +vt 0.813262 0.848966 +vt 0.815084 0.55954 +vt 0.815568 0.450115 +vt 0.815623 0.672879 +vt 0.817917 0.336875 +vt 0.826631 0.731436 +vt 0.831281 0.61852 +vt 0.831927 0.400723 +vt 0.833333 0.5 +vt 0.85 0.058736 +vt 0.85 0.902721 +vt 0.85 0.352416 +vt 0.85 0.560069 +vt 0.85 0.676208 +vt 0.85 1 +vt 0.85 0.176208 +vt 0.85 0.29368 +vt 0.85 0.449696 +vt 0.85 0.792348 +vt 0.85 0.234944 +vt 0.85 0.117472 +vt 0.866667 0.5 +vt 0.868073 0.400723 +vt 0.868719 0.61852 +vt 0.873369 0.731436 +vt 0.882083 0.336875 +vt 0.884377 0.672879 +vt 0.884433 0.450115 +vt 0.884916 0.55954 +vt 0.886738 0.848966 +vt 0.887136 0.277187 +vt 0.895108 0.217953 +vt 0.899273 0.388445 +vt 0.9 0.5 +vt 0.900727 0.611555 +vt 0.904892 0.782047 +vt 0.912864 0.722813 +vt 0.913262 0.151034 +vt 0.915084 0.44046 +vt 0.915568 0.549885 +vt 0.915623 0.327121 +vt 0.917917 0.663125 +vt 0.926631 0.268564 +vt 0.931281 0.38148 +vt 0.931927 0.599277 +vt 0.933333 0.5 +vt 0.95 0 +vt 0.95 0.882528 +vt 0.95 0.823792 +vt 0.95 0.439931 +vt 0.95 0.706319 +vt 0.95 0.765056 +vt 0.95 0.0972793 +vt 0.95 0.550304 +vt 0.95 0.647584 +vt 0.95 0.941264 +vt 0.95 0.207652 +vt 0.95 0.323792 +vt 0.966667 0.5 +vt 0.968073 0.599277 +vt 0.968719 0.38148 +vt 0.973369 0.268564 +vt 0.982083 0.663125 +vt 0.984377 0.327121 +vt 0.984433 0.549885 +vt 0.984916 0.44046 +vt 0.986738 0.151034 +vt 0.987136 0.722813 +vt 0.995108 0.782047 +vt 0.999273 0.611555 +vt 1 0.5 +vt 1.00073 0.388445 +vt 1.00489 0.217953 +vt 1.01286 0.277187 +vt 1.01326 0.848966 +vt 1.01508 0.55954 +vt 1.01562 0.672879 +vt 1.05 0.0587359 +vt 1.05 0.902721 +vn -1 1.00021e-008 4.62596e-008 +vn -0.981591 -0.162468 0.100411 +vn -0.981591 0.162468 -0.100411 +vn -0.978376 -0.180943 -0.100195 +vn -0.978376 0.180943 0.100195 +vn -0.978376 -0.00869708 -0.206649 +vn -0.978376 0.0086971 0.20665 +vn -0.939218 -0.157292 0.30517 +vn -0.939218 -0.343297 0.00421013 +vn -0.939218 0.343297 -0.0042102 +vn -0.939218 0.157293 -0.305171 +vn -0.934172 0.187592 0.303531 +vn -0.934172 -0.187593 -0.303531 +vn -0.929022 -0.314761 0.194533 +vn -0.929022 0.314761 -0.194533 +vn -0.912988 0.360941 0.190194 +vn -0.912988 0.00869702 0.407893 +vn -0.912988 -0.360942 -0.190194 +vn -0.912988 -0.00869627 -0.407893 +vn -0.865939 0.31476 -0.388685 +vn -0.865939 -0.31476 0.388684 +vn -0.865939 -0.488415 0.107705 +vn -0.865939 0.488415 -0.107705 +vn -0.853145 0.162466 -0.49573 +vn -0.853145 -0.516052 -0.0763834 +vn -0.853144 -0.162466 0.495732 +vn -0.853144 0.516053 0.0763836 +vn -0.850652 0.447212 -0.276392 +vn -0.850652 -0.447213 0.276392 +vn -0.850417 -0.180942 -0.494015 +vn -0.850417 -0.360941 -0.382769 +vn -0.850416 0.180942 0.494016 +vn -0.850416 0.360941 0.382772 +vn -0.809018 -0.52573 -0.262865 +vn -0.809017 2.413e-007 -0.587785 +vn -0.809017 0.525732 0.262865 +vn -0.809017 -4.85101e-007 0.587786 +vn -0.763866 0.488416 -0.421851 +vn -0.763866 -0.488417 0.421851 +vn -0.763865 0.595742 -0.248195 +vn -0.763865 -0.595742 0.248195 +vn -0.762317 0.343296 -0.548653 +vn -0.762317 -0.644257 0.0616893 +vn -0.762317 0.644257 -0.0616879 +vn -0.762316 -0.343296 0.548655 +vn -0.757369 -0.343296 -0.555464 +vn -0.757368 0.343296 0.555465 +vn -0.735105 -0.516054 -0.439669 +vn -0.735104 -0.162466 -0.658199 +vn -0.735104 0.162467 0.6582 +vn -0.735104 0.516054 0.439671 +vn -0.73263 -0.667785 -0.131592 +vn -0.73263 0.180943 -0.656135 +vn -0.73263 -0.180942 0.656135 +vn -0.73263 0.667785 0.131592 +vn -0.670058 -0.00869553 0.742258 +vn -0.670058 0.00869665 -0.742258 +vn -0.670057 0.667785 0.324169 +vn -0.670057 -0.667786 -0.324169 +vn -0.652987 -0.644257 0.398171 +vn -0.652987 0.644257 -0.398172 +vn -0.645311 -0.734582 0.209674 +vn -0.645311 0.734582 -0.209674 +vn -0.645311 -0.516052 0.563262 +vn -0.64531 0.516053 -0.563262 +vn -0.637252 0.488417 0.59612 +vn -0.637252 0.31476 0.703446 +vn -0.637251 -0.488416 -0.596121 +vn -0.637251 -0.31476 -0.703447 +vn -0.62683 -0.360942 0.690511 +vn -0.62683 0.77903 -0.0140296 +vn -0.626829 -0.779031 0.0140304 +vn -0.626829 0.360942 -0.690512 +vn -0.580469 -0.157292 -0.798946 +vn -0.580468 0.157292 0.798947 +vn -0.580468 -0.644257 -0.497986 +vn -0.580467 0.644257 0.497987 +vn -0.57735 -0.187593 0.794654 +vn -0.57735 0.794655 0.187592 +vn -0.57735 0.187593 -0.794655 +vn -0.577349 -0.794656 -0.187593 +vn -0.525731 -0.447214 -0.723607 +vn -0.525731 0.447214 0.723607 +vn -0.515363 0.667784 -0.537089 +vn -0.515363 0.77903 -0.35709 +vn -0.515363 -0.667785 0.537089 +vn -0.515362 -0.77903 0.35709 +vn -0.500001 0.52573 -0.688191 +vn -0.5 -0.525729 0.688192 +vn -0.5 0.850651 -0.16246 +vn -0.5 -0.850651 0.16246 +vn -0.49887 -0.00869475 0.866633 +vn -0.49887 0.00869757 -0.866633 +vn -0.498869 -0.77903 -0.379791 +vn -0.498869 0.77903 0.379793 +vn -0.472095 -0.31476 -0.823439 +vn -0.472095 -0.595742 -0.649783 +vn -0.472095 0.314759 0.82344 +vn -0.472095 0.595743 0.649782 +vn -0.463014 0.360941 -0.80953 +vn -0.463014 -0.885484 -0.0391978 +vn -0.463014 0.885484 0.0391977 +vn -0.463013 -0.360942 0.80953 +vn -0.398825 -0.734582 -0.548934 +vn -0.398824 0.162469 0.90252 +vn -0.398824 0.734581 0.548935 +vn -0.398824 -0.162467 -0.902521 +vn -0.397626 -0.885484 -0.240441 +vn -0.397626 0.180943 -0.89953 +vn -0.397625 0.885484 0.240441 +vn -0.397625 -0.180944 0.89953 +vn -0.370023 -0.488416 -0.790274 +vn -0.370022 0.488416 0.790274 +vn -0.356821 0.794655 -0.491122 +vn -0.356821 -0.794656 0.491122 +vn -0.351546 0.667784 -0.656109 +vn -0.351546 -0.885484 0.303865 +vn -0.351546 0.885484 -0.303863 +vn -0.351546 -0.667785 0.656109 +vn -0.336281 -0.935402 0.109265 +vn -0.336281 -0.516052 0.787785 +vn -0.336281 0.516052 -0.787785 +vn -0.336281 0.935402 -0.109265 +vn -0.309017 -0.850651 -0.425325 +vn -0.309017 6.87643e-008 -0.951056 +vn -0.309017 4.8135e-007 0.951057 +vn -0.309017 0.850651 0.425326 +vn -0.29424 -0.644257 -0.705943 +vn -0.294239 0.644258 0.705943 +vn -0.294238 -0.343295 -0.891948 +vn -0.294238 0.343295 0.891949 +vn -0.286232 -0.953636 -0.0930024 +vn -0.286232 0.953636 0.0930024 +vn -0.286231 0.343296 -0.89455 +vn -0.286231 -0.343296 0.89455 +vn -0.207833 -0.935402 -0.286058 +vn -0.207833 0.935402 0.286058 +vn -0.207833 0.162468 -0.964577 +vn -0.207832 -0.162469 0.964577 +vn -0.207046 -0.77903 -0.591814 +vn -0.207046 -0.180943 -0.961453 +vn -0.207045 0.77903 0.591814 +vn -0.207045 0.180944 0.961453 +vn -0.190993 0.516052 0.834992 +vn -0.190992 -0.516052 -0.834992 +vn -0.180359 -0.885484 0.42824 +vn -0.180358 -0.779031 0.600485 +vn -0.180358 0.885484 -0.428239 +vn -0.180357 0.77903 -0.600486 +vn -0.176901 0.953636 -0.243484 +vn -0.176901 -0.953636 0.243484 +vn -0.1769 0.644256 -0.74407 +vn -0.1769 -0.644256 0.74407 +vn -0.165158 -0.984806 0.0536629 +vn -0.165158 0.984806 -0.0536629 +vn -0.165157 0.488415 -0.856839 +vn -0.165157 -0.488415 0.856839 +vn -0.105801 -0.00869593 -0.994349 +vn -0.105801 -0.885484 -0.452464 +vn -0.1058 0.885484 0.452465 +vn -0.1058 0.0086958 0.994349 +vn -0.102073 -0.984806 -0.140492 +vn -0.102073 0.984806 0.140492 +vn -0.102072 -0.31476 0.943667 +vn -0.102071 0.31476 -0.943667 +vn -0.101246 0.360941 0.927077 +vn -0.101246 -0.667784 -0.737437 +vn -0.101245 0.667785 0.737436 +vn -0.101245 -0.360941 -0.927077 +vn -1.38907e-007 0.187592 0.982247 +vn -1.37495e-007 -0.157294 0.987552 +vn -2.50052e-008 -0.52573 -0.850651 +vn -1.24996e-008 -0.953636 -0.300962 +vn -8.74969e-009 0.157294 -0.987552 +vn -1.25026e-009 0.850651 -0.52573 +vn -1.24987e-009 0.984806 -0.173657 +vn -1.24987e-009 0.595741 -0.803177 +vn -1.24987e-009 0.734582 -0.67852 +vn -1.24986e-009 0.935402 -0.353587 +vn 0 -1 1.49983e-008 +vn 0 0.447212 -0.894428 +vn 0 1 -1.34985e-008 +vn 3.74961e-009 -0.984806 0.173657 +vn 1.24987e-008 -0.935402 0.353587 +vn 1.24996e-008 0.953636 0.300962 +vn 2.00227e-008 0.794656 0.60706 +vn 2.12544e-008 -0.850651 0.52573 +vn 2.7497e-008 -0.734582 0.67852 +vn 2.8756e-008 0.52573 0.850651 +vn 3.37465e-008 -0.595741 0.803177 +vn 3.89956e-008 -0.447212 0.894428 +vn 1.45164e-007 -0.187592 -0.982247 +vn 1.45164e-007 -0.794656 -0.60706 +vn 0.101245 0.667785 0.737436 +vn 0.101245 0.360941 0.927077 +vn 0.101246 -0.360941 -0.927077 +vn 0.101246 -0.667784 -0.737437 +vn 0.102071 0.31476 -0.943667 +vn 0.102072 -0.31476 0.943667 +vn 0.102073 -0.984806 -0.140492 +vn 0.102073 0.984806 0.140492 +vn 0.1058 -0.00869608 -0.994349 +vn 0.1058 0.885484 0.452465 +vn 0.105801 -0.885484 -0.452464 +vn 0.105801 0.00869592 0.994349 +vn 0.165157 0.488415 -0.856839 +vn 0.165157 -0.488415 0.856839 +vn 0.165158 0.984806 -0.0536629 +vn 0.165158 -0.984806 0.0536629 +vn 0.1769 -0.644256 0.74407 +vn 0.1769 0.644256 -0.74407 +vn 0.176901 -0.953636 0.243484 +vn 0.176901 0.953636 -0.243484 +vn 0.180358 -0.779031 0.600485 +vn 0.180358 0.779031 -0.600485 +vn 0.180359 0.885484 -0.42824 +vn 0.180359 -0.885484 0.42824 +vn 0.190992 0.516052 0.834992 +vn 0.190993 -0.516052 -0.834992 +vn 0.207045 -0.180944 -0.961453 +vn 0.207045 0.77903 0.591814 +vn 0.207046 0.180943 0.961453 +vn 0.207047 -0.77903 -0.591814 +vn 0.207832 0.162469 -0.964577 +vn 0.207833 -0.162468 0.964577 +vn 0.207833 -0.935402 -0.286058 +vn 0.207833 0.935402 0.286058 +vn 0.286231 -0.343296 0.89455 +vn 0.286231 0.343296 -0.89455 +vn 0.286232 -0.953636 -0.0930024 +vn 0.286232 0.953636 0.0930024 +vn 0.294238 -0.343295 -0.891949 +vn 0.294238 0.343295 0.891948 +vn 0.294239 -0.644258 -0.705943 +vn 0.29424 0.644258 0.705943 +vn 0.309017 -8.52678e-007 -0.951057 +vn 0.309017 -6.87643e-008 0.951056 +vn 0.309017 -0.850651 -0.425326 +vn 0.309017 0.850651 0.425326 +vn 0.336281 -0.935402 0.109265 +vn 0.336281 -0.516052 0.787785 +vn 0.336281 0.516052 -0.787785 +vn 0.336281 0.935402 -0.109265 +vn 0.351546 0.667785 -0.656109 +vn 0.351546 -0.885484 0.303865 +vn 0.351546 0.885484 -0.303865 +vn 0.351546 -0.667785 0.656108 +vn 0.356821 0.794656 -0.491122 +vn 0.356822 -0.794655 0.491122 +vn 0.370022 -0.488416 -0.790274 +vn 0.370023 0.488416 0.790274 +vn 0.397626 -0.180943 0.89953 +vn 0.397626 -0.885484 -0.240442 +vn 0.397626 0.885484 0.240442 +vn 0.397626 0.180944 -0.899529 +vn 0.398824 0.162467 0.902521 +vn 0.398824 -0.162469 -0.90252 +vn 0.398824 -0.734582 -0.548934 +vn 0.398825 0.734582 0.548934 +vn 0.463014 -0.885484 -0.0391978 +vn 0.463014 0.885484 0.0391978 +vn 0.463014 -0.360941 0.80953 +vn 0.463014 0.360941 -0.80953 +vn 0.472095 -0.595743 -0.649782 +vn 0.472095 -0.314759 -0.82344 +vn 0.472095 0.595743 0.649782 +vn 0.472095 0.31476 0.823439 +vn 0.498869 -0.77903 -0.379792 +vn 0.498869 0.77903 0.379792 +vn 0.49887 -0.00869757 0.866633 +vn 0.498871 0.00869589 -0.866633 +vn 0.5 -0.850651 0.16246 +vn 0.5 0.850651 -0.16246 +vn 0.5 0.525729 -0.688192 +vn 0.500001 -0.52573 0.688191 +vn 0.515362 -0.77903 0.357091 +vn 0.515362 0.77903 -0.35709 +vn 0.515363 -0.667785 0.537089 +vn 0.515363 0.667785 -0.537089 +vn 0.525731 -0.447214 -0.723607 +vn 0.525731 0.447214 0.723607 +vn 0.577349 0.794656 0.187593 +vn 0.57735 -0.794655 -0.187592 +vn 0.57735 -0.187593 0.794655 +vn 0.57735 0.187593 -0.794655 +vn 0.580467 -0.644258 -0.497986 +vn 0.580467 0.644258 0.497986 +vn 0.580468 -0.157292 -0.798947 +vn 0.580469 0.157292 0.798946 +vn 0.626829 -0.360942 0.690512 +vn 0.626829 0.360942 -0.690512 +vn 0.626829 0.779031 -0.0140304 +vn 0.62683 -0.77903 0.0140295 +vn 0.637251 0.488417 0.596121 +vn 0.637251 0.31476 0.703447 +vn 0.637252 -0.488417 -0.59612 +vn 0.637252 -0.31476 -0.703446 +vn 0.64531 -0.516053 0.563262 +vn 0.645311 0.516052 -0.563262 +vn 0.645311 -0.734582 0.209674 +vn 0.645311 0.734582 -0.209674 +vn 0.652987 -0.644257 0.398172 +vn 0.652987 0.644257 -0.398171 +vn 0.670057 -0.667786 -0.324169 +vn 0.670057 0.667785 0.32417 +vn 0.670057 0.00869565 -0.742258 +vn 0.670058 -0.00869665 0.742258 +vn 0.732629 0.180942 -0.656136 +vn 0.732629 -0.667786 -0.131592 +vn 0.73263 0.667785 0.131592 +vn 0.73263 -0.180943 0.656135 +vn 0.735104 -0.162467 -0.6582 +vn 0.735104 -0.516053 -0.439671 +vn 0.735104 0.516054 0.43967 +vn 0.735104 0.162466 0.658199 +vn 0.757369 -0.343296 -0.555465 +vn 0.757369 0.343296 0.555464 +vn 0.762317 -0.644257 0.0616879 +vn 0.762317 0.343297 -0.548653 +vn 0.762317 0.644257 -0.0616893 +vn 0.762317 -0.343296 0.548653 +vn 0.763865 -0.595742 0.248195 +vn 0.763865 0.595742 -0.248195 +vn 0.763866 -0.488416 0.421851 +vn 0.763866 0.488416 -0.421851 +vn 0.809017 -5.86372e-007 -0.587785 +vn 0.809017 -0.525731 -0.262865 +vn 0.809017 -2.413e-007 0.587785 +vn 0.809018 0.52573 0.262865 +vn 0.850416 -0.180943 -0.494016 +vn 0.850416 -0.360941 -0.382771 +vn 0.850417 0.180942 0.494015 +vn 0.850417 0.360942 0.382769 +vn 0.850652 -0.447212 0.276392 +vn 0.850652 0.447212 -0.276393 +vn 0.853144 -0.516053 -0.0763836 +vn 0.853145 0.516052 0.0763834 +vn 0.853145 0.162466 -0.495731 +vn 0.853145 -0.162466 0.49573 +vn 0.865939 -0.488415 0.107705 +vn 0.865939 0.488415 -0.107705 +vn 0.865939 -0.31476 0.388685 +vn 0.865939 0.31476 -0.388684 +vn 0.912988 0.360942 0.190194 +vn 0.912988 0.00869627 0.407893 +vn 0.912988 -0.360941 -0.190194 +vn 0.912988 -0.00869702 -0.407893 +vn 0.929022 -0.314761 0.194533 +vn 0.929022 0.314761 -0.194533 +vn 0.934172 -0.187593 -0.303531 +vn 0.934172 0.187593 0.303531 +vn 0.939218 -0.157293 0.305171 +vn 0.939218 -0.343297 0.00421008 +vn 0.939218 0.343297 -0.0042101 +vn 0.939218 0.157293 -0.305171 +vn 0.978376 -0.0086971 -0.20665 +vn 0.978376 0.00869708 0.20665 +vn 0.978376 -0.180943 -0.100195 +vn 0.978376 0.180943 0.100195 +vn 0.981591 -0.162468 0.100411 +vn 0.981591 0.162468 -0.100411 +vn 1 -8.75182e-009 -1.62534e-008 +#usemtl Default_Smoothing +s 1 +f 181/292/176 182/250/182 209/210/208 +f 213/254/213 209/210/208 243/218/243 +f 181/292/176 213/254/213 180/291/179 +f 181/292/176 209/210/208 213/254/213 +f 247/235/246 243/218/243 275/216/273 +f 217/264/216 213/254/213 247/235/246 +f 180/291/179 217/264/216 179/290/175 +f 213/254/213 243/218/243 247/235/246 +f 180/291/179 213/254/213 217/264/216 +f 279/229/277 275/216/273 297/214/301 +f 249/247/248 247/235/246 279/229/277 +f 217/264/216 249/247/248 216/270/215 +f 179/290/175 216/270/215 178/289/178 +f 247/235/246 275/216/273 279/229/277 +f 217/264/216 247/235/246 249/247/248 +f 179/290/175 217/264/216 216/270/215 +f 303/228/303 297/214/301 321/213/323 +f 278/240/279 279/229/277 303/228/303 +f 246/259/244 249/247/248 278/240/279 +f 216/270/215 246/259/244 212/271/211 +f 178/289/178 212/271/211 177/288/177 +f 279/229/277 297/214/301 303/228/303 +f 249/247/248 279/229/277 278/240/279 +f 216/270/215 249/247/248 246/259/244 +f 178/289/178 216/270/215 212/271/211 +f 320/223/325 321/213/323 335/209/335 +f 296/238/299 303/228/303 320/223/325 +f 274/249/274 278/240/279 296/238/299 +f 246/259/244 274/249/274 242/261/242 +f 212/271/211 242/261/242 208/276/206 +f 177/288/177 208/276/206 176/287/181 +f 303/228/303 321/213/323 320/223/325 +f 278/240/279 303/228/303 296/238/299 +f 246/259/244 278/240/279 274/249/274 +f 212/271/211 246/259/244 242/261/242 +f 177/288/177 212/271/211 208/276/206 +f 209/210/208 182/171/182 201/133/201 +f 231/175/231 201/133/201 223/144/227 +f 209/210/208 231/175/231 243/218/243 +f 209/210/208 201/133/201 231/175/231 +f 255/161/254 223/144/227 239/142/239 +f 263/190/261 231/175/231 255/161/254 +f 243/218/243 263/190/261 275/216/273 +f 231/175/231 223/144/227 255/161/254 +f 243/218/243 231/175/231 263/190/261 +f 271/155/269 239/142/239 258/136/259 +f 285/181/282 255/161/254 271/155/269 +f 263/190/261 285/181/282 293/196/292 +f 275/216/273 293/196/292 297/214/301 +f 255/161/254 239/142/239 271/155/269 +f 263/190/261 255/161/254 285/181/282 +f 275/216/273 263/190/261 293/196/292 +f 288/154/287 258/136/259 267/141/266 +f 307/166/305 271/155/269 288/154/287 +f 311/185/310 285/181/282 307/166/305 +f 293/196/292 311/185/310 325/197/320 +f 297/214/301 325/197/320 321/213/323 +f 271/155/269 258/136/259 288/154/287 +f 285/181/282 271/155/269 307/166/305 +f 293/196/292 285/181/282 311/185/310 +f 297/214/301 293/196/292 325/197/320 +f 301/149/294 267/141/266 281/135/281 +f 315/164/314 288/154/287 301/149/294 +f 329/180/329 307/166/305 315/164/314 +f 311/185/310 329/180/329 339/187/337 +f 325/197/320 339/187/337 343/202/341 +f 321/213/323 343/202/341 335/209/335 +f 288/154/287 267/141/266 301/149/294 +f 307/166/305 288/154/287 315/164/314 +f 311/185/310 307/166/305 329/180/329 +f 325/197/320 311/185/310 339/187/337 +f 321/213/323 325/197/320 343/202/341 +f 201/133/201 182/107/182 165/70/163 +f 184/106/185 165/70/163 142/59/137 +f 201/133/201 184/106/185 223/144/227 +f 201/133/201 165/70/163 184/106/185 +f 169/87/160 142/59/137 127/61/127 +f 197/116/203 184/106/185 169/87/160 +f 223/144/227 197/116/203 239/142/239 +f 184/106/185 142/59/137 169/87/160 +f 223/144/227 184/106/185 197/116/203 +f 139/81/142 127/61/127 107/65/106 +f 187/105/186 169/87/160 139/81/142 +f 197/116/203 187/105/186 226/122/221 +f 239/142/239 226/122/221 258/136/259 +f 169/87/160 127/61/127 139/81/142 +f 197/116/203 169/87/160 187/105/186 +f 239/142/239 197/116/203 226/122/221 +f 131/80/129 107/65/106 99/60/99 +f 161/92/168 139/81/142 131/80/129 +f 205/111/194 187/105/186 161/92/168 +f 226/122/221 205/111/194 235/123/235 +f 258/136/259 235/123/235 267/141/266 +f 139/81/142 107/65/106 131/80/129 +f 187/105/186 139/81/142 161/92/168 +f 226/122/221 187/105/186 205/111/194 +f 258/136/259 226/122/221 235/123/235 +f 113/75/113 99/60/99 83/67/83 +f 145/90/144 131/80/129 113/75/113 +f 190/104/189 161/92/168 145/90/144 +f 205/111/194 190/104/189 219/113/218 +f 235/123/235 219/113/218 251/128/251 +f 267/141/266 251/128/251 281/135/281 +f 131/80/129 99/60/99 113/75/113 +f 161/92/168 131/80/129 145/90/144 +f 205/111/194 161/92/168 190/104/189 +f 235/123/235 205/111/194 219/113/218 +f 267/141/266 235/123/235 251/128/251 +f 182/32/182 157/2/155 165/70/163 +f 135/387/133 157/364/155 123/356/123 +f 165/70/163 135/27/133 142/59/137 +f 165/70/163 157/2/155 135/27/133 +f 103/383/102 123/356/123 91/357/90 +f 135/27/133 103/13/102 111/42/110 +f 142/59/137 111/42/110 127/61/127 +f 135/387/133 123/356/123 103/383/102 +f 142/59/137 135/27/133 111/42/110 +f 73/377/71 91/357/90 69/360/63 +f 81/31/79 103/13/102 73/7/71 +f 111/42/110 81/31/79 95/48/95 +f 127/61/127 95/48/95 107/65/106 +f 103/383/102 91/357/90 73/377/71 +f 111/42/110 103/13/102 81/31/79 +f 127/61/127 111/42/110 95/48/95 +f 41/376/44 69/360/63 45/359/40 +f 55/18/55 73/7/71 41/6/44 +f 81/31/79 55/18/55 59/37/58 +f 95/48/95 59/37/58 77/49/77 +f 107/65/106 77/49/77 99/60/99 +f 73/377/71 69/360/63 41/376/44 +f 81/31/79 73/7/71 55/18/55 +f 95/48/95 81/31/79 59/37/58 +f 107/65/106 95/48/95 77/49/77 +f 23/371/23 45/359/40 29/363/28 +f 27/385/27 41/376/44 23/371/23 +f 37/30/36 55/18/55 27/16/27 +f 59/37/58 37/30/36 51/39/51 +f 77/49/77 51/39/51 65/54/66 +f 99/60/99 65/54/66 83/67/83 +f 41/376/44 45/359/40 23/371/23 +f 55/18/55 41/6/44 27/16/27 +f 59/37/58 55/18/55 37/30/36 +f 77/49/77 59/37/58 51/39/51 +f 99/60/99 77/49/77 65/54/66 +f 182/323/182 181/292/176 157/364/155 +f 153/319/150 181/292/176 180/291/179 +f 157/364/155 153/319/150 123/356/123 +f 157/364/155 181/292/176 153/319/150 +f 149/309/148 180/291/179 179/290/175 +f 153/319/150 149/309/148 119/338/118 +f 123/356/123 119/338/118 91/357/90 +f 153/319/150 180/291/179 149/309/148 +f 123/356/123 153/319/150 119/338/118 +f 148/303/149 179/290/175 178/289/178 +f 115/327/114 149/309/148 148/303/149 +f 119/338/118 115/327/114 87/344/85 +f 91/357/90 87/344/85 69/360/63 +f 149/309/148 179/290/175 148/303/149 +f 119/338/118 149/309/148 115/327/114 +f 91/357/90 119/338/118 87/344/85 +f 152/302/152 178/289/178 177/288/177 +f 118/314/116 148/303/149 152/302/152 +f 115/327/114 118/314/116 86/333/84 +f 87/344/85 86/333/84 61/345/61 +f 69/360/63 61/345/61 45/359/40 +f 148/303/149 178/289/178 152/302/152 +f 115/327/114 148/303/149 118/314/116 +f 87/344/85 115/327/114 86/333/84 +f 69/360/63 87/344/85 61/345/61 +f 156/297/156 177/288/177 176/287/181 +f 122/312/122 152/302/152 156/297/156 +f 90/322/88 118/314/116 122/312/122 +f 86/333/84 90/322/88 68/335/65 +f 61/345/61 68/335/65 44/350/38 +f 45/359/40 44/350/38 29/363/28 +f 152/302/152 177/288/177 156/297/156 +f 118/314/116 152/302/152 122/312/122 +f 86/333/84 118/314/116 90/322/88 +f 61/345/61 86/333/84 68/335/65 +f 45/359/40 61/345/61 44/350/38 +f 198/255/200 206/178/209 175/217/180 +f 220/244/226 228/211/230 198/255/200 +f 228/211/230 240/170/240 206/178/209 +f 198/255/200 228/211/230 206/178/209 +f 236/245/238 252/227/253 220/244/226 +f 252/227/253 260/198/260 228/211/230 +f 260/198/260 272/172/272 240/170/240 +f 220/244/226 252/227/253 228/211/230 +f 260/198/260 240/170/240 228/211/230 +f 256/251/258 268/233/268 236/245/238 +f 268/233/268 282/207/283 252/227/253 +f 282/207/283 290/192/293 260/198/260 +f 290/192/293 294/176/300 272/172/272 +f 236/245/238 268/233/268 252/227/253 +f 252/227/253 282/207/283 260/198/260 +f 290/192/293 272/172/272 260/198/260 +f 264/246/264 286/234/286 256/251/258 +f 286/234/286 304/222/304 268/233/268 +f 304/222/304 308/203/309 282/207/283 +f 308/203/309 322/191/318 290/192/293 +f 322/191/318 318/173/322 294/176/300 +f 256/251/258 286/234/286 268/233/268 +f 268/233/268 304/222/304 282/207/283 +f 308/203/309 290/192/293 282/207/283 +f 322/191/318 294/176/300 290/192/293 +f 280/252/280 298/239/296 264/246/264 +f 298/239/296 312/224/313 286/234/286 +f 312/224/313 326/215/327 304/222/304 +f 326/215/327 336/201/336 308/203/309 +f 336/201/336 340/186/340 322/191/318 +f 340/186/340 334/179/334 318/173/322 +f 264/246/264 298/239/296 286/234/286 +f 286/234/286 312/224/313 304/222/304 +f 304/222/304 326/215/327 308/203/309 +f 336/201/336 322/191/318 308/203/309 +f 340/186/340 318/173/322 322/191/318 +f 206/178/209 183/96/183 175/138/180 +f 240/170/240 210/134/212 206/178/209 +f 210/134/212 185/97/184 183/96/183 +f 206/178/209 210/134/212 183/96/183 +f 272/172/272 244/153/245 240/170/240 +f 244/153/245 214/124/217 210/134/212 +f 214/124/217 186/98/187 185/97/184 +f 240/170/240 244/153/245 210/134/212 +f 214/124/217 185/97/184 210/134/212 +f 294/176/300 276/159/276 272/172/272 +f 276/159/276 248/140/249 244/153/245 +f 248/140/249 215/118/214 214/124/217 +f 215/118/214 188/99/188 186/98/187 +f 272/172/272 276/159/276 244/153/245 +f 244/153/245 248/140/249 214/124/217 +f 215/118/214 186/98/187 214/124/217 +f 318/173/322 302/160/302 294/176/300 +f 302/160/302 277/148/278 276/159/276 +f 277/148/278 245/129/247 248/140/249 +f 245/129/247 211/117/210 215/118/214 +f 211/117/210 189/100/190 188/99/188 +f 294/176/300 302/160/302 276/159/276 +f 276/159/276 277/148/278 248/140/249 +f 245/129/247 215/118/214 248/140/249 +f 211/117/210 188/99/188 215/118/214 +f 334/179/334 319/165/324 318/173/322 +f 319/165/324 295/150/298 302/160/302 +f 295/150/298 273/137/275 277/148/278 +f 273/137/275 241/127/241 245/129/247 +f 241/127/241 207/112/207 211/117/210 +f 207/112/207 191/101/191 189/100/190 +f 318/173/322 319/165/324 302/160/302 +f 302/160/302 295/150/298 277/148/278 +f 277/148/278 273/137/275 245/129/247 +f 241/127/241 211/117/210 245/129/247 +f 207/112/207 189/100/190 211/117/210 +f 183/96/183 154/22/154 175/63/180 +f 185/97/184 150/69/151 183/96/183 +f 150/69/151 120/33/120 154/22/154 +f 150/69/151 154/22/154 183/96/183 +f 186/98/187 146/79/146 185/97/184 +f 146/79/146 116/50/117 150/69/151 +f 116/50/117 88/29/91 120/33/120 +f 185/97/184 146/79/146 150/69/151 +f 116/50/117 120/33/120 150/69/151 +f 188/99/188 147/85/147 186/98/187 +f 147/85/147 114/62/115 146/79/146 +f 114/62/115 84/44/87 116/50/117 +f 84/44/87 66/25/62 88/29/91 +f 186/98/187 147/85/147 146/79/146 +f 114/62/115 116/50/117 146/79/146 +f 84/44/87 88/29/91 116/50/117 +f 189/100/190 151/86/153 188/99/188 +f 151/86/153 117/74/119 147/85/147 +f 117/74/119 85/55/86 114/62/115 +f 85/55/86 60/43/60 84/44/87 +f 60/43/60 42/26/41 66/25/62 +f 188/99/188 151/86/153 147/85/147 +f 147/85/147 117/74/119 114/62/115 +f 85/55/86 84/44/87 114/62/115 +f 60/43/60 66/25/62 84/44/87 +f 191/101/191 155/91/157 189/100/190 +f 155/91/157 121/76/121 151/86/153 +f 121/76/121 89/64/89 117/74/119 +f 89/64/89 67/53/64 85/55/86 +f 67/53/64 43/38/39 60/43/60 +f 43/38/39 28/23/29 42/26/41 +f 189/100/190 155/91/157 151/86/153 +f 151/86/153 121/76/121 117/74/119 +f 89/64/89 85/55/86 117/74/119 +f 67/53/64 60/43/60 85/55/86 +f 43/38/39 42/26/41 60/43/60 +f 154/386/154 162/318/162 175/355/180 +f 120/33/120 132/1/132 154/22/154 +f 132/361/132 140/329/136 162/318/162 +f 132/361/132 162/318/162 154/386/154 +f 88/29/91 100/5/101 120/33/120 +f 100/375/101 108/346/108 132/361/132 +f 108/346/108 124/324/124 140/329/136 +f 120/33/120 100/5/101 132/1/132 +f 108/346/108 140/329/136 132/361/132 +f 66/25/62 70/11/72 88/29/91 +f 70/381/72 78/365/81 100/375/101 +f 78/365/81 92/340/94 108/346/108 +f 92/340/94 104/328/104 124/324/124 +f 88/29/91 70/11/72 100/5/101 +f 78/365/81 108/346/108 100/375/101 +f 92/340/94 124/324/124 108/346/108 +f 42/26/41 38/12/43 66/25/62 +f 38/382/43 52/370/52 70/381/72 +f 52/370/52 56/351/59 78/365/81 +f 56/351/59 74/339/76 92/340/94 +f 74/339/76 96/325/97 104/328/104 +f 66/25/62 38/12/43 70/11/72 +f 70/381/72 52/370/52 78/365/81 +f 56/351/59 92/340/94 78/365/81 +f 74/339/76 104/328/104 92/340/94 +f 28/23/29 20/17/22 42/26/41 +f 20/17/22 24/3/25 38/12/43 +f 24/372/25 34/366/34 52/370/52 +f 34/366/34 48/349/48 56/351/59 +f 48/349/48 62/334/68 74/339/76 +f 62/334/68 82/320/82 96/325/97 +f 42/26/41 20/17/22 38/12/43 +f 38/382/43 24/372/25 52/370/52 +f 34/366/34 56/351/59 52/370/52 +f 48/349/48 74/339/76 56/351/59 +f 62/334/68 96/325/97 74/339/76 +f 162/318/162 198/255/200 175/281/180 +f 140/329/136 174/282/173 162/318/162 +f 174/282/173 220/244/226 198/255/200 +f 174/282/173 198/255/200 162/318/162 +f 124/324/124 166/301/159 140/329/136 +f 166/301/159 194/272/204 174/282/173 +f 194/272/204 236/245/238 220/244/226 +f 140/329/136 166/301/159 174/282/173 +f 194/272/204 220/244/226 174/282/173 +f 104/328/104 136/307/140 124/324/124 +f 136/307/140 172/283/193 166/301/159 +f 172/283/193 224/266/223 194/272/204 +f 224/266/223 256/251/258 236/245/238 +f 124/324/124 136/307/140 166/301/159 +f 172/283/193 194/272/204 166/301/159 +f 224/266/223 236/245/238 194/272/204 +f 96/325/97 128/308/128 104/328/104 +f 128/308/128 158/296/167 136/307/140 +f 158/296/167 202/277/197 172/283/193 +f 202/277/197 232/265/234 224/266/223 +f 232/265/234 264/246/264 256/251/258 +f 104/328/104 128/308/128 136/307/140 +f 136/307/140 158/296/167 172/283/193 +f 202/277/197 224/266/223 172/283/193 +f 232/265/234 256/251/258 224/266/223 +f 82/320/82 112/313/112 96/325/97 +f 112/313/112 144/298/145 128/308/128 +f 144/298/145 170/284/172 158/296/167 +f 170/284/172 218/275/219 202/277/197 +f 218/275/219 250/260/250 232/265/234 +f 250/260/250 280/252/280 264/246/264 +f 96/325/97 112/313/112 128/308/128 +f 128/308/128 144/298/145 158/296/167 +f 158/296/167 170/284/172 202/277/197 +f 218/275/219 232/265/234 202/277/197 +f 250/260/250 264/246/264 232/265/234 +f 176/287/181 208/276/206 200/279/198 +f 208/276/206 242/261/242 230/269/229 +f 200/279/198 230/269/229 222/274/224 +f 208/276/206 230/269/229 200/279/198 +f 242/261/242 274/249/274 262/258/263 +f 230/269/229 262/258/263 254/263/255 +f 222/274/224 254/263/255 238/268/236 +f 242/261/242 262/258/263 230/269/229 +f 230/269/229 254/263/255 222/274/224 +f 274/249/274 296/238/299 292/241/291 +f 262/258/263 292/241/291 284/248/285 +f 254/263/255 284/248/285 270/256/271 +f 238/268/236 270/256/271 257/262/257 +f 262/258/263 274/249/274 292/241/291 +f 262/258/263 284/248/285 254/263/255 +f 238/268/236 254/263/255 270/256/271 +f 296/238/299 320/223/325 324/230/319 +f 292/241/291 324/230/319 310/236/308 +f 284/248/285 310/236/308 306/243/306 +f 270/256/271 306/243/306 287/253/288 +f 257/262/257 287/253/288 265/257/265 +f 292/241/291 296/238/299 324/230/319 +f 284/248/285 292/241/291 310/236/308 +f 270/256/271 284/248/285 306/243/306 +f 257/262/257 270/256/271 287/253/288 +f 320/223/325 335/209/335 342/220/343 +f 324/230/319 342/220/343 338/225/338 +f 310/236/308 338/225/338 328/231/326 +f 306/243/306 328/231/326 313/237/312 +f 287/253/288 313/237/312 299/242/297 +f 265/257/265 299/242/297 280/252/280 +f 324/230/319 320/223/325 342/220/343 +f 310/236/308 324/230/319 338/225/338 +f 306/243/306 310/236/308 328/231/326 +f 306/243/306 313/237/312 287/253/288 +f 265/257/265 287/253/288 299/242/297 +f 335/209/335 343/202/341 349/205/349 +f 343/202/341 339/187/337 355/195/354 +f 349/205/349 355/195/354 361/200/361 +f 343/202/341 355/195/354 349/205/349 +f 339/187/337 329/180/329 347/184/344 +f 355/195/354 347/184/344 359/189/359 +f 361/200/361 359/189/359 362/194/362 +f 339/187/337 347/184/344 355/195/354 +f 355/195/354 359/189/359 361/200/361 +f 329/180/329 315/164/314 333/167/333 +f 347/184/344 333/167/333 351/174/351 +f 359/189/359 351/174/351 357/182/357 +f 362/194/362 357/182/357 360/188/360 +f 347/184/344 329/180/329 333/167/333 +f 347/184/344 351/174/351 359/189/359 +f 362/194/362 359/189/359 357/182/357 +f 315/164/314 301/149/294 317/156/317 +f 333/167/333 317/156/317 332/162/332 +f 351/174/351 332/162/332 345/169/345 +f 357/182/357 345/169/345 353/177/352 +f 360/188/360 353/177/352 348/183/348 +f 333/167/333 315/164/314 317/156/317 +f 351/174/351 333/167/333 332/162/332 +f 357/182/357 351/174/351 345/169/345 +f 360/188/360 357/182/357 353/177/352 +f 301/149/294 281/135/281 300/146/295 +f 317/156/317 300/146/295 314/151/315 +f 332/162/332 314/151/315 327/157/328 +f 345/169/345 327/157/328 337/163/339 +f 353/177/352 337/163/339 341/168/342 +f 348/183/348 341/168/342 334/179/334 +f 317/156/317 301/149/294 300/146/295 +f 332/162/332 317/156/317 314/151/315 +f 345/169/345 332/162/332 327/157/328 +f 345/169/345 337/163/339 353/177/352 +f 348/183/348 353/177/352 341/168/342 +f 281/135/281 251/128/251 266/131/267 +f 251/128/251 219/113/218 234/121/233 +f 266/131/267 234/121/233 259/126/256 +f 251/128/251 234/121/233 266/131/267 +f 219/113/218 190/104/189 204/110/195 +f 234/121/233 204/110/195 227/115/222 +f 259/126/256 227/115/222 237/120/237 +f 219/113/218 204/110/195 234/121/233 +f 234/121/233 227/115/222 259/126/256 +f 190/104/189 145/90/144 160/93/166 +f 204/110/195 160/93/166 192/103/170 +f 227/115/222 192/103/170 195/108/205 +f 237/120/237 195/108/205 221/114/225 +f 204/110/195 190/104/189 160/93/166 +f 204/110/195 192/103/170 227/115/222 +f 237/120/237 227/115/222 195/108/205 +f 145/90/144 113/75/113 130/82/131 +f 160/93/166 130/82/131 138/88/143 +f 192/103/170 138/88/143 167/95/161 +f 195/108/205 167/95/161 193/102/171 +f 221/114/225 193/102/171 199/109/199 +f 160/93/166 145/90/144 130/82/131 +f 192/103/170 160/93/166 138/88/143 +f 195/108/205 192/103/170 167/95/161 +f 221/114/225 195/108/205 193/102/171 +f 113/75/113 83/67/83 98/72/98 +f 130/82/131 98/72/98 106/77/105 +f 138/88/143 106/77/105 125/83/126 +f 167/95/161 125/83/126 143/89/139 +f 193/102/171 143/89/139 163/94/164 +f 199/109/199 163/94/164 191/101/191 +f 130/82/131 113/75/113 98/72/98 +f 138/88/143 130/82/131 106/77/105 +f 138/88/143 125/83/126 167/95/161 +f 167/95/161 143/89/139 193/102/171 +f 199/109/199 193/102/171 163/94/164 +f 83/67/83 65/54/66 64/57/67 +f 65/54/66 51/39/51 47/47/47 +f 64/57/67 47/47/47 50/52/50 +f 65/54/66 47/47/47 64/57/67 +f 51/39/51 37/30/36 33/36/33 +f 47/47/47 33/36/33 32/41/32 +f 50/52/50 32/41/32 35/46/37 +f 51/39/51 33/36/33 47/47/47 +f 47/47/47 32/41/32 50/52/50 +f 37/30/36 27/16/27 19/19/16 +f 33/36/33 19/19/16 13/28/12 +f 32/41/32 13/28/12 17/34/17 +f 35/46/37 17/34/17 25/40/26 +f 37/30/36 19/19/16 33/36/33 +f 33/36/33 13/28/12 32/41/32 +f 32/41/32 17/34/17 35/46/37 +f 27/385/27 23/371/23 11/378/10 +f 19/19/16 11/8/10 7/14/5 +f 13/28/12 7/14/5 5/21/7 +f 17/34/17 5/21/7 9/24/8 +f 25/40/26 9/24/8 21/35/21 +f 19/19/16 27/16/27 11/8/10 +f 13/28/12 19/19/16 7/14/5 +f 13/28/12 5/21/7 17/34/17 +f 25/40/26 17/34/17 9/24/8 +f 23/371/23 29/363/28 15/368/15 +f 11/378/10 15/368/15 3/373/3 +f 7/384/5 3/373/3 1/379/1 +f 5/21/7 1/9/1 2/15/2 +f 9/24/8 2/15/2 14/20/14 +f 21/35/21 14/20/14 28/23/29 +f 11/378/10 23/371/23 15/368/15 +f 7/384/5 11/378/10 3/373/3 +f 7/14/5 1/9/1 5/21/7 +f 5/21/7 2/15/2 9/24/8 +f 9/24/8 14/20/14 21/35/21 +f 29/363/28 44/350/38 22/353/20 +f 44/350/38 68/335/65 40/343/42 +f 22/353/20 40/343/42 26/348/24 +f 44/350/38 40/343/42 22/353/20 +f 68/335/65 90/322/88 72/332/73 +f 40/343/42 72/332/73 53/337/53 +f 26/348/24 53/337/53 36/342/35 +f 68/335/65 72/332/73 40/343/42 +f 40/343/42 53/337/53 26/348/24 +f 90/322/88 122/312/122 102/315/100 +f 72/332/73 102/315/100 80/321/80 +f 53/337/53 80/321/80 58/330/57 +f 36/342/35 58/330/57 49/336/49 +f 90/322/88 102/315/100 72/332/73 +f 72/332/73 80/321/80 53/337/53 +f 53/337/53 58/330/57 36/342/35 +f 122/312/122 156/297/156 134/304/134 +f 102/315/100 134/304/134 110/310/109 +f 80/321/80 110/310/109 94/317/93 +f 58/330/57 94/317/93 75/326/74 +f 49/336/49 75/326/74 63/331/69 +f 102/315/100 122/312/122 134/304/134 +f 80/321/80 102/315/100 110/310/109 +f 80/321/80 94/317/93 58/330/57 +f 49/336/49 58/330/57 75/326/74 +f 156/297/156 176/287/181 164/294/165 +f 134/304/134 164/294/165 141/299/138 +f 110/310/109 141/299/138 126/305/125 +f 94/317/93 126/305/125 105/311/107 +f 75/326/74 105/311/107 97/316/96 +f 63/331/69 97/316/96 82/320/82 +f 134/304/134 156/297/156 164/294/165 +f 110/310/109 134/304/134 141/299/138 +f 110/310/109 126/305/125 94/317/93 +f 94/317/93 105/311/107 75/326/74 +f 75/326/74 97/316/96 63/331/69 +f 348/183/348 334/179/334 340/186/340 +f 352/193/353 340/186/340 336/201/336 +f 360/188/360 348/183/348 352/193/353 +f 352/193/353 348/183/348 340/186/340 +f 344/204/346 336/201/336 326/215/327 +f 356/199/358 352/193/353 344/204/346 +f 362/194/362 360/188/360 356/199/358 +f 344/204/346 352/193/353 336/201/336 +f 356/199/358 360/188/360 352/193/353 +f 312/224/313 330/221/331 326/215/327 +f 330/221/331 350/212/350 344/204/346 +f 358/206/356 356/199/358 350/212/350 +f 358/206/356 361/200/361 362/194/362 +f 330/221/331 344/204/346 326/215/327 +f 350/212/350 356/199/358 344/204/346 +f 358/206/356 362/194/362 356/199/358 +f 298/239/296 316/232/316 312/224/313 +f 316/232/316 331/226/330 330/221/331 +f 331/226/330 346/219/347 350/212/350 +f 346/219/347 354/208/355 358/206/356 +f 354/208/355 349/205/349 361/200/361 +f 316/232/316 330/221/331 312/224/313 +f 331/226/330 350/212/350 330/221/331 +f 346/219/347 358/206/356 350/212/350 +f 354/208/355 361/200/361 358/206/356 +f 280/252/280 299/242/297 298/239/296 +f 299/242/297 313/237/312 316/232/316 +f 313/237/312 328/231/326 331/226/330 +f 328/231/326 338/225/338 346/219/347 +f 342/220/343 354/208/355 338/225/338 +f 342/220/343 335/209/335 349/205/349 +f 299/242/297 316/232/316 298/239/296 +f 313/237/312 331/226/330 316/232/316 +f 328/231/326 346/219/347 331/226/330 +f 338/225/338 354/208/355 346/219/347 +f 342/220/343 349/205/349 354/208/355 +f 199/109/199 191/101/191 207/112/207 +f 229/119/228 207/112/207 241/127/241 +f 221/114/225 199/109/199 229/119/228 +f 229/119/228 199/109/199 207/112/207 +f 261/130/262 241/127/241 273/137/275 +f 253/125/252 229/119/228 261/130/262 +f 237/120/237 221/114/225 253/125/252 +f 261/130/262 229/119/228 241/127/241 +f 253/125/252 221/114/225 229/119/228 +f 295/150/298 291/147/290 273/137/275 +f 291/147/290 283/139/284 261/130/262 +f 269/132/270 253/125/252 283/139/284 +f 269/132/270 259/126/256 237/120/237 +f 291/147/290 261/130/262 273/137/275 +f 283/139/284 253/125/252 261/130/262 +f 269/132/270 237/120/237 253/125/252 +f 319/165/324 323/158/321 295/150/298 +f 323/158/321 309/152/311 291/147/290 +f 309/152/311 305/145/307 283/139/284 +f 305/145/307 289/143/289 269/132/270 +f 289/143/289 266/131/267 259/126/256 +f 323/158/321 291/147/290 295/150/298 +f 309/152/311 283/139/284 291/147/290 +f 305/145/307 269/132/270 283/139/284 +f 289/143/289 259/126/256 269/132/270 +f 334/179/334 341/168/342 319/165/324 +f 341/168/342 337/163/339 323/158/321 +f 337/163/339 327/157/328 309/152/311 +f 327/157/328 314/151/315 305/145/307 +f 300/146/295 289/143/289 314/151/315 +f 300/146/295 281/135/281 266/131/267 +f 341/168/342 323/158/321 319/165/324 +f 337/163/339 309/152/311 323/158/321 +f 327/157/328 305/145/307 309/152/311 +f 314/151/315 289/143/289 305/145/307 +f 300/146/295 266/131/267 289/143/289 +f 21/35/21 28/23/29 43/38/39 +f 39/45/45 43/38/39 67/53/64 +f 25/40/26 21/35/21 39/45/45 +f 39/45/45 21/35/21 43/38/39 +f 71/56/70 67/53/64 89/64/89 +f 54/51/54 39/45/45 71/56/70 +f 35/46/37 25/40/26 54/51/54 +f 71/56/70 39/45/45 67/53/64 +f 54/51/54 25/40/26 39/45/45 +f 121/76/121 101/73/103 89/64/89 +f 79/68/78 71/56/70 101/73/103 +f 57/58/56 54/51/54 79/68/78 +f 50/52/50 35/46/37 57/58/56 +f 101/73/103 71/56/70 89/64/89 +f 79/68/78 54/51/54 71/56/70 +f 57/58/56 35/46/37 54/51/54 +f 155/91/157 133/84/135 121/76/121 +f 133/84/135 109/78/111 101/73/103 +f 109/78/111 93/71/92 79/68/78 +f 76/66/75 57/58/56 93/71/92 +f 76/66/75 64/57/67 50/52/50 +f 133/84/135 101/73/103 121/76/121 +f 109/78/111 79/68/78 101/73/103 +f 93/71/92 57/58/56 79/68/78 +f 76/66/75 50/52/50 57/58/56 +f 191/101/191 163/94/164 155/91/157 +f 163/94/164 143/89/139 133/84/135 +f 143/89/139 125/83/126 109/78/111 +f 106/77/105 93/71/92 125/83/126 +f 98/72/98 76/66/75 106/77/105 +f 83/67/83 64/57/67 98/72/98 +f 163/94/164 133/84/135 155/91/157 +f 143/89/139 109/78/111 133/84/135 +f 125/83/126 93/71/92 109/78/111 +f 106/77/105 76/66/75 93/71/92 +f 98/72/98 64/57/67 76/66/75 +f 63/331/69 82/320/82 62/334/68 +f 46/341/46 62/334/68 48/349/48 +f 49/336/49 63/331/69 46/341/46 +f 46/341/46 63/331/69 62/334/68 +f 30/352/31 48/349/48 34/366/34 +f 31/347/30 46/341/46 30/352/31 +f 36/342/35 49/336/49 31/347/30 +f 30/352/31 46/341/46 48/349/48 +f 31/347/30 49/336/49 46/341/46 +f 24/372/25 16/369/18 34/366/34 +f 12/358/13 30/352/31 16/369/18 +f 18/354/19 31/347/30 12/358/13 +f 26/348/24 36/342/35 18/354/19 +f 16/369/18 30/352/31 34/366/34 +f 12/358/13 31/347/30 30/352/31 +f 18/354/19 36/342/35 31/347/30 +f 20/17/22 8/10/9 24/3/25 +f 8/380/9 4/374/4 16/369/18 +f 4/374/4 6/367/6 12/358/13 +f 10/362/11 18/354/19 6/367/6 +f 10/362/11 22/353/20 26/348/24 +f 8/380/9 16/369/18 24/372/25 +f 4/374/4 12/358/13 16/369/18 +f 6/367/6 18/354/19 12/358/13 +f 10/362/11 26/348/24 18/354/19 +f 28/23/29 14/20/14 20/17/22 +f 14/20/14 2/15/2 8/10/9 +f 2/15/2 1/9/1 4/4/4 +f 3/373/3 6/367/6 1/379/1 +f 15/368/15 10/362/11 3/373/3 +f 29/363/28 22/353/20 15/368/15 +f 14/20/14 8/10/9 20/17/22 +f 2/15/2 4/4/4 8/10/9 +f 1/379/1 6/367/6 4/374/4 +f 3/373/3 10/362/11 6/367/6 +f 15/368/15 22/353/20 10/362/11 +f 265/257/265 280/252/280 250/260/250 +f 233/267/232 250/260/250 218/275/219 +f 257/262/257 265/257/265 233/267/232 +f 233/267/232 265/257/265 250/260/250 +f 203/278/196 218/275/219 170/284/172 +f 225/273/220 233/267/232 203/278/196 +f 238/268/236 257/262/257 225/273/220 +f 203/278/196 233/267/232 218/275/219 +f 225/273/220 257/262/257 233/267/232 +f 144/298/145 159/295/169 170/284/172 +f 159/295/169 171/285/192 203/278/196 +f 196/280/202 225/273/220 171/285/192 +f 196/280/202 222/274/224 238/268/236 +f 159/295/169 203/278/196 170/284/172 +f 171/285/192 225/273/220 203/278/196 +f 196/280/202 238/268/236 225/273/220 +f 112/313/112 129/306/130 144/298/145 +f 129/306/130 137/300/141 159/295/169 +f 137/300/141 168/293/158 171/285/192 +f 168/293/158 173/286/174 196/280/202 +f 173/286/174 200/279/198 222/274/224 +f 129/306/130 159/295/169 144/298/145 +f 137/300/141 171/285/192 159/295/169 +f 168/293/158 196/280/202 171/285/192 +f 173/286/174 222/274/224 196/280/202 +f 82/320/82 97/316/96 112/313/112 +f 97/316/96 105/311/107 129/306/130 +f 105/311/107 126/305/125 137/300/141 +f 141/299/138 168/293/158 126/305/125 +f 164/294/165 173/286/174 141/299/138 +f 164/294/165 176/287/181 200/279/198 +f 97/316/96 129/306/130 112/313/112 +f 105/311/107 137/300/141 129/306/130 +f 126/305/125 168/293/158 137/300/141 +f 141/299/138 173/286/174 168/293/158 +f 164/294/165 200/279/198 173/286/174 diff --git a/demos/art/meshes/suzanne.obj b/demos/art/meshes/suzanne.obj new file mode 100644 index 0000000..7d657dc --- /dev/null +++ b/demos/art/meshes/suzanne.obj @@ -0,0 +1,2580 @@ +# Blender3D v249 OBJ File: suzanne.blend +# www.blender3d.org +v 0.437500 0.164063 0.765625 +v -0.437500 0.164063 0.765625 +v 0.500000 0.093750 0.687500 +v -0.500000 0.093750 0.687500 +v 0.546875 0.054688 0.578125 +v -0.546875 0.054688 0.578125 +v 0.351563 -0.023438 0.617188 +v -0.351563 -0.023438 0.617188 +v 0.351563 0.031250 0.718750 +v -0.351563 0.031250 0.718750 +v 0.351563 0.132813 0.781250 +v -0.351563 0.132813 0.781250 +v 0.273438 0.164063 0.796875 +v -0.273438 0.164063 0.796875 +v 0.203125 0.093750 0.742188 +v -0.203125 0.093750 0.742188 +v 0.156250 0.054688 0.648438 +v -0.156250 0.054688 0.648438 +v 0.078125 0.242188 0.656250 +v -0.078125 0.242188 0.656250 +v 0.140625 0.242188 0.742188 +v -0.140625 0.242188 0.742188 +v 0.242188 0.242188 0.796875 +v -0.242188 0.242188 0.796875 +v 0.273438 0.328125 0.796875 +v -0.273438 0.328125 0.796875 +v 0.203125 0.390625 0.742188 +v -0.203125 0.390625 0.742188 +v 0.156250 0.437500 0.648438 +v -0.156250 0.437500 0.648438 +v 0.351563 0.515625 0.617188 +v -0.351563 0.515625 0.617188 +v 0.351563 0.453125 0.718750 +v -0.351563 0.453125 0.718750 +v 0.351563 0.359375 0.781250 +v -0.351563 0.359375 0.781250 +v 0.437500 0.328125 0.765625 +v -0.437500 0.328125 0.765625 +v 0.500000 0.390625 0.687500 +v -0.500000 0.390625 0.687500 +v 0.546875 0.437500 0.578125 +v -0.546875 0.437500 0.578125 +v 0.625000 0.242188 0.562500 +v -0.625000 0.242188 0.562500 +v 0.562500 0.242188 0.671875 +v -0.562500 0.242188 0.671875 +v 0.468750 0.242188 0.757813 +v -0.468750 0.242188 0.757813 +v 0.476563 0.242188 0.773438 +v -0.476563 0.242188 0.773438 +v 0.445313 0.335938 0.781250 +v -0.445313 0.335938 0.781250 +v 0.351563 0.375000 0.804688 +v -0.351563 0.375000 0.804688 +v 0.265625 0.335938 0.820313 +v -0.265625 0.335938 0.820313 +v 0.226563 0.242188 0.820313 +v -0.226563 0.242188 0.820313 +v 0.265625 0.156250 0.820313 +v -0.265625 0.156250 0.820313 +v 0.351563 0.242188 0.828125 +v -0.351563 0.242188 0.828125 +v 0.351563 0.117188 0.804688 +v -0.351563 0.117188 0.804688 +v 0.445313 0.156250 0.781250 +v -0.445313 0.156250 0.781250 +v 0.000000 0.429688 0.742188 +v 0.000000 0.351563 0.820313 +v 0.000000 -0.679688 0.734375 +v 0.000000 -0.320313 0.781250 +v 0.000000 -0.187500 0.796875 +v 0.000000 -0.773438 0.718750 +v 0.000000 0.406250 0.601563 +v 0.000000 0.570313 0.570313 +v 0.000000 0.898438 -0.546875 +v 0.000000 0.562500 -0.851563 +v 0.000000 0.070313 -0.828125 +v 0.000000 -0.382813 -0.351563 +v 0.203125 -0.187500 0.562500 +v -0.203125 -0.187500 0.562500 +v 0.312500 -0.437500 0.570313 +v -0.312500 -0.437500 0.570313 +v 0.351563 -0.695313 0.570313 +v -0.351563 -0.695313 0.570313 +v 0.367188 -0.890625 0.531250 +v -0.367188 -0.890625 0.531250 +v 0.328125 -0.945313 0.523438 +v -0.328125 -0.945313 0.523438 +v 0.179688 -0.968750 0.554688 +v -0.179688 -0.968750 0.554688 +v 0.000000 -0.984375 0.578125 +v 0.437500 -0.140625 0.531250 +v -0.437500 -0.140625 0.531250 +v 0.632813 -0.039063 0.539063 +v -0.632813 -0.039063 0.539063 +v 0.828125 0.148438 0.445313 +v -0.828125 0.148438 0.445313 +v 0.859375 0.429688 0.593750 +v -0.859375 0.429688 0.593750 +v 0.710938 0.484375 0.625000 +v -0.710938 0.484375 0.625000 +v 0.492188 0.601563 0.687500 +v -0.492188 0.601563 0.687500 +v 0.320313 0.757813 0.734375 +v -0.320313 0.757813 0.734375 +v 0.156250 0.718750 0.757813 +v -0.156250 0.718750 0.757813 +v 0.062500 0.492188 0.750000 +v -0.062500 0.492188 0.750000 +v 0.164063 0.414063 0.773438 +v -0.164063 0.414063 0.773438 +v 0.125000 0.304688 0.765625 +v -0.125000 0.304688 0.765625 +v 0.203125 0.093750 0.742188 +v -0.203125 0.093750 0.742188 +v 0.375000 0.015625 0.703125 +v -0.375000 0.015625 0.703125 +v 0.492188 0.062500 0.671875 +v -0.492188 0.062500 0.671875 +v 0.625000 0.187500 0.648438 +v -0.625000 0.187500 0.648438 +v 0.640625 0.296875 0.648438 +v -0.640625 0.296875 0.648438 +v 0.601563 0.375000 0.664063 +v -0.601563 0.375000 0.664063 +v 0.429688 0.437500 0.718750 +v -0.429688 0.437500 0.718750 +v 0.250000 0.468750 0.757813 +v -0.250000 0.468750 0.757813 +v 0.000000 -0.765625 0.734375 +v 0.109375 -0.718750 0.734375 +v -0.109375 -0.718750 0.734375 +v 0.117188 -0.835938 0.710938 +v -0.117188 -0.835938 0.710938 +v 0.062500 -0.882813 0.695313 +v -0.062500 -0.882813 0.695313 +v 0.000000 -0.890625 0.687500 +v 0.000000 -0.195313 0.750000 +v 0.000000 -0.140625 0.742188 +v 0.101563 -0.148438 0.742188 +v -0.101563 -0.148438 0.742188 +v 0.125000 -0.226563 0.750000 +v -0.125000 -0.226563 0.750000 +v 0.085938 -0.289063 0.742188 +v -0.085938 -0.289063 0.742188 +v 0.398438 -0.046875 0.671875 +v -0.398438 -0.046875 0.671875 +v 0.617188 0.054688 0.625000 +v -0.617188 0.054688 0.625000 +v 0.726563 0.203125 0.601563 +v -0.726563 0.203125 0.601563 +v 0.742188 0.375000 0.656250 +v -0.742188 0.375000 0.656250 +v 0.687500 0.414063 0.726563 +v -0.687500 0.414063 0.726563 +v 0.437500 0.546875 0.796875 +v -0.437500 0.546875 0.796875 +v 0.312500 0.640625 0.835938 +v -0.312500 0.640625 0.835938 +v 0.203125 0.617188 0.851563 +v -0.203125 0.617188 0.851563 +v 0.101563 0.429688 0.843750 +v -0.101563 0.429688 0.843750 +v 0.125000 -0.101563 0.812500 +v -0.125000 -0.101563 0.812500 +v 0.210938 -0.445313 0.710938 +v -0.210938 -0.445313 0.710938 +v 0.250000 -0.703125 0.687500 +v -0.250000 -0.703125 0.687500 +v 0.265625 -0.820313 0.664063 +v -0.265625 -0.820313 0.664063 +v 0.234375 -0.914063 0.632813 +v -0.234375 -0.914063 0.632813 +v 0.164063 -0.929688 0.632813 +v -0.164063 -0.929688 0.632813 +v 0.000000 -0.945313 0.640625 +v 0.000000 0.046875 0.726563 +v 0.000000 0.210938 0.765625 +v 0.328125 0.476563 0.742188 +v -0.328125 0.476563 0.742188 +v 0.164063 0.140625 0.750000 +v -0.164063 0.140625 0.750000 +v 0.132813 0.210938 0.757813 +v -0.132813 0.210938 0.757813 +v 0.117188 -0.687500 0.734375 +v -0.117188 -0.687500 0.734375 +v 0.078125 -0.445313 0.750000 +v -0.078125 -0.445313 0.750000 +v 0.000000 -0.445313 0.750000 +v 0.000000 -0.328125 0.742188 +v 0.093750 -0.273438 0.781250 +v -0.093750 -0.273438 0.781250 +v 0.132813 -0.226563 0.796875 +v -0.132813 -0.226563 0.796875 +v 0.109375 -0.132813 0.781250 +v -0.109375 -0.132813 0.781250 +v 0.039063 -0.125000 0.781250 +v -0.039063 -0.125000 0.781250 +v 0.000000 -0.203125 0.828125 +v 0.046875 -0.148438 0.812500 +v -0.046875 -0.148438 0.812500 +v 0.093750 -0.156250 0.812500 +v -0.093750 -0.156250 0.812500 +v 0.109375 -0.226563 0.828125 +v -0.109375 -0.226563 0.828125 +v 0.078125 -0.250000 0.804688 +v -0.078125 -0.250000 0.804688 +v 0.000000 -0.289063 0.804688 +v 0.257813 -0.312500 0.554688 +v -0.257813 -0.312500 0.554688 +v 0.164063 -0.242188 0.710938 +v -0.164063 -0.242188 0.710938 +v 0.179688 -0.312500 0.710938 +v -0.179688 -0.312500 0.710938 +v 0.234375 -0.250000 0.554688 +v -0.234375 -0.250000 0.554688 +v 0.000000 -0.875000 0.687500 +v 0.046875 -0.867188 0.687500 +v -0.046875 -0.867188 0.687500 +v 0.093750 -0.820313 0.710938 +v -0.093750 -0.820313 0.710938 +v 0.093750 -0.742188 0.726563 +v -0.093750 -0.742188 0.726563 +v 0.000000 -0.781250 0.656250 +v 0.093750 -0.750000 0.664063 +v -0.093750 -0.750000 0.664063 +v 0.093750 -0.812500 0.640625 +v -0.093750 -0.812500 0.640625 +v 0.046875 -0.851563 0.632813 +v -0.046875 -0.851563 0.632813 +v 0.000000 -0.859375 0.632813 +v 0.171875 0.218750 0.781250 +v -0.171875 0.218750 0.781250 +v 0.187500 0.156250 0.773438 +v -0.187500 0.156250 0.773438 +v 0.335938 0.429688 0.757813 +v -0.335938 0.429688 0.757813 +v 0.273438 0.421875 0.773438 +v -0.273438 0.421875 0.773438 +v 0.421875 0.398438 0.773438 +v -0.421875 0.398438 0.773438 +v 0.562500 0.351563 0.695313 +v -0.562500 0.351563 0.695313 +v 0.585938 0.289063 0.687500 +v -0.585938 0.289063 0.687500 +v 0.578125 0.195313 0.679688 +v -0.578125 0.195313 0.679688 +v 0.476563 0.101563 0.718750 +v -0.476563 0.101563 0.718750 +v 0.375000 0.062500 0.742188 +v -0.375000 0.062500 0.742188 +v 0.226563 0.109375 0.781250 +v -0.226563 0.109375 0.781250 +v 0.179688 0.296875 0.781250 +v -0.179688 0.296875 0.781250 +v 0.210938 0.375000 0.781250 +v -0.210938 0.375000 0.781250 +v 0.234375 0.359375 0.757813 +v -0.234375 0.359375 0.757813 +v 0.195313 0.296875 0.757813 +v -0.195313 0.296875 0.757813 +v 0.242188 0.125000 0.757813 +v -0.242188 0.125000 0.757813 +v 0.375000 0.085938 0.726563 +v -0.375000 0.085938 0.726563 +v 0.460938 0.117188 0.703125 +v -0.460938 0.117188 0.703125 +v 0.546875 0.210938 0.671875 +v -0.546875 0.210938 0.671875 +v 0.554688 0.281250 0.671875 +v -0.554688 0.281250 0.671875 +v 0.531250 0.335938 0.679688 +v -0.531250 0.335938 0.679688 +v 0.414063 0.390625 0.750000 +v -0.414063 0.390625 0.750000 +v 0.281250 0.398438 0.765625 +v -0.281250 0.398438 0.765625 +v 0.335938 0.406250 0.750000 +v -0.335938 0.406250 0.750000 +v 0.203125 0.171875 0.750000 +v -0.203125 0.171875 0.750000 +v 0.195313 0.226563 0.750000 +v -0.195313 0.226563 0.750000 +v 0.109375 0.460938 0.609375 +v -0.109375 0.460938 0.609375 +v 0.195313 0.664063 0.617188 +v -0.195313 0.664063 0.617188 +v 0.335938 0.687500 0.593750 +v -0.335938 0.687500 0.593750 +v 0.484375 0.554688 0.554688 +v -0.484375 0.554688 0.554688 +v 0.679688 0.453125 0.492188 +v -0.679688 0.453125 0.492188 +v 0.796875 0.406250 0.460938 +v -0.796875 0.406250 0.460938 +v 0.773438 0.164063 0.375000 +v -0.773438 0.164063 0.375000 +v 0.601563 0.000000 0.414063 +v -0.601563 0.000000 0.414063 +v 0.437500 -0.093750 0.468750 +v -0.437500 -0.093750 0.468750 +v 0.000000 0.898438 0.289063 +v 0.000000 0.984375 -0.078125 +v 0.000000 -0.195313 -0.671875 +v 0.000000 -0.460938 0.187500 +v 0.000000 -0.976563 0.460938 +v 0.000000 -0.804688 0.343750 +v 0.000000 -0.570313 0.320313 +v 0.000000 -0.484375 0.281250 +v 0.851563 0.234375 0.054688 +v -0.851563 0.234375 0.054688 +v 0.859375 0.320313 -0.046875 +v -0.859375 0.320313 -0.046875 +v 0.773438 0.265625 -0.437500 +v -0.773438 0.265625 -0.437500 +v 0.460938 0.437500 -0.703125 +v -0.460938 0.437500 -0.703125 +v 0.734375 -0.046875 0.070313 +v -0.734375 -0.046875 0.070313 +v 0.593750 -0.125000 -0.164063 +v -0.593750 -0.125000 -0.164063 +v 0.640625 -0.007813 -0.429688 +v -0.640625 -0.007813 -0.429688 +v 0.335938 0.054688 -0.664063 +v -0.335938 0.054688 -0.664063 +v 0.234375 -0.351563 0.406250 +v -0.234375 -0.351563 0.406250 +v 0.179688 -0.414063 0.257813 +v -0.179688 -0.414063 0.257813 +v 0.289063 -0.710938 0.382813 +v -0.289063 -0.710938 0.382813 +v 0.250000 -0.500000 0.390625 +v -0.250000 -0.500000 0.390625 +v 0.328125 -0.914063 0.398438 +v -0.328125 -0.914063 0.398438 +v 0.140625 -0.757813 0.367188 +v -0.140625 -0.757813 0.367188 +v 0.125000 -0.539063 0.359375 +v -0.125000 -0.539063 0.359375 +v 0.164063 -0.945313 0.437500 +v -0.164063 -0.945313 0.437500 +v 0.218750 -0.281250 0.429688 +v -0.218750 -0.281250 0.429688 +v 0.210938 -0.226563 0.468750 +v -0.210938 -0.226563 0.468750 +v 0.203125 -0.171875 0.500000 +v -0.203125 -0.171875 0.500000 +v 0.210938 -0.390625 0.164063 +v -0.210938 -0.390625 0.164063 +v 0.296875 -0.312500 -0.265625 +v -0.296875 -0.312500 -0.265625 +v 0.343750 -0.148438 -0.539063 +v -0.343750 -0.148438 -0.539063 +v 0.453125 0.867188 -0.382813 +v -0.453125 0.867188 -0.382813 +v 0.453125 0.929688 -0.070313 +v -0.453125 0.929688 -0.070313 +v 0.453125 0.851563 0.234375 +v -0.453125 0.851563 0.234375 +v 0.460938 0.523438 0.429688 +v -0.460938 0.523438 0.429688 +v 0.726563 0.406250 0.335938 +v -0.726563 0.406250 0.335938 +v 0.632813 0.453125 0.281250 +v -0.632813 0.453125 0.281250 +v 0.640625 0.703125 0.054688 +v -0.640625 0.703125 0.054688 +v 0.796875 0.562500 0.125000 +v -0.796875 0.562500 0.125000 +v 0.796875 0.617188 -0.117188 +v -0.796875 0.617188 -0.117188 +v 0.640625 0.750000 -0.195313 +v -0.640625 0.750000 -0.195313 +v 0.640625 0.679688 -0.445313 +v -0.640625 0.679688 -0.445313 +v 0.796875 0.539063 -0.359375 +v -0.796875 0.539063 -0.359375 +v 0.617188 0.328125 -0.585938 +v -0.617188 0.328125 -0.585938 +v 0.484375 0.023438 -0.546875 +v -0.484375 0.023438 -0.546875 +v 0.820313 0.328125 -0.203125 +v -0.820313 0.328125 -0.203125 +v 0.406250 -0.171875 0.148438 +v -0.406250 -0.171875 0.148438 +v 0.429688 -0.195313 -0.210938 +v -0.429688 -0.195313 -0.210938 +v 0.890625 0.406250 -0.234375 +v -0.890625 0.406250 -0.234375 +v 0.773438 -0.140625 -0.125000 +v -0.773438 -0.140625 -0.125000 +v 1.039063 -0.101563 -0.328125 +v -1.039063 -0.101563 -0.328125 +v 1.281250 0.054688 -0.429688 +v -1.281250 0.054688 -0.429688 +v 1.351563 0.320313 -0.421875 +v -1.351563 0.320313 -0.421875 +v 1.234375 0.507813 -0.421875 +v -1.234375 0.507813 -0.421875 +v 1.023438 0.476563 -0.312500 +v -1.023438 0.476563 -0.312500 +v 1.015625 0.414063 -0.289063 +v -1.015625 0.414063 -0.289063 +v 1.187500 0.437500 -0.390625 +v -1.187500 0.437500 -0.390625 +v 1.265625 0.289063 -0.406250 +v -1.265625 0.289063 -0.406250 +v 1.210938 0.078125 -0.406250 +v -1.210938 0.078125 -0.406250 +v 1.031250 -0.039063 -0.304688 +v -1.031250 -0.039063 -0.304688 +v 0.828125 -0.070313 -0.132813 +v -0.828125 -0.070313 -0.132813 +v 0.921875 0.359375 -0.218750 +v -0.921875 0.359375 -0.218750 +v 0.945313 0.304688 -0.289063 +v -0.945313 0.304688 -0.289063 +v 0.882813 -0.023438 -0.210938 +v -0.882813 -0.023438 -0.210938 +v 1.039063 0.000000 -0.367188 +v -1.039063 0.000000 -0.367188 +v 1.187500 0.093750 -0.445313 +v -1.187500 0.093750 -0.445313 +v 1.234375 0.250000 -0.445313 +v -1.234375 0.250000 -0.445313 +v 1.171875 0.359375 -0.437500 +v -1.171875 0.359375 -0.437500 +v 1.023438 0.343750 -0.359375 +v -1.023438 0.343750 -0.359375 +v 0.843750 0.289063 -0.210938 +v -0.843750 0.289063 -0.210938 +v 0.835938 0.171875 -0.273438 +v -0.835938 0.171875 -0.273438 +v 0.757813 0.093750 -0.273438 +v -0.757813 0.093750 -0.273438 +v 0.820313 0.085938 -0.273438 +v -0.820313 0.085938 -0.273438 +v 0.843750 0.015625 -0.273438 +v -0.843750 0.015625 -0.273438 +v 0.812500 -0.015625 -0.273438 +v -0.812500 -0.015625 -0.273438 +v 0.726563 0.000000 -0.070313 +v -0.726563 0.000000 -0.070313 +v 0.718750 -0.023438 -0.171875 +v -0.718750 -0.023438 -0.171875 +v 0.718750 0.039063 -0.187500 +v -0.718750 0.039063 -0.187500 +v 0.796875 0.203125 -0.210938 +v -0.796875 0.203125 -0.210938 +v 0.890625 0.242188 -0.265625 +v -0.890625 0.242188 -0.265625 +v 0.890625 0.234375 -0.320313 +v -0.890625 0.234375 -0.320313 +v 0.812500 -0.015625 -0.320313 +v -0.812500 -0.015625 -0.320313 +v 0.851563 0.015625 -0.320313 +v -0.851563 0.015625 -0.320313 +v 0.828125 0.078125 -0.320313 +v -0.828125 0.078125 -0.320313 +v 0.765625 0.093750 -0.320313 +v -0.765625 0.093750 -0.320313 +v 0.843750 0.171875 -0.320313 +v -0.843750 0.171875 -0.320313 +v 1.039063 0.328125 -0.414063 +v -1.039063 0.328125 -0.414063 +v 1.187500 0.343750 -0.484375 +v -1.187500 0.343750 -0.484375 +v 1.257813 0.242188 -0.492188 +v -1.257813 0.242188 -0.492188 +v 1.210938 0.085938 -0.484375 +v -1.210938 0.085938 -0.484375 +v 1.046875 0.000000 -0.421875 +v -1.046875 0.000000 -0.421875 +v 0.882813 -0.015625 -0.265625 +v -0.882813 -0.015625 -0.265625 +v 0.953125 0.289063 -0.343750 +v -0.953125 0.289063 -0.343750 +v 0.890625 0.109375 -0.328125 +v -0.890625 0.109375 -0.328125 +v 0.937500 0.062500 -0.335938 +v -0.937500 0.062500 -0.335938 +v 1.000000 0.125000 -0.367188 +v -1.000000 0.125000 -0.367188 +v 0.960938 0.171875 -0.351563 +v -0.960938 0.171875 -0.351563 +v 1.015625 0.234375 -0.375000 +v -1.015625 0.234375 -0.375000 +v 1.054688 0.187500 -0.382813 +v -1.054688 0.187500 -0.382813 +v 1.109375 0.210938 -0.390625 +v -1.109375 0.210938 -0.390625 +v 1.085938 0.273438 -0.390625 +v -1.085938 0.273438 -0.390625 +v 1.023438 0.437500 -0.484375 +v -1.023438 0.437500 -0.484375 +v 1.250000 0.468750 -0.546875 +v -1.250000 0.468750 -0.546875 +v 1.367188 0.296875 -0.500000 +v -1.367188 0.296875 -0.500000 +v 1.312500 0.054688 -0.531250 +v -1.312500 0.054688 -0.531250 +v 1.039063 -0.085938 -0.492188 +v -1.039063 -0.085938 -0.492188 +v 0.789063 -0.125000 -0.328125 +v -0.789063 -0.125000 -0.328125 +v 0.859375 0.382813 -0.382813 +v -0.859375 0.382813 -0.382813 +v -1.023438 0.476563 -0.312500 +v -1.234375 0.507813 -0.421875 +v -0.890625 0.406250 -0.234375 +v -0.820313 0.328125 -0.203125 +vt 0.315596 0.792535 +vt 0.331462 0.787091 +vt 0.331944 0.799704 +vt 0.049262 0.798007 +vt 0.050304 0.785428 +vt 0.065913 0.791570 +vt 0.321453 0.778649 +vt 0.060677 0.777438 +vt 0.310368 0.778802 +vt 0.071744 0.778083 +vt 0.302416 0.786560 +vt 0.079345 0.786186 +vt 0.301514 0.798474 +vt 0.079717 0.798128 +vt 0.308740 0.806873 +vt 0.072125 0.806199 +vt 0.321648 0.808687 +vt 0.059149 0.807438 +vt 0.048462 0.201858 +vt 0.040084 0.207259 +vt 0.043232 0.202821 +vt 0.043249 0.220655 +vt 0.040093 0.216224 +vt 0.048480 0.221607 +vt 0.563710 0.649220 +vt 0.540594 0.657349 +vt 0.547067 0.627433 +vt 0.974643 0.218739 +vt 0.968169 0.188824 +vt 0.991286 0.196952 +vt 0.166564 0.702856 +vt 0.160061 0.635503 +vt 0.218800 0.643864 +vt 0.646379 0.202310 +vt 0.587641 0.210669 +vt 0.594146 0.143318 +vt 0.231653 0.710981 +vt 0.181122 0.727399 +vt 0.174315 0.716236 +vt 0.601897 0.129938 +vt 0.608704 0.118775 +vt 0.659234 0.135195 +vt 0.266169 0.503056 +vt 0.270502 0.531304 +vt 0.237927 0.525958 +vt 0.665505 0.320215 +vt 0.698081 0.314870 +vt 0.693747 0.343118 +vt 0.392095 0.783569 +vt 0.421339 0.774990 +vt 0.422693 0.793271 +vt 0.628129 0.465996 +vt 0.613733 0.456434 +vt 0.634389 0.436387 +vt 0.501778 0.870396 +vt 0.507486 0.857499 +vt 0.528577 0.865850 +vt 0.643384 0.583025 +vt 0.644052 0.562152 +vt 0.656465 0.561923 +vt 0.766386 0.787223 +vt 0.745292 0.810963 +vt 0.708792 0.802136 +vt 0.769147 0.634951 +vt 0.732033 0.641034 +vt 0.711181 0.618495 +vt 0.849461 0.545148 +vt 0.823375 0.497849 +vt 0.897469 0.500666 +vt 0.902318 0.546395 +vt 0.572425 0.679855 +vt 0.643837 0.668801 +vt 0.623443 0.718088 +vt 0.572425 0.724426 +vt 0.726607 0.540494 +vt 0.753364 0.518460 +vt 0.715449 0.680462 +vt 0.749227 0.698466 +vt 0.695922 0.534580 +vt 0.693526 0.510498 +vt 0.772837 0.655221 +vt 0.784620 0.679820 +vt 0.718163 0.580185 +vt 0.809389 0.599417 +vt 0.761761 0.743313 +vt 0.667750 0.767676 +vt 0.693110 0.564191 +vt 0.797155 0.722534 +vt 0.682009 0.616616 +vt 0.795802 0.787304 +vt 0.719538 0.655221 +vt 0.756895 0.826983 +vt 0.782765 0.655221 +vt 0.695179 0.821970 +vt 0.843059 0.610497 +vt 0.635588 0.780626 +vt 0.634422 0.561399 +vt 0.628274 0.581967 +vt 0.511020 0.847430 +vt 0.533908 0.850607 +vt 0.633815 0.551490 +vt 0.613046 0.571327 +vt 0.530368 0.831407 +vt 0.501394 0.842435 +vt 0.626589 0.538875 +vt 0.604527 0.544684 +vt 0.508929 0.810914 +vt 0.492547 0.829318 +vt 0.618247 0.522587 +vt 0.602583 0.501781 +vt 0.480939 0.813120 +vt 0.469234 0.787943 +vt 0.616652 0.502716 +vt 0.613925 0.497595 +vt 0.459358 0.796431 +vt 0.462840 0.801566 +vt 0.644899 0.511966 +vt 0.630336 0.517087 +vt 0.628893 0.504351 +vt 0.635735 0.498392 +vt 0.458270 0.813966 +vt 0.469630 0.821874 +vt 0.457144 0.833207 +vt 0.449054 0.817297 +vt 0.637359 0.534149 +vt 0.654293 0.524569 +vt 0.464258 0.849211 +vt 0.482600 0.837505 +vt 0.644187 0.548520 +vt 0.659377 0.540935 +vt 0.478087 0.863369 +vt 0.493557 0.851414 +vt 0.597230 0.539263 +vt 0.595257 0.495349 +vt 0.466971 0.777596 +vt 0.507407 0.801398 +vt 0.605628 0.572478 +vt 0.534801 0.825096 +vt 0.627145 0.592333 +vt 0.544318 0.853620 +vt 0.651887 0.586528 +vt 0.528822 0.875551 +vt 0.665532 0.557472 +vt 0.492878 0.878439 +vt 0.669345 0.535984 +vt 0.467321 0.871200 +vt 0.612569 0.491986 +vt 0.454710 0.792385 +vt 0.619277 0.495381 +vt 0.454636 0.800448 +vt 0.628580 0.496763 +vt 0.451294 0.809743 +vt 0.636682 0.490206 +vt 0.440853 0.813605 +vt 0.652342 0.504728 +vt 0.446182 0.836397 +vt 0.664409 0.519225 +vt 0.453285 0.856119 +vt 0.666191 0.492411 +vt 0.717596 0.474672 +vt 0.382398 0.879324 +vt 0.427166 0.842398 +vt 0.681733 0.511408 +vt 0.427493 0.877628 +vt 0.435523 0.867805 +vt 0.685777 0.532869 +vt 0.453231 0.887054 +vt 0.588528 0.478377 +vt 0.454313 0.762782 +vt 0.446975 0.900429 +vt 0.713425 0.237886 +vt 0.709019 0.215724 +vt 0.755152 0.224403 +vt 0.762923 0.242445 +vt 0.327574 0.621771 +vt 0.281440 0.630451 +vt 0.285847 0.608289 +vt 0.335345 0.603729 +vt 0.576794 0.465515 +vt 0.583867 0.423087 +vt 0.405805 0.730353 +vt 0.448347 0.745304 +vt 0.686035 0.253032 +vt 0.258456 0.593142 +vt 0.683851 0.556229 +vt 0.482266 0.899349 +vt 0.670531 0.597684 +vt 0.532990 0.898426 +vt 0.630909 0.604157 +vt 0.553941 0.861896 +vt 0.596864 0.576275 +vt 0.542184 0.818594 +vt 0.585561 0.529242 +vt 0.503791 0.785451 +vt 0.572425 0.529736 +vt 0.510638 0.773572 +vt 0.587548 0.588270 +vt 0.557294 0.815416 +vt 0.629961 0.623919 +vt 0.572425 0.868524 +vt 0.548104 0.914571 +vt 0.488130 0.914571 +vt 0.658830 0.266292 +vt 0.631691 0.281488 +vt 0.204112 0.564686 +vt 0.231252 0.579881 +vt 0.706402 0.288928 +vt 0.278823 0.557246 +vt 0.743528 0.317934 +vt 0.752264 0.346660 +vt 0.324686 0.499513 +vt 0.315950 0.528240 +vt 0.743309 0.289810 +vt 0.315731 0.556363 +vt 0.700326 0.147967 +vt 0.272746 0.698208 +vt 0.795874 0.266472 +vt 0.775660 0.289442 +vt 0.757507 0.263314 +vt 0.348083 0.556732 +vt 0.329929 0.582860 +vt 0.368297 0.579702 +vt 0.804056 0.232825 +vt 0.376478 0.613349 +vt 0.810124 0.179100 +vt 0.382547 0.667075 +vt 0.753847 0.157090 +vt 0.811201 0.146834 +vt 0.383624 0.699341 +vt 0.326269 0.689085 +vt 0.879685 0.183943 +vt 0.888071 0.157228 +vt 0.460496 0.688946 +vt 0.452109 0.662231 +vt 0.925222 0.140531 +vt 0.947451 0.149372 +vt 0.519876 0.696801 +vt 0.497647 0.705643 +vt 0.876420 0.258223 +vt 0.946138 0.286262 +vt 0.518561 0.559910 +vt 0.448843 0.587951 +vt 0.829953 0.196170 +vt 0.837053 0.152275 +vt 0.409477 0.693900 +vt 0.402377 0.650004 +vt 0.829888 0.255993 +vt 0.402311 0.590181 +vt 0.852096 0.297194 +vt 0.813695 0.289418 +vt 0.424519 0.548979 +vt 0.386117 0.556756 +vt 0.820842 0.328587 +vt 0.789451 0.311961 +vt 0.393264 0.517587 +vt 0.361873 0.534212 +vt 0.840465 0.403536 +vt 0.762603 0.423087 +vt 0.412887 0.442637 +vt 0.335024 0.423087 +vt 0.909248 0.345901 +vt 0.481670 0.500271 +vt 0.676670 0.402805 +vt 0.249092 0.443369 +vt 0.573469 0.193539 +vt 0.579214 0.151927 +vt 0.151632 0.694246 +vt 0.145888 0.652633 +vt 0.546919 0.227092 +vt 0.536510 0.214419 +vt 0.119340 0.619080 +vt 0.108931 0.631753 +vt 0.588792 0.317539 +vt 0.161214 0.528634 +vt 0.630429 0.371564 +vt 0.202851 0.474609 +vt 0.657494 0.118541 +vt 0.164237 0.319427 +vt 0.169464 0.304721 +vt 0.210459 0.345510 +vt 0.169574 0.118572 +vt 0.164356 0.103821 +vt 0.210731 0.077759 +vt 0.229913 0.727634 +vt 0.589956 0.115821 +vt 0.153468 0.300432 +vt 0.153526 0.122857 +vt 0.162374 0.730353 +vt 0.578472 0.119429 +vt 0.553653 0.120209 +vt 0.126070 0.725964 +vt 0.150890 0.726744 +vt 0.546510 0.159800 +vt 0.509384 0.119033 +vt 0.081800 0.727137 +vt 0.118929 0.686371 +vt 0.534072 0.185482 +vt 0.106492 0.660689 +vt 0.462352 0.161885 +vt 0.478174 0.145123 +vt 0.493641 0.175543 +vt 0.505521 0.150780 +vt 0.077939 0.695390 +vt 0.050592 0.701044 +vt 0.066060 0.670626 +vt 0.034770 0.684282 +vt 0.476706 0.124129 +vt 0.049122 0.722039 +vt 0.465324 0.131169 +vt 0.037741 0.714998 +vt 0.446348 0.149671 +vt 0.018765 0.696495 +vt 0.445483 0.184898 +vt 0.427581 0.175095 +vt 0.000000 0.671069 +vt 0.017903 0.661268 +vt 0.480167 0.198327 +vt 0.052588 0.647841 +vt 0.521714 0.207472 +vt 0.094135 0.638699 +vt 0.701979 0.120236 +vt 0.274400 0.725940 +vt 0.757541 0.138176 +vt 0.329963 0.708000 +vt 0.817327 0.117813 +vt 0.389751 0.728363 +vt 0.844767 0.126748 +vt 0.417191 0.719428 +vt 0.893893 0.126476 +vt 0.466319 0.719698 +vt 0.936543 0.115821 +vt 0.508970 0.730353 +vt 0.965717 0.128368 +vt 0.538144 0.717805 +vt 0.989276 0.166159 +vt 0.561701 0.680013 +vt 1.000000 0.175243 +vt 0.572425 0.670929 +vt 0.289028 0.269037 +vt 0.283878 0.263049 +vt 0.299187 0.258321 +vt 0.300964 0.267357 +vt 0.299421 0.165436 +vt 0.284101 0.160633 +vt 0.289287 0.154655 +vt 0.301244 0.156393 +vt 0.317793 0.260767 +vt 0.316733 0.267304 +vt 0.318078 0.163079 +vt 0.317052 0.156521 +vt 0.335398 0.269583 +vt 0.330421 0.276220 +vt 0.335777 0.154335 +vt 0.330824 0.147649 +vt 0.278552 0.277080 +vt 0.273734 0.272912 +vt 0.273975 0.150706 +vt 0.278818 0.146548 +vt 0.271078 0.306358 +vt 0.264864 0.305818 +vt 0.265194 0.117691 +vt 0.271427 0.117166 +vt 0.278613 0.324240 +vt 0.274006 0.327477 +vt 0.274436 0.095993 +vt 0.279049 0.099253 +vt 0.298062 0.342565 +vt 0.294660 0.349561 +vt 0.295240 0.073895 +vt 0.298634 0.080932 +vt 0.312476 0.342961 +vt 0.315033 0.350198 +vt 0.315702 0.073322 +vt 0.313108 0.080584 +vt 0.323281 0.337709 +vt 0.328696 0.344302 +vt 0.329405 0.079293 +vt 0.323940 0.085897 +vt 0.335361 0.313857 +vt 0.339396 0.315576 +vt 0.340031 0.108187 +vt 0.335968 0.109893 +vt 0.339920 0.298303 +vt 0.345292 0.298556 +vt 0.345869 0.125306 +vt 0.340471 0.125531 +vt 0.339277 0.286081 +vt 0.344398 0.284332 +vt 0.344895 0.139582 +vt 0.339764 0.137799 +vt 0.345671 0.260159 +vt 0.355483 0.280619 +vt 0.356003 0.143373 +vt 0.346021 0.163854 +vt 0.356162 0.297750 +vt 0.356783 0.126174 +vt 0.349494 0.319809 +vt 0.350195 0.103982 +vt 0.333524 0.354692 +vt 0.334295 0.068869 +vt 0.317323 0.364551 +vt 0.318050 0.058911 +vt 0.293154 0.361782 +vt 0.293765 0.061619 +vt 0.263750 0.335417 +vt 0.264168 0.087998 +vt 0.251373 0.309082 +vt 0.251676 0.114380 +vt 0.264926 0.265507 +vt 0.265122 0.158092 +vt 0.278030 0.255522 +vt 0.278212 0.168150 +vt 0.320744 0.246538 +vt 0.320956 0.177355 +vt 0.296570 0.247318 +vt 0.296748 0.176443 +vt 0.038845 0.211743 +vt 0.047440 0.211734 +vt 0.055230 0.211728 +vt 0.057303 0.228458 +vt 0.057278 0.194991 +vt 0.041287 0.229096 +vt 0.041253 0.194380 +vt 0.032564 0.220061 +vt 0.032546 0.203437 +vt 0.030743 0.211752 +vt 0.029931 0.223131 +vt 0.028053 0.211756 +vt 0.029906 0.200372 +vt 0.038587 0.233067 +vt 0.038544 0.190412 +vt 0.061533 0.231825 +vt 0.061505 0.191616 +vt 0.057382 0.211726 +vt 0.168191 0.258703 +vt 0.213958 0.246887 +vt 0.214040 0.176591 +vt 0.168236 0.164676 +vt 0.148297 0.258447 +vt 0.138777 0.299079 +vt 0.138791 0.124216 +vt 0.148319 0.164919 +vt 0.115455 0.259296 +vt 0.109657 0.296761 +vt 0.109611 0.126556 +vt 0.115440 0.164070 +vt 0.119233 0.228698 +vt 0.156540 0.233552 +vt 0.156556 0.189842 +vt 0.119230 0.194690 +vt 0.173998 0.244074 +vt 0.174035 0.179329 +vt 0.195860 0.238258 +vt 0.195909 0.185188 +vt 0.203534 0.211734 +vt 0.252997 0.211802 +vt 0.171285 0.225095 +vt 0.164455 0.211704 +vt 0.180017 0.211713 +vt 0.177113 0.227468 +vt 0.171300 0.198319 +vt 0.177134 0.195952 +vt 0.185539 0.227013 +vt 0.187516 0.221322 +vt 0.187531 0.202116 +vt 0.185563 0.196419 +vt 0.176585 0.232500 +vt 0.165993 0.229894 +vt 0.176611 0.190916 +vt 0.166011 0.193512 +vt 0.189406 0.230672 +vt 0.189438 0.192766 +vt 0.193574 0.221791 +vt 0.193592 0.201656 +vt 0.186479 0.211718 +vt 0.156919 0.211701 +vt 0.148476 0.211699 +vt 0.427853 0.115821 +vt 0.427581 0.104121 +vt 0.441185 0.104121 +vt 0.427581 0.011703 +vt 0.427581 0.000000 +vt 0.441181 0.011386 +vt 0.067509 0.234045 +vt 0.071465 0.211716 +vt 0.067479 0.189385 +vt 0.119764 0.211696 +vt 0.060932 0.261035 +vt 0.038121 0.261699 +vt 0.038025 0.161756 +vt 0.060860 0.162382 +vt 0.019864 0.255578 +vt 0.019760 0.167921 +vt 0.016617 0.242679 +vt 0.016537 0.180842 +vt 0.014466 0.211775 +vt 0.297831 0.211892 +vt 0.340508 0.212027 +vt 0.356498 0.241635 +vt 0.356742 0.182510 +vt 0.236517 0.317748 +vt 0.236802 0.105655 +vt 0.264789 0.363401 +vt 0.265286 0.059917 +vt 0.296951 0.385966 +vt 0.297650 0.037339 +vt 0.337996 0.385300 +vt 0.338890 0.038126 +vt 0.349401 0.368365 +vt 0.350300 0.055183 +vt 0.377282 0.319664 +vt 0.378129 0.104260 +vt 0.394788 0.292204 +vt 0.395576 0.131978 +vt 0.391029 0.270263 +vt 0.391643 0.154015 +vt 0.368661 0.212151 +vt 0.379482 0.228055 +vt 0.379686 0.196331 +vt 0.420379 0.261837 +vt 0.421104 0.162716 +vt 0.426533 0.298960 +vt 0.427581 0.125377 +vt 0.396664 0.342212 +vt 0.397734 0.081667 +vt 0.365156 0.387054 +vt 0.366203 0.036443 +vt 0.346744 0.416452 +vt 0.347768 0.006839 +vt 0.278009 0.423087 +vt 0.278714 0.000000 +vt 0.241964 0.376122 +vt 0.242399 0.047096 +vt 0.055563 0.291878 +vt 0.055443 0.131506 +vt 0.014495 0.288026 +vt 0.014318 0.135436 +vt 0.003828 0.279132 +vt 0.003650 0.144368 +vt 0.000113 0.248111 +vt 0.000000 0.175447 +vt 0.000000 0.211799 +vt 0.046962 0.798865 +vt 0.047306 0.784561 +vt 0.334495 0.786358 +vt 0.334204 0.800664 +vt 0.058429 0.773633 +vt 0.323868 0.774947 +vt 0.072992 0.774071 +vt 0.309301 0.774739 +vt 0.084403 0.784016 +vt 0.297459 0.784168 +vt 0.083417 0.800146 +vt 0.297728 0.800325 +vt 0.073091 0.810538 +vt 0.307582 0.811166 +vt 0.057505 0.810093 +vt 0.323173 0.811412 +vt 0.024988 0.807478 +vt 0.047717 0.829014 +vt 0.332112 0.830749 +vt 0.355774 0.810244 +vt 0.000000 0.817350 +vt 0.033121 0.852785 +vt 0.345638 0.855146 +vt 0.380299 0.821215 +vt 0.083391 0.855019 +vt 0.078555 0.829097 +vt 0.301299 0.829463 +vt 0.295318 0.855146 +vt 0.100718 0.807888 +vt 0.280100 0.807291 +vt 0.123146 0.821929 +vt 0.257070 0.820323 +vt 0.127501 0.768220 +vt 0.103229 0.776171 +vt 0.279000 0.775494 +vt 0.255105 0.766472 +vt 0.079351 0.756089 +vt 0.303746 0.756492 +vt 0.089008 0.730353 +vt 0.295241 0.730353 +vt 0.049398 0.755271 +vt 0.035422 0.733227 +vt 0.333706 0.757005 +vt 0.348646 0.735604 +vt 0.026877 0.776230 +vt 0.355274 0.778943 +vt 0.000000 0.770061 +vt 0.382398 0.773973 +vn 0.189764 -0.003571 0.981811 +vn 0.646809 -0.758202 0.082095 +vn 0.999573 -0.014496 -0.024445 +vn -0.999573 -0.014496 -0.024445 +vn -0.646809 -0.758202 0.082095 +vn -0.189764 -0.003571 0.981811 +vn -0.085788 -0.982971 0.162389 +vn 0.085788 -0.982971 0.162389 +vn -0.744835 -0.623768 0.236824 +vn 0.744835 -0.623768 0.236824 +vn -0.870968 -0.014710 0.491104 +vn 0.870968 -0.014710 0.491104 +vn -0.758354 0.606128 0.239692 +vn 0.758354 0.606128 0.239692 +vn -0.085788 0.982513 0.165105 +vn 0.085788 0.982513 0.165105 +vn 0.655141 0.750633 0.085574 +vn -0.655141 0.750633 0.085574 +vn -0.349284 -0.719932 0.599719 +vn -0.173681 0.215735 0.960845 +vn -0.809839 0.388287 0.439741 +vn 0.809839 0.388287 0.439741 +vn 0.173681 0.215735 0.960845 +vn 0.349284 -0.719932 0.599719 +vn 0.000000 0.794183 0.607654 +vn -0.508652 0.858119 -0.069887 +vn 0.000000 0.487075 0.873348 +vn 0.508652 0.858119 -0.069887 +vn 0.981414 -0.186682 0.043947 +vn 0.569811 -0.821711 0.007813 +vn 0.563463 -0.814570 0.137669 +vn -0.563463 -0.814570 0.137669 +vn -0.569811 -0.821711 0.007813 +vn -0.981414 -0.186682 0.043947 +vn 0.475845 -0.876247 0.075381 +vn 0.850520 -0.525529 -0.020692 +vn 0.876949 -0.163823 0.451766 +vn -0.876949 -0.163823 0.451766 +vn -0.850520 -0.525529 -0.020692 +vn -0.475845 -0.876247 0.075381 +vn 0.448286 -0.367870 -0.814661 +vn 0.530534 -0.539445 -0.653829 +vn 0.513077 -0.674673 -0.530595 +vn -0.513077 -0.674673 -0.530595 +vn -0.530534 -0.539445 -0.653829 +vn -0.448286 -0.367870 -0.814661 +vn 0.888180 -0.439955 -0.132389 +vn 0.588519 0.226966 0.775933 +vn 0.911527 -0.115268 0.394665 +vn -0.911527 -0.115268 0.394665 +vn -0.588519 0.226966 0.775933 +vn -0.888180 -0.439955 -0.132389 +vn 0.468886 -0.304727 0.829005 +vn 0.251564 0.260781 0.932005 +vn -0.003082 -0.330882 0.943632 +vn 0.003082 -0.330882 0.943632 +vn -0.251564 0.260781 0.932005 +vn -0.468886 -0.304727 0.829005 +vn 0.473067 0.578997 -0.664022 +vn 0.992462 0.028626 -0.118900 +vn 0.459975 -0.380261 -0.802362 +vn -0.459975 -0.380261 -0.802362 +vn -0.992462 0.028626 -0.118900 +vn -0.473067 0.578997 -0.664022 +vn -0.059908 -0.804712 -0.590594 +vn -0.346141 -0.637287 -0.688498 +vn -0.330546 -0.943236 0.031281 +vn -0.073672 -0.594989 0.800317 +vn 0.330546 -0.943236 0.031281 +vn 0.346141 -0.637287 -0.688498 +vn 0.059908 -0.804712 -0.590594 +vn 0.073672 -0.594989 0.800317 +vn 0.593738 0.595264 -0.541368 +vn -0.626057 -0.002686 -0.779748 +vn 0.626057 -0.002686 -0.779748 +vn -0.593738 0.595264 -0.541368 +vn 0.127689 0.703757 0.698843 +vn -0.713828 0.382183 0.586810 +vn 0.713828 0.382183 0.586810 +vn -0.127689 0.703757 0.698843 +vn 0.378063 0.560045 -0.737144 +vn 0.036805 -0.708457 -0.704764 +vn -0.378063 0.560045 -0.737144 +vn -0.036805 -0.708457 -0.704764 +vn -0.031556 0.838710 0.543626 +vn 0.031556 0.838710 0.543626 +vn -0.361156 0.848689 0.386303 +vn 0.361156 0.848689 0.386303 +vn -0.716392 0.204474 0.667043 +vn 0.716392 0.204474 0.667043 +vn -0.662038 -0.413770 0.624866 +vn 0.662038 -0.413770 0.624866 +vn -0.530229 -0.655751 0.537370 +vn 0.530229 -0.655751 0.537370 +vn -0.437483 0.001221 0.899197 +vn 0.550981 -0.138096 0.822993 +vn 0.437483 0.001221 0.899197 +vn -0.550981 -0.138096 0.822993 +vn -0.315958 -0.102298 0.943205 +vn 0.608539 0.296121 0.736167 +vn -0.608539 0.296121 0.736167 +vn 0.315958 -0.102298 0.943205 +vn -0.445479 -0.088778 0.890866 +vn -0.257698 0.600024 0.757317 +vn 0.257698 0.600024 0.757317 +vn 0.445479 -0.088778 0.890866 +vn -0.327799 0.169927 0.929319 +vn 0.041780 0.927213 0.372112 +vn 0.327799 0.169927 0.929319 +vn -0.041780 0.927213 0.372112 +vn -0.277932 0.260201 0.924680 +vn -0.750725 0.111545 0.651112 +vn 0.750725 0.111545 0.651112 +vn 0.277932 0.260201 0.924680 +vn -0.437910 -0.293985 0.849574 +vn -0.183782 0.036836 0.982269 +vn -0.554216 0.387219 0.736808 +vn -0.814325 0.253426 0.522111 +vn 0.554216 0.387219 0.736808 +vn 0.183782 0.036836 0.982269 +vn 0.437910 -0.293985 0.849574 +vn 0.814325 0.253426 0.522111 +vn -0.326670 -0.001617 0.945128 +vn -0.704337 -0.526872 0.475692 +vn 0.704337 -0.526872 0.475692 +vn 0.326670 -0.001617 0.945128 +vn -0.308786 0.134617 0.941527 +vn -0.629170 -0.371441 0.682730 +vn 0.629170 -0.371441 0.682730 +vn 0.308786 0.134617 0.941527 +vn 0.146184 0.948637 0.280465 +vn -0.137516 0.905820 0.400708 +vn 0.137516 0.905820 0.400708 +vn -0.146184 0.948637 0.280465 +vn 0.723746 0.690023 -0.005219 +vn -0.723746 0.690023 -0.005219 +vn 0.994690 -0.078005 0.067019 +vn -0.994690 -0.078005 0.067019 +vn 0.200934 -0.758141 0.620350 +vn -0.200934 -0.758141 0.620350 +vn -0.541246 -0.672658 0.504501 +vn 0.541246 -0.672658 0.504501 +vn -0.690054 -0.553209 0.466628 +vn 0.690054 -0.553209 0.466628 +vn -0.464003 0.686666 0.559557 +vn 0.464003 0.686666 0.559557 +vn -0.827448 -0.135899 0.544786 +vn 0.827448 -0.135899 0.544786 +vn -0.466231 0.808863 0.358196 +vn 0.466231 0.808863 0.358196 +vn -0.743980 -0.022919 0.667776 +vn 0.743980 -0.022919 0.667776 +vn -0.711295 -0.638325 0.294137 +vn 0.711295 -0.638325 0.294137 +vn -0.709769 -0.501999 0.494125 +vn 0.709769 -0.501999 0.494125 +vn -0.818903 -0.425520 0.385113 +vn -0.992523 -0.071444 -0.098758 +vn 0.992523 -0.071444 -0.098758 +vn 0.818903 -0.425520 0.385113 +vn -0.439192 -0.273568 0.855708 +vn 0.439192 -0.273568 0.855708 +vn -0.414686 -0.059877 0.907956 +vn 0.414686 -0.059877 0.907956 +vn -0.341563 0.452132 0.823939 +vn 0.341563 0.452132 0.823939 +vn -0.724509 -0.684927 0.076632 +vn -0.987548 -0.123020 0.097995 +vn 0.987548 -0.123020 0.097995 +vn 0.724509 -0.684927 0.076632 +vn -0.572741 -0.088443 0.814936 +vn 0.572741 -0.088443 0.814936 +vn -0.291818 -0.152104 0.944273 +vn 0.291818 -0.152104 0.944273 +vn 0.239662 -0.128605 0.962279 +vn -0.239662 -0.128605 0.962279 +vn 0.187017 0.370678 0.909696 +vn -0.187017 0.370678 0.909696 +vn -0.455794 0.423170 0.783044 +vn 0.455794 0.423170 0.783044 +vn -0.543504 -0.813379 -0.207343 +vn -0.560045 -0.814417 -0.151738 +vn 0.560045 -0.814417 -0.151738 +vn 0.543504 -0.813379 -0.207343 +vn -0.615375 -0.087649 -0.783319 +vn -0.447310 0.229530 -0.864406 +vn 0.447310 0.229530 -0.864406 +vn 0.615375 -0.087649 -0.783319 +vn -0.547166 -0.832179 -0.089785 +vn 0.547166 -0.832179 -0.089785 +vn -0.873135 0.486984 -0.020264 +vn -0.865352 0.331217 -0.376049 +vn 0.865352 0.331217 -0.376049 +vn 0.873135 0.486984 -0.020264 +vn -0.748741 0.518387 0.413038 +vn 0.748741 0.518387 0.413038 +vn -0.766167 0.634816 0.099612 +vn 0.766167 0.634816 0.099612 +vn -0.953185 -0.248299 -0.172430 +vn -0.665639 0.602496 -0.440321 +vn 0.665639 0.602496 -0.440321 +vn 0.953185 -0.248299 -0.172430 +vn -0.322642 0.847713 0.421033 +vn -0.188574 0.788934 -0.584765 +vn 0.188574 0.788934 -0.584765 +vn 0.322642 0.847713 0.421033 +vn -0.239784 0.745262 -0.622120 +vn 0.494247 0.520585 -0.696158 +vn -0.494247 0.520585 -0.696158 +vn 0.239784 0.745262 -0.622120 +vn -0.480697 0.731223 0.483932 +vn 0.000000 0.758690 0.651418 +vn 0.480697 0.731223 0.483932 +vn -0.489242 0.762963 0.422498 +vn -0.363109 0.908567 -0.206458 +vn 0.363109 0.908567 -0.206458 +vn 0.489242 0.762963 0.422498 +vn -0.645039 0.694540 0.318613 +vn 0.645039 0.694540 0.318613 +vn -0.492843 0.869015 0.043062 +vn -0.679434 0.728965 -0.083468 +vn 0.492843 0.869015 0.043062 +vn 0.679434 0.728965 -0.083468 +vn -0.391736 0.826014 -0.405225 +vn -0.644398 0.527207 -0.553880 +vn 0.391736 0.826014 -0.405225 +vn 0.644398 0.527207 -0.553880 +vn 0.000000 0.800714 -0.599017 +vn 0.000000 0.330729 -0.943693 +vn 0.000000 0.999664 0.025636 +vn 0.000000 -0.271462 -0.962432 +vn -0.685293 -0.583148 -0.436232 +vn -0.907224 0.252602 -0.336253 +vn 0.907224 0.252602 -0.336253 +vn 0.685293 -0.583148 -0.436232 +vn 0.000000 -0.984344 -0.176214 +vn 0.000000 -0.736351 -0.676565 +vn 0.000000 -0.948759 -0.315928 +vn 0.000000 -0.648244 -0.761406 +vn -0.317362 -0.946959 -0.049959 +vn -0.838282 -0.408155 0.361461 +vn 0.838282 -0.408155 0.361461 +vn 0.317362 -0.946959 -0.049959 +vn -0.939360 0.325999 0.106113 +vn 0.939360 0.325999 0.106113 +vn -0.930631 0.340159 0.134770 +vn -0.960143 0.231361 0.156774 +vn 0.960143 0.231361 0.156774 +vn 0.930631 0.340159 0.134770 +vn -0.812555 -0.001068 -0.582842 +vn -0.979583 0.093387 0.177862 +vn 0.979583 0.093387 0.177862 +vn 0.812555 -0.001068 -0.582842 +vn -0.272530 -0.301157 -0.913785 +vn 0.272530 -0.301157 -0.913785 +vn -0.090915 -0.776330 -0.623707 +vn -0.506851 -0.488144 -0.710471 +vn -0.142521 -0.147282 -0.978759 +vn -0.637257 0.093326 -0.764946 +vn 0.637257 0.093326 -0.764946 +vn 0.506851 -0.488144 -0.710471 +vn 0.142521 -0.147282 -0.978759 +vn 0.090915 -0.776330 -0.623707 +vn -0.937284 -0.254250 0.238350 +vn 0.937284 -0.254250 0.238350 +vn -0.430525 -0.895260 0.114597 +vn 0.430525 -0.895260 0.114597 +vn -0.158391 -0.974822 0.156774 +vn 0.158391 -0.974822 0.156774 +vn 0.000000 -0.915860 -0.401440 +vn 0.000000 -0.946440 0.322855 +vn 0.000000 -0.336802 -0.941557 +vn 0.000000 -0.175726 -0.984436 +vn -0.599231 -0.773980 0.204566 +vn 0.599231 -0.773980 0.204566 +vn -0.890988 -0.423261 -0.164037 +vn 0.890988 -0.423261 -0.164037 +vn -0.851985 0.219275 0.475387 +vn 0.851985 0.219275 0.475387 +vn -0.509171 0.852229 0.119999 +vn 0.509171 0.852229 0.119999 +vn -0.610431 0.759148 0.225867 +vn 0.610431 0.759148 0.225867 +vn -0.182470 0.981780 0.052492 +vn 0.182470 0.981780 0.052492 +vn 0.520371 0.770348 0.368389 +vn -0.520371 0.770348 0.368389 +vn 0.852718 0.504257 0.136204 +vn -0.852718 0.504257 0.136204 +vn 0.000000 0.970214 0.242164 +vn -0.709647 0.261818 0.654042 +vn 0.067293 -0.064272 0.995636 +vn -0.246590 -0.034089 0.968505 +vn -0.809717 -0.010224 0.586688 +vn 0.246590 -0.034089 0.968505 +vn -0.067293 -0.064272 0.995636 +vn 0.709647 0.261818 0.654042 +vn 0.809717 -0.010224 0.586688 +vn -0.465835 -0.080325 0.881191 +vn -0.737114 -0.244179 0.630085 +vn 0.465835 -0.080325 0.881191 +vn 0.737114 -0.244179 0.630085 +vn -0.211951 -0.085971 0.973479 +vn -0.367504 -0.376476 0.850398 +vn 0.211951 -0.085971 0.973479 +vn 0.367504 -0.376476 0.850398 +vn -0.430280 0.556597 0.710624 +vn -0.020081 -0.072939 0.997131 +vn 0.020081 -0.072939 0.997131 +vn 0.430280 0.556597 0.710624 +vn -0.090976 0.597339 0.796777 +vn -0.187933 -0.091617 0.977874 +vn 0.187933 -0.091617 0.977874 +vn 0.090976 0.597339 0.796777 +vn 0.165929 0.609363 0.775292 +vn -0.203314 0.092532 0.974700 +vn 0.203314 0.092532 0.974700 +vn -0.165929 0.609363 0.775292 +vn 0.269295 0.241676 0.932218 +vn -0.314219 -0.132420 0.940062 +vn 0.314219 -0.132420 0.940062 +vn -0.269295 0.241676 0.932218 +vn 0.420057 -0.118992 0.899625 +vn -0.119755 -0.070925 0.990234 +vn 0.119755 -0.070925 0.990234 +vn -0.420057 -0.118992 0.899625 +vn 0.226142 -0.606586 0.762139 +vn -0.320841 0.040712 0.946226 +vn 0.320841 0.040712 0.946226 +vn -0.226142 -0.606586 0.762139 +vn 0.232612 -0.746055 0.623890 +vn -0.074557 -0.391644 0.917081 +vn 0.074557 -0.391644 0.917081 +vn -0.232612 -0.746055 0.623890 +vn -0.121250 -0.313883 0.941679 +vn -0.146702 -0.035707 0.988525 +vn 0.146702 -0.035707 0.988525 +vn 0.121250 -0.313883 0.941679 +vn -0.216834 -0.273721 0.937010 +vn -0.187445 0.001160 0.982269 +vn 0.187445 0.001160 0.982269 +vn 0.216834 -0.273721 0.937010 +vn -0.303018 -0.201941 0.931333 +vn -0.253090 -0.161809 0.953795 +vn 0.253090 -0.161809 0.953795 +vn 0.303018 -0.201941 0.931333 +vn -0.140110 -0.091189 0.985900 +vn 0.140110 -0.091189 0.985900 +vn -0.237983 0.050172 0.969939 +vn 0.237983 0.050172 0.969939 +vn -0.312662 -0.237922 0.919553 +vn 0.312662 -0.237922 0.919553 +vn -0.373791 -0.105197 0.921506 +vn 0.373791 -0.105197 0.921506 +vn -0.470595 -0.164647 0.866817 +vn 0.470595 -0.164647 0.866817 +vn -0.439222 -0.376141 0.815821 +vn 0.439222 -0.376141 0.815821 +vn -0.219611 -0.540635 0.812037 +vn 0.219611 -0.540635 0.812037 +vn 0.166967 -0.374828 0.911893 +vn -0.166967 -0.374828 0.911893 +vn 0.201849 -0.277596 0.939238 +vn -0.201849 -0.277596 0.939238 +vn 0.001160 -0.165563 0.986175 +vn -0.001160 -0.165563 0.986175 +vn 0.292917 -0.174108 0.940123 +vn -0.292917 -0.174108 0.940123 +vn 0.000000 0.732200 0.681051 +vn 0.000000 -0.603626 0.797266 +vn 0.000000 -0.971740 0.235908 +vn 0.131779 -0.608295 0.782678 +vn -0.131779 -0.608295 0.782678 +vn 0.759117 0.068392 0.647298 +vn -0.759117 0.068392 0.647298 +vn 0.405957 0.643605 0.648793 +vn -0.405957 0.643605 0.648793 +vn 0.000000 0.598346 0.801202 +vn 0.073855 -0.330546 0.940855 +vn 0.000000 -0.124516 0.992187 +vn -0.073855 -0.330546 0.940855 +vn -0.085116 -0.339244 0.936827 +vn 0.085116 -0.339244 0.936827 +vn -0.141881 -0.148350 0.978698 +vn 0.141881 -0.148350 0.978698 +vn 0.000000 -0.482803 0.875698 +vn -0.692984 -0.001343 0.720908 +vn -0.095523 -0.326090 0.940489 +vn 0.095523 -0.326090 0.940489 +vn 0.692984 -0.001343 0.720908 +vn -0.646687 0.162603 0.745201 +vn 0.646687 0.162603 0.745201 +vn -0.593463 0.121860 0.795556 +vn 0.593463 0.121860 0.795556 +vn -0.124363 0.009674 0.992187 +vn -0.509995 -0.457717 0.728233 +vn 0.509995 -0.457717 0.728233 +vn 0.124363 0.009674 0.992187 +vn -0.972137 -0.167882 0.163549 +vn 0.972137 -0.167882 0.163549 +vn -0.715995 0.572161 0.399945 +vn 0.715995 0.572161 0.399945 +vn 0.000000 0.430525 0.902554 +vn 0.000000 0.010865 0.999939 +vn -0.221839 -0.606037 0.763848 +vn 0.000000 -0.492935 0.870022 +vn 0.000000 0.010315 0.999939 +vn -0.294320 -0.184484 0.937712 +vn 0.221839 -0.606037 0.763848 +vn 0.294320 -0.184484 0.937712 +vn -0.396924 0.534989 0.745781 +vn 0.247780 0.568224 0.784661 +vn -0.247780 0.568224 0.784661 +vn 0.396924 0.534989 0.745781 +vn -0.868221 -0.261330 0.421735 +vn -0.555986 -0.690695 0.462355 +vn 0.868221 -0.261330 0.421735 +vn 0.555986 -0.690695 0.462355 +vn -0.753075 0.649892 0.102298 +vn 0.753075 0.649892 0.102298 +vn 0.194189 0.935697 0.294473 +vn -0.194189 0.935697 0.294473 +vn 0.000000 0.788965 0.614399 +vn 0.000000 -0.888638 0.458571 +vn 0.000000 -0.336772 0.941557 +vn 0.000000 -0.251991 0.967711 +vn -0.188360 -0.040132 0.981262 +vn 0.000000 -0.032899 0.999451 +vn 0.188360 -0.040132 0.981262 +vn 0.000000 0.000000 1.000000 +vn -0.572039 -0.018708 0.820002 +vn -0.536332 -0.212409 0.816828 +vn 0.536332 -0.212409 0.816828 +vn 0.572039 -0.018708 0.820002 +vn -0.357707 -0.638325 0.681570 +vn 0.357707 -0.638325 0.681570 +vn -0.154302 -0.754112 0.638325 +vn 0.154302 -0.754112 0.638325 +vn 0.000000 -0.743461 0.668752 +vn 0.000000 -0.189123 0.981933 +vn 0.000000 -0.114475 0.993408 +vn 0.001404 -0.055635 0.998444 +vn -0.001404 -0.055635 0.998444 +vn -0.336283 -0.512833 0.789850 +vn 0.336283 -0.512833 0.789850 +vn -0.454543 -0.337077 0.824458 +vn 0.454543 -0.337077 0.824458 +vn -0.543474 -0.308603 0.780602 +vn 0.543474 -0.308603 0.780602 +vn -0.387158 -0.187811 0.902646 +vn 0.387158 -0.187811 0.902646 +vn -0.430647 -0.144902 0.890805 +vn 0.430647 -0.144902 0.890805 +vn -0.234016 -0.120548 0.964721 +vn 0.234016 -0.120548 0.964721 +vn -0.263833 0.168798 0.949675 +vn 0.263833 0.168798 0.949675 +vn 0.196722 0.141881 0.970122 +vn -0.196722 0.141881 0.970122 +vn -0.906766 -0.008332 0.421522 +vn -0.744133 -0.640919 0.188269 +vn 0.744133 -0.640919 0.188269 +vn 0.906766 -0.008332 0.421522 +vn -0.044191 -0.974395 0.220313 +vn 0.044191 -0.974395 0.220313 +vn 0.639943 -0.761498 0.102786 +vn -0.639943 -0.761498 0.102786 +vn 0.955504 -0.011444 0.294717 +vn -0.955504 -0.011444 0.294717 +vn 0.649678 0.754387 0.093570 +vn -0.649678 0.754387 0.093570 +vn -0.037049 0.978881 0.200903 +vn 0.037049 0.978881 0.200903 +vn -0.752342 0.635395 0.173742 +vn 0.752342 0.635395 0.173742 +vn -0.811792 -0.002777 0.583880 +vn -0.596942 0.486770 0.637684 +vn 0.596942 0.486770 0.637684 +vn 0.811792 -0.002777 0.583880 +vn -0.868221 -0.005829 0.496109 +vn -0.719504 0.473006 0.508469 +vn 0.719504 0.473006 0.508469 +vn 0.868221 -0.005829 0.496109 +vn -0.204260 0.828761 0.520951 +vn -0.095767 0.717277 0.690146 +vn 0.095767 0.717277 0.690146 +vn 0.204260 0.828761 0.520951 +vn 0.451704 0.459883 0.764458 +vn -0.451704 0.459883 0.764458 +vn 0.450362 0.693899 0.561815 +vn -0.450362 0.693899 0.561815 +vn 0.805536 0.109409 0.582324 +vn 0.691488 -0.074099 0.718558 +vn -0.691488 -0.074099 0.718558 +vn -0.805536 0.109409 0.582324 +vn 0.386212 -0.474685 0.790857 +vn -0.386212 -0.474685 0.790857 +vn 0.557756 -0.629109 0.541368 +vn -0.557756 -0.629109 0.541368 +vn -0.091159 -0.723716 0.684011 +vn -0.199744 -0.858058 0.473067 +vn 0.091159 -0.723716 0.684011 +vn 0.199744 -0.858058 0.473067 +vn -0.597949 -0.496475 0.629231 +vn 0.597949 -0.496475 0.629231 +vn -0.723197 -0.488907 0.487747 +vn 0.723197 -0.488907 0.487747 +usemtl Material_ray.png +s 1 +f 61/1/1 65/2/2 49/3/3 +f 50/4/4 66/5/5 62/6/6 +f 63/7/7 65/2/2 61/1/1 +f 62/6/6 66/5/5 64/8/8 +f 61/1/1 59/9/9 63/7/7 +f 64/8/8 60/10/10 62/6/6 +f 61/1/1 57/11/11 59/9/9 +f 60/10/10 58/12/12 62/6/6 +f 61/1/1 55/13/13 57/11/11 +f 58/12/12 56/14/14 62/6/6 +f 61/1/1 53/15/15 55/13/13 +f 56/14/14 54/16/16 62/6/6 +f 61/1/1 51/17/17 53/15/15 +f 54/16/16 52/18/18 62/6/6 +f 61/1/1 49/3/3 51/17/17 +f 52/18/18 50/4/4 62/6/6 +f 225/19/19 229/20/20 227/21/21 +f 228/22/22 230/23/23 226/24/24 +f 73/25/25 284/26/26 74/27/27 +f 74/28/27 285/29/28 73/30/25 +f 342/31/29 348/32/30 384/33/31 +f 385/34/32 349/35/33 343/36/34 +f 300/37/35 346/38/36 344/39/37 +f 345/40/38 347/41/39 301/42/40 +f 324/43/41 380/44/42 352/45/43 +f 353/46/44 381/47/45 325/48/46 +f 442/49/47 444/50/48 446/51/49 +f 447/52/50 445/53/51 443/54/52 +f 464/55/53 492/56/54 466/57/55 +f 467/58/56 493/59/57 465/60/58 +f 496/61/59 498/62/60 500/63/61 +f 501/64/62 499/65/63 497/66/64 +f 505/67/65 323/68/66 321/69/67 +f 505/67/65 321/69/67 391/70/68 +f 320/71/69 322/72/70 504/73/71 +f 320/71/69 504/73/71 390/74/72 +f 505/67/65 507/75/73 315/76/74 +f 505/67/65 315/76/74 323/68/66 +f 314/77/75 506/78/76 504/73/71 +f 314/77/75 504/73/71 322/72/70 +f 389/79/77 383/80/78 507/75/73 +f 383/80/78 315/76/74 507/75/73 +f 314/77/75 382/81/79 506/78/76 +f 382/81/79 388/82/80 506/78/76 +f 501/64/62 497/66/64 495/83/81 +f 501/64/62 495/83/81 503/84/82 +f 494/85/83 496/61/59 500/63/61 +f 494/85/83 500/63/61 502/86/84 +f 505/67/65 503/84/82 507/75/73 +f 503/84/82 495/83/81 507/75/73 +f 494/85/83 502/86/84 506/78/76 +f 502/86/84 504/73/71 506/78/76 +f 495/83/81 401/87/85 507/75/73 +f 401/87/85 389/79/77 507/75/73 +f 388/82/80 400/88/86 506/78/76 +f 400/88/86 494/85/83 506/78/76 +f 497/66/64 399/89/87 495/83/81 +f 399/89/87 401/87/85 495/83/81 +f 400/88/86 398/90/88 494/85/83 +f 398/90/88 496/61/59 494/85/83 +f 499/65/63 397/91/89 497/66/64 +f 397/91/89 399/89/87 497/66/64 +f 398/90/88 396/92/90 496/61/59 +f 396/92/90 498/62/60 496/61/59 +f 501/64/62 395/93/91 499/65/63 +f 395/93/91 397/91/89 499/65/63 +f 396/92/90 394/94/92 498/62/60 +f 394/94/92 500/63/61 498/62/60 +f 503/84/82 393/95/93 395/93/91 +f 503/84/82 395/93/91 501/64/62 +f 394/94/92 392/96/94 502/86/84 +f 394/94/92 502/86/84 500/63/61 +f 505/67/65 391/70/68 393/95/93 +f 505/67/65 393/95/93 503/84/82 +f 392/96/94 390/74/72 504/73/71 +f 392/96/94 504/73/71 502/86/84 +f 491/97/95 493/59/57 467/58/56 +f 491/97/95 467/58/56 469/98/96 +f 466/57/55 492/56/54 490/99/97 +f 466/57/55 490/99/97 468/100/98 +f 489/101/99 491/97/95 471/102/100 +f 491/97/95 469/98/96 471/102/100 +f 468/100/98 490/99/97 470/103/101 +f 490/99/97 488/104/102 470/103/101 +f 483/105/103 489/101/99 473/106/104 +f 489/101/99 471/102/100 473/106/104 +f 470/103/101 488/104/102 472/107/105 +f 488/104/102 482/108/106 472/107/105 +f 481/109/107 483/105/103 473/106/104 +f 481/109/107 473/106/104 475/110/108 +f 472/107/105 482/108/106 480/111/109 +f 472/107/105 480/111/109 474/112/110 +f 481/109/107 475/110/108 457/113/111 +f 475/110/108 455/114/112 457/113/111 +f 454/115/113 474/112/110 456/116/114 +f 474/112/110 480/111/109 456/116/114 +f 463/117/115 479/118/116 459/119/117 +f 463/117/115 459/119/117 461/120/118 +f 458/121/119 478/122/120 462/123/121 +f 458/121/119 462/123/121 460/124/122 +f 479/118/116 463/117/115 485/125/123 +f 463/117/115 453/126/124 485/125/123 +f 452/127/125 462/123/121 484/128/126 +f 462/123/121 478/122/120 484/128/126 +f 487/129/127 485/125/123 477/130/128 +f 485/125/123 453/126/124 477/130/128 +f 452/127/125 484/128/126 476/131/129 +f 484/128/126 486/132/130 476/131/129 +f 487/129/127 477/130/128 465/60/58 +f 487/129/127 465/60/58 493/59/57 +f 464/55/53 476/131/129 486/132/130 +f 464/55/53 486/132/130 492/56/54 +f 491/97/95 489/101/99 493/59/57 +f 489/101/99 487/129/127 493/59/57 +f 486/132/130 488/104/102 492/56/54 +f 488/104/102 490/99/97 492/56/54 +f 489/101/99 483/105/103 485/125/123 +f 489/101/99 485/125/123 487/129/127 +f 484/128/126 482/108/106 488/104/102 +f 484/128/126 488/104/102 486/132/130 +f 483/105/103 481/109/107 485/125/123 +f 481/109/107 479/118/116 485/125/123 +f 478/122/120 480/111/109 484/128/126 +f 480/111/109 482/108/106 484/128/126 +f 481/109/107 457/113/111 479/118/116 +f 457/113/111 459/119/117 479/118/116 +f 458/121/119 456/116/114 478/122/120 +f 456/116/114 480/111/109 478/122/120 +f 473/106/104 421/133/131 475/110/108 +f 421/133/131 419/134/132 475/110/108 +f 418/135/133 420/136/134 474/112/110 +f 420/136/134 472/107/105 474/112/110 +f 471/102/100 423/137/135 473/106/104 +f 423/137/135 421/133/131 473/106/104 +f 420/136/134 422/138/136 472/107/105 +f 422/138/136 470/103/101 472/107/105 +f 469/98/96 425/139/137 471/102/100 +f 425/139/137 423/137/135 471/102/100 +f 422/138/136 424/140/138 470/103/101 +f 424/140/138 468/100/98 470/103/101 +f 467/58/56 427/141/139 425/139/137 +f 467/58/56 425/139/137 469/98/96 +f 424/140/138 426/142/140 466/57/55 +f 424/140/138 466/57/55 468/100/98 +f 465/60/58 429/143/141 427/141/139 +f 465/60/58 427/141/139 467/58/56 +f 426/142/140 428/144/142 464/55/53 +f 426/142/140 464/55/53 466/57/55 +f 477/130/128 417/145/143 429/143/141 +f 477/130/128 429/143/141 465/60/58 +f 428/144/142 416/146/144 476/131/129 +f 428/144/142 476/131/129 464/55/53 +f 475/110/108 419/134/132 441/147/145 +f 475/110/108 441/147/145 455/114/112 +f 440/148/146 418/135/133 474/112/110 +f 440/148/146 474/112/110 454/115/113 +f 455/114/112 441/147/145 439/149/147 +f 455/114/112 439/149/147 457/113/111 +f 438/150/148 440/148/146 454/115/113 +f 438/150/148 454/115/113 456/116/114 +f 457/113/111 439/149/147 459/119/117 +f 439/149/147 437/151/149 459/119/117 +f 436/152/150 438/150/148 458/121/119 +f 438/150/148 456/116/114 458/121/119 +f 459/119/117 437/151/149 461/120/118 +f 437/151/149 435/153/151 461/120/118 +f 434/154/152 436/152/150 460/124/122 +f 436/152/150 458/121/119 460/124/122 +f 461/120/118 435/153/151 433/155/153 +f 461/120/118 433/155/153 463/117/115 +f 432/156/154 434/154/152 460/124/122 +f 432/156/154 460/124/122 462/123/121 +f 463/117/115 433/155/153 453/126/124 +f 433/155/153 451/157/155 453/126/124 +f 450/158/156 432/156/154 452/127/125 +f 432/156/154 462/123/121 452/127/125 +f 453/126/124 451/157/155 417/145/143 +f 453/126/124 417/145/143 477/130/128 +f 416/146/144 450/158/156 452/127/125 +f 416/146/144 452/127/125 476/131/129 +f 447/52/50 443/54/52 449/159/157 +f 443/54/52 313/160/158 449/159/157 +f 312/161/159 442/49/47 448/162/160 +f 442/49/47 446/51/49 448/162/160 +f 431/163/161 449/159/157 383/80/78 +f 449/159/157 313/160/158 383/80/78 +f 312/161/159 448/162/160 382/164/79 +f 448/162/160 430/165/162 382/164/79 +f 451/157/155 431/163/161 417/145/143 +f 431/163/161 415/166/163 417/145/143 +f 414/167/164 430/165/162 416/146/144 +f 430/165/162 450/158/156 416/146/144 +f 433/155/153 449/159/157 451/157/155 +f 449/159/157 431/163/161 451/157/155 +f 430/165/162 448/162/160 450/158/156 +f 448/162/160 432/156/154 450/158/156 +f 447/52/50 449/159/157 435/153/151 +f 449/159/157 433/155/153 435/153/151 +f 432/156/154 448/162/160 434/154/152 +f 448/162/160 446/51/49 434/154/152 +f 439/149/147 447/52/50 435/153/151 +f 439/149/147 435/153/151 437/151/149 +f 434/154/152 446/51/49 438/150/148 +f 434/154/152 438/150/148 436/152/150 +f 445/53/51 447/52/50 441/147/145 +f 447/52/50 439/149/147 441/147/145 +f 438/150/148 446/51/49 440/148/146 +f 446/51/49 444/50/48 440/148/146 +f 441/147/145 419/134/132 413/168/165 +f 441/147/145 413/168/165 445/53/51 +f 412/169/166 418/135/133 440/148/146 +f 412/169/166 440/148/146 444/50/48 +f 415/166/163 431/163/161 383/80/78 +f 415/166/163 383/80/78 389/79/77 +f 382/164/79 430/165/162 414/167/164 +f 382/164/79 414/167/164 388/170/80 +f 443/171/52 319/172/167 311/173/168 +f 443/171/52 311/173/168 313/174/158 +f 310/175/169 318/176/170 442/177/47 +f 310/175/169 442/177/47 312/178/159 +f 413/168/165 391/179/68 445/53/51 +f 391/179/68 321/180/67 445/53/51 +f 320/181/69 390/182/72 444/50/48 +f 390/182/72 412/169/166 444/50/48 +f 445/53/51 321/180/67 443/54/52 +f 321/183/67 319/172/167 443/171/52 +f 318/176/170 320/184/69 442/177/47 +f 320/181/69 444/50/48 442/49/47 +f 417/145/143 415/166/163 403/185/171 +f 417/145/143 403/185/171 429/143/141 +f 402/186/172 414/167/164 416/146/144 +f 402/186/172 416/146/144 428/144/142 +f 427/141/139 429/143/141 405/187/173 +f 429/143/141 403/185/171 405/187/173 +f 402/186/172 428/144/142 404/188/174 +f 428/144/142 426/142/140 404/188/174 +f 425/139/137 427/141/139 407/189/175 +f 427/141/139 405/187/173 407/189/175 +f 404/188/174 426/142/140 406/190/176 +f 426/142/140 424/140/138 406/190/176 +f 423/137/135 425/139/137 409/191/177 +f 425/139/137 407/189/175 409/191/177 +f 406/190/176 424/140/138 408/192/178 +f 424/140/138 422/138/136 408/192/178 +f 421/133/131 423/137/135 409/191/177 +f 421/133/131 409/191/177 411/193/179 +f 408/192/178 422/138/136 420/136/134 +f 408/192/178 420/136/134 410/194/180 +f 419/134/132 421/133/131 411/193/179 +f 419/134/132 411/193/179 413/168/165 +f 410/194/180 420/136/134 418/135/133 +f 410/194/180 418/135/133 412/169/166 +f 413/168/165 411/193/179 393/195/93 +f 413/168/165 393/195/93 391/179/68 +f 392/196/94 410/194/180 412/169/166 +f 392/196/94 412/169/166 390/182/72 +f 411/193/179 409/191/177 393/195/93 +f 409/191/177 395/197/91 393/195/93 +f 394/198/92 408/192/178 392/196/94 +f 408/192/178 410/194/180 392/196/94 +f 409/191/177 407/189/175 395/197/91 +f 407/189/175 397/199/89 395/197/91 +f 396/200/90 406/190/176 394/198/92 +f 406/190/176 408/192/178 394/198/92 +f 407/189/175 405/187/173 397/199/89 +f 405/187/173 399/89/87 397/199/89 +f 398/201/88 404/188/174 396/200/90 +f 404/188/174 406/190/176 396/200/90 +f 405/187/173 403/185/171 401/87/85 +f 405/187/173 401/87/85 399/89/87 +f 400/202/86 402/186/172 404/188/174 +f 400/202/86 404/188/174 398/201/88 +f 415/166/163 389/79/77 403/185/171 +f 389/79/77 401/87/85 403/185/171 +f 400/202/86 388/170/80 402/186/172 +f 388/170/80 414/167/164 402/186/172 +f 381/47/45 353/46/44 387/203/181 +f 353/46/44 351/204/182 387/203/181 +f 350/205/183 352/45/43 386/206/184 +f 352/45/43 380/44/42 386/206/184 +f 381/47/45 387/203/181 323/207/66 +f 387/203/181 321/183/67 323/207/66 +f 320/184/69 386/206/184 322/208/70 +f 386/206/184 380/44/42 322/208/70 +f 381/47/45 379/209/185 325/48/46 +f 379/209/185 317/210/186 325/48/46 +f 316/211/187 378/212/188 324/43/41 +f 378/212/188 380/44/42 324/43/41 +f 381/47/45 323/207/66 379/209/185 +f 323/207/66 315/213/74 379/209/185 +f 314/214/75 322/208/70 378/212/188 +f 322/208/70 380/44/42 378/212/188 +f 343/36/34 345/40/38 301/42/40 +f 343/36/34 301/42/40 385/34/32 +f 300/37/35 344/39/37 342/31/29 +f 300/37/35 342/31/29 384/33/31 +f 385/34/32 301/42/40 299/215/189 +f 385/34/32 299/215/189 319/172/167 +f 298/216/190 300/37/35 384/33/31 +f 298/216/190 384/33/31 318/176/170 +f 387/203/181 385/34/32 321/183/67 +f 385/34/32 319/172/167 321/183/67 +f 318/176/170 384/33/31 320/184/69 +f 384/33/31 386/206/184 320/184/69 +f 387/203/181 351/204/182 385/34/32 +f 351/204/182 349/35/33 385/34/32 +f 348/32/30 350/205/183 384/33/31 +f 350/205/183 386/206/184 384/33/31 +f 371/217/191 377/218/192 383/219/78 +f 377/218/192 315/213/74 383/219/78 +f 314/214/75 376/220/193 382/221/79 +f 376/220/193 370/222/194 382/221/79 +f 371/217/191 383/219/78 313/174/158 +f 371/217/191 313/174/158 369/223/195 +f 312/178/159 382/221/79 370/222/194 +f 312/178/159 370/222/194 368/224/196 +f 369/223/195 313/174/158 311/173/168 +f 369/223/195 311/173/168 363/225/197 +f 310/175/169 312/178/159 368/224/196 +f 310/175/169 368/224/196 362/226/198 +f 311/173/168 297/227/199 363/225/197 +f 297/227/199 295/228/200 363/225/197 +f 294/229/201 296/230/202 362/226/198 +f 296/230/202 310/175/169 362/226/198 +f 361/231/203 291/232/204 285/29/28 +f 361/231/203 285/29/28 74/28/27 +f 284/26/26 290/233/205 360/234/206 +f 284/26/26 360/234/206 74/27/27 +f 289/235/207 287/236/208 291/232/204 +f 287/236/208 285/29/28 291/232/204 +f 284/26/26 286/237/209 290/233/205 +f 286/237/209 288/238/210 290/233/205 +f 359/239/211 361/231/203 302/240/212 +f 361/231/203 74/28/27 302/240/212 +f 74/27/27 360/234/206 302/241/212 +f 360/234/206 358/242/213 302/241/212 +f 365/243/214 293/244/215 361/231/203 +f 293/244/215 291/232/204 361/231/203 +f 290/233/205 292/245/216 360/234/206 +f 292/245/216 364/246/217 360/234/206 +f 365/243/214 361/231/203 359/239/211 +f 365/243/214 359/239/211 367/247/218 +f 358/242/213 360/234/206 364/246/217 +f 358/242/213 364/246/217 366/248/219 +f 367/247/218 359/239/211 357/249/220 +f 367/247/218 357/249/220 373/250/221 +f 356/251/222 358/242/213 366/248/219 +f 356/251/222 366/248/219 372/252/223 +f 373/250/221 357/249/220 355/253/224 +f 373/250/221 355/253/224 375/254/225 +f 354/255/226 356/251/222 372/252/223 +f 354/255/226 372/252/223 374/256/227 +f 375/254/225 355/253/224 317/210/186 +f 375/254/225 317/210/186 379/209/185 +f 316/211/187 354/255/226 374/256/227 +f 316/211/187 374/256/227 378/212/188 +f 375/254/225 379/209/185 377/218/192 +f 379/209/185 315/213/74 377/218/192 +f 314/214/75 378/212/188 376/220/193 +f 378/212/188 374/256/227 376/220/193 +f 377/218/192 371/217/191 373/250/221 +f 377/218/192 373/250/221 375/254/225 +f 372/252/223 370/222/194 376/220/193 +f 372/252/223 376/220/193 374/256/227 +f 371/217/191 369/223/195 367/247/218 +f 371/217/191 367/247/218 373/250/221 +f 366/248/219 368/224/196 370/222/194 +f 366/248/219 370/222/194 372/252/223 +f 369/223/195 363/225/197 365/243/214 +f 369/223/195 365/243/214 367/247/218 +f 364/246/217 362/226/198 368/224/196 +f 364/246/217 368/224/196 366/248/219 +f 363/225/197 295/228/200 293/244/215 +f 363/225/197 293/244/215 365/243/214 +f 292/245/216 294/229/201 362/226/198 +f 292/245/216 362/226/198 364/246/217 +f 317/210/186 355/253/224 75/257/228 +f 317/210/186 75/257/228 76/258/229 +f 75/259/228 354/255/226 316/211/187 +f 75/259/228 316/211/187 76/260/229 +f 355/253/224 357/249/220 303/261/230 +f 355/253/224 303/261/230 75/257/228 +f 303/262/230 356/251/222 354/255/226 +f 303/262/230 354/255/226 75/259/228 +f 357/249/220 359/239/211 303/261/230 +f 359/239/211 302/240/212 303/261/230 +f 302/241/212 358/242/213 303/262/230 +f 358/242/213 356/251/222 303/262/230 +f 325/48/46 317/210/186 77/263/231 +f 317/210/186 76/258/229 77/263/231 +f 76/260/229 316/211/187 77/264/231 +f 316/211/187 324/43/41 77/264/231 +f 319/172/167 299/215/189 297/227/199 +f 319/172/167 297/227/199 311/173/168 +f 296/230/202 298/216/190 318/176/170 +f 296/230/202 318/176/170 310/175/169 +f 349/35/33 329/265/232 343/36/34 +f 329/265/232 327/266/233 343/36/34 +f 326/267/234 328/268/235 342/31/29 +f 328/268/235 348/32/30 342/31/29 +f 329/265/232 349/35/33 305/269/236 +f 329/265/232 305/269/236 309/270/237 +f 305/271/236 348/32/30 328/268/235 +f 305/271/236 328/268/235 309/272/237 +f 349/35/33 351/204/182 78/273/238 +f 349/35/33 78/273/238 305/269/236 +f 78/274/238 350/205/183 348/32/30 +f 78/274/238 348/32/30 305/271/236 +f 351/204/182 353/46/44 78/273/238 +f 353/46/44 304/275/239 78/273/238 +f 304/276/239 352/45/43 78/274/238 +f 352/45/43 350/205/183 78/274/238 +f 353/46/44 325/48/46 304/275/239 +f 325/48/46 77/263/231 304/275/239 +f 77/264/231 324/43/41 304/276/239 +f 324/43/41 352/45/43 304/276/239 +f 301/42/40 347/41/39 93/277/240 +f 347/278/39 80/279/241 93/280/240 +f 79/281/242 346/282/36 92/283/243 +f 346/38/36 300/37/35 92/284/243 +f 345/40/38 216/285/244 347/41/39 +f 216/286/244 80/279/241 347/278/39 +f 79/281/242 215/287/245 346/282/36 +f 215/288/245 344/39/37 346/38/36 +f 343/36/34 327/266/233 210/289/246 +f 327/266/233 82/290/247 210/289/246 +f 81/291/248 326/267/234 209/292/249 +f 326/267/234 342/31/29 209/292/249 +f 345/40/38 343/36/34 216/285/244 +f 343/36/34 210/289/246 216/285/244 +f 209/292/249 342/31/29 215/288/245 +f 342/31/29 344/39/37 215/288/245 +f 333/293/250 84/294/251 82/290/247 +f 333/293/250 82/290/247 327/266/233 +f 81/291/248 83/295/252 332/296/253 +f 81/291/248 332/296/253 326/267/234 +f 339/297/254 333/293/250 329/265/232 +f 333/293/250 327/266/233 329/265/232 +f 326/267/234 332/296/253 328/268/235 +f 332/296/253 338/298/255 328/268/235 +f 341/299/256 335/300/257 337/301/258 +f 335/300/257 331/302/259 337/301/258 +f 330/303/260 334/304/261 336/305/262 +f 334/304/261 340/306/263 336/305/262 +f 339/297/254 337/301/258 331/302/259 +f 339/297/254 331/302/259 333/293/250 +f 330/303/260 336/305/262 338/298/255 +f 330/303/260 338/298/255 332/296/253 +f 331/302/259 86/307/264 84/294/251 +f 331/302/259 84/294/251 333/293/250 +f 83/295/252 85/308/265 330/303/260 +f 83/295/252 330/303/260 332/296/253 +f 335/300/257 88/309/266 86/307/264 +f 335/300/257 86/307/264 331/302/259 +f 85/308/265 87/310/267 334/304/261 +f 85/308/265 334/304/261 330/303/260 +f 341/299/256 90/311/268 88/309/266 +f 341/299/256 88/309/266 335/300/257 +f 87/310/267 89/312/269 340/306/263 +f 87/310/267 340/306/263 334/304/261 +f 306/313/270 91/314/271 90/311/268 +f 306/313/270 90/311/268 341/299/256 +f 89/312/269 91/315/271 306/316/270 +f 89/312/269 306/316/270 340/306/263 +f 337/301/258 307/317/272 341/299/256 +f 307/317/272 306/313/270 341/299/256 +f 306/316/270 307/318/272 340/306/263 +f 307/318/272 336/305/262 340/306/263 +f 339/297/254 308/319/273 337/301/258 +f 308/319/273 307/317/272 337/301/258 +f 307/318/272 308/320/273 336/305/262 +f 308/320/273 338/298/255 336/305/262 +f 329/265/232 309/270/237 339/297/254 +f 309/270/237 308/319/273 339/297/254 +f 308/320/273 309/272/237 338/298/255 +f 309/272/237 328/268/235 338/298/255 +f 301/42/40 93/277/240 95/321/274 +f 301/42/40 95/321/274 299/215/189 +f 94/322/275 92/284/243 300/37/35 +f 94/322/275 300/37/35 298/216/190 +f 299/215/189 95/321/274 97/323/276 +f 299/215/189 97/323/276 297/227/199 +f 96/324/277 94/322/275 298/216/190 +f 96/324/277 298/216/190 296/230/202 +f 297/227/199 97/323/276 295/228/200 +f 97/323/276 99/325/278 295/228/200 +f 98/326/279 96/324/277 294/229/201 +f 96/324/277 296/230/202 294/229/201 +f 295/228/200 99/325/278 101/327/280 +f 295/228/200 101/327/280 293/244/215 +f 100/328/281 98/326/279 294/229/201 +f 100/328/281 294/229/201 292/245/216 +f 293/244/215 101/327/280 291/232/204 +f 101/327/280 103/329/282 291/232/204 +f 102/330/283 100/328/281 290/233/205 +f 100/328/281 292/245/216 290/233/205 +f 291/232/204 103/329/282 289/235/207 +f 103/329/282 105/331/284 289/235/207 +f 104/332/285 102/330/283 288/238/210 +f 102/330/283 290/233/205 288/238/210 +f 289/235/207 105/331/284 287/236/208 +f 105/331/284 107/333/286 287/236/208 +f 106/334/287 104/332/285 286/237/209 +f 104/332/285 288/238/210 286/237/209 +f 287/236/208 107/333/286 109/335/288 +f 287/236/208 109/335/288 285/29/28 +f 108/336/289 106/334/287 286/237/209 +f 108/336/289 286/237/209 284/26/26 +f 285/29/28 109/335/288 67/337/290 +f 285/29/28 67/337/290 73/30/25 +f 67/338/290 108/336/289 284/26/26 +f 67/338/290 284/26/26 73/25/25 +f 281/339/291 235/340/292 233/341/293 +f 281/339/291 233/341/293 283/342/294 +f 232/343/295 234/344/296 280/345/297 +f 232/343/295 280/345/297 282/346/298 +f 283/342/294 233/341/293 255/347/299 +f 283/342/294 255/347/299 261/348/300 +f 254/349/301 232/343/295 282/346/298 +f 254/349/301 282/346/298 260/350/302 +f 261/348/300 255/347/299 257/351/303 +f 261/348/300 257/351/303 259/352/304 +f 256/353/305 254/349/301 260/350/302 +f 256/353/305 260/350/302 258/354/306 +f 263/355/307 253/356/308 235/340/292 +f 263/355/307 235/340/292 281/339/291 +f 234/344/296 252/357/309 262/358/310 +f 234/344/296 262/358/310 280/345/297 +f 265/359/311 251/360/312 263/355/307 +f 251/360/312 253/356/308 263/355/307 +f 252/357/309 250/361/313 262/358/310 +f 250/361/313 264/362/314 262/358/310 +f 267/363/315 249/364/316 265/359/311 +f 249/364/316 251/360/312 265/359/311 +f 250/361/313 248/365/317 264/362/314 +f 248/365/317 266/366/318 264/362/314 +f 269/367/319 247/368/320 249/364/316 +f 269/367/319 249/364/316 267/363/315 +f 248/365/317 246/369/321 268/370/322 +f 248/365/317 268/370/322 266/366/318 +f 271/371/323 245/372/324 269/367/319 +f 245/372/324 247/368/320 269/367/319 +f 246/369/321 244/373/325 268/370/322 +f 244/373/325 270/374/326 268/370/322 +f 273/375/327 243/376/328 245/372/324 +f 273/375/327 245/372/324 271/371/323 +f 244/373/325 242/377/329 272/378/330 +f 244/373/325 272/378/330 270/374/326 +f 275/379/331 241/380/332 273/375/327 +f 241/380/332 243/376/328 273/375/327 +f 242/377/329 240/381/333 272/378/330 +f 240/381/333 274/382/334 272/378/330 +f 279/383/335 237/384/336 275/379/331 +f 237/384/336 241/380/332 275/379/331 +f 240/381/333 236/385/337 274/382/334 +f 236/385/337 278/386/338 274/382/334 +f 277/387/339 239/388/340 237/384/336 +f 277/387/339 237/384/336 279/383/335 +f 236/385/337 238/389/341 276/390/342 +f 236/385/337 276/390/342 278/386/338 +f 259/352/304 257/351/303 239/388/340 +f 259/352/304 239/388/340 277/387/339 +f 238/389/341 256/353/305 258/354/306 +f 238/389/341 258/354/306 276/390/342 +f 257/351/303 111/391/343 129/392/344 +f 257/351/303 129/392/344 239/388/340 +f 128/393/345 110/394/346 256/353/305 +f 128/393/345 256/353/305 238/389/341 +f 239/388/340 129/392/344 180/395/347 +f 239/388/340 180/395/347 237/384/336 +f 179/396/348 128/393/345 238/389/341 +f 179/396/348 238/389/341 236/385/337 +f 237/384/336 180/395/347 127/397/349 +f 237/384/336 127/397/349 241/380/332 +f 126/398/350 179/396/348 236/385/337 +f 126/398/350 236/385/337 240/381/333 +f 241/380/332 127/397/349 243/376/328 +f 127/397/349 125/399/351 243/376/328 +f 124/400/352 126/398/350 242/377/329 +f 126/398/350 240/381/333 242/377/329 +f 243/376/328 125/399/351 245/372/324 +f 125/399/351 123/401/353 245/372/324 +f 122/402/354 124/400/352 244/373/325 +f 124/400/352 242/377/329 244/373/325 +f 245/372/324 123/401/353 121/403/355 +f 245/372/324 121/403/355 247/368/320 +f 120/404/356 122/402/354 244/373/325 +f 120/404/356 244/373/325 246/369/321 +f 247/368/320 121/403/355 119/405/357 +f 247/368/320 119/405/357 249/364/316 +f 118/406/358 120/404/356 246/369/321 +f 118/406/358 246/369/321 248/365/317 +f 249/364/316 119/405/357 117/407/359 +f 249/364/316 117/407/359 251/360/312 +f 116/408/360 118/406/358 248/365/317 +f 116/408/360 248/365/317 250/361/313 +f 251/360/312 117/407/359 115/409/361 +f 251/360/312 115/409/361 253/356/308 +f 114/410/362 116/408/360 250/361/313 +f 114/410/362 250/361/313 252/357/309 +f 253/356/308 115/409/361 235/340/292 +f 115/409/361 182/411/363 235/340/292 +f 181/412/364 114/410/362 234/344/296 +f 114/410/362 252/357/309 234/344/296 +f 255/347/299 113/413/365 257/351/303 +f 113/413/365 111/391/343 257/351/303 +f 110/394/346 112/414/366 256/353/305 +f 112/414/366 254/349/301 256/353/305 +f 233/341/293 184/415/367 113/413/365 +f 233/341/293 113/413/365 255/347/299 +f 112/414/366 183/416/368 232/343/295 +f 112/414/366 232/343/295 254/349/301 +f 235/340/292 182/411/363 184/415/367 +f 235/340/292 184/415/367 233/341/293 +f 183/416/368 181/412/364 234/344/296 +f 183/416/368 234/344/296 232/343/295 +f 230/23/23 231/417/369 224/418/370 +f 230/23/23 224/418/370 226/24/24 +f 224/418/370 231/417/369 229/20/20 +f 224/418/370 229/20/20 225/19/19 +f 224/418/370 72/419/371 226/24/24 +f 72/419/371 223/420/372 226/24/24 +f 222/421/373 72/419/371 225/19/19 +f 72/419/371 224/418/370 225/19/19 +f 226/24/24 223/420/372 221/422/374 +f 226/24/24 221/422/374 228/22/22 +f 220/423/375 222/421/373 225/19/19 +f 220/423/375 225/19/19 227/21/21 +f 228/22/22 221/422/374 219/424/376 +f 228/22/22 219/424/376 230/23/23 +f 218/425/377 220/423/375 227/21/21 +f 218/425/377 227/21/21 229/20/20 +f 230/23/23 219/424/376 231/417/369 +f 219/424/376 217/426/378 231/417/369 +f 217/426/378 218/425/377 231/417/369 +f 218/425/377 229/20/20 231/417/369 +f 219/424/376 136/427/379 137/428/380 +f 219/424/376 137/428/380 217/426/378 +f 137/428/380 135/429/381 218/425/377 +f 137/428/380 218/425/377 217/426/378 +f 221/422/374 134/430/382 136/427/379 +f 221/422/374 136/427/379 219/424/376 +f 135/429/381 133/431/383 220/423/375 +f 135/429/381 220/423/375 218/425/377 +f 223/420/372 132/432/384 134/430/382 +f 223/420/372 134/430/382 221/422/374 +f 133/431/383 131/433/385 222/421/373 +f 133/431/383 222/421/373 220/423/375 +f 72/419/371 130/434/386 223/420/372 +f 130/434/386 132/432/384 223/420/372 +f 131/433/385 130/434/386 222/421/373 +f 130/434/386 72/419/371 222/421/373 +f 212/435/387 165/436/388 80/279/241 +f 212/435/387 80/279/241 216/286/244 +f 79/281/242 164/437/389 211/438/390 +f 79/281/242 211/438/390 215/287/245 +f 212/435/387 216/286/244 214/439/391 +f 216/286/244 210/440/246 214/439/391 +f 209/441/249 215/287/245 213/442/392 +f 215/287/245 211/438/390 213/442/392 +f 214/439/391 210/440/246 167/443/393 +f 210/440/246 82/444/247 167/443/393 +f 81/445/248 209/441/249 166/446/394 +f 209/441/249 213/442/392 166/446/394 +f 167/443/393 188/447/395 214/439/391 +f 188/447/395 145/448/396 214/439/391 +f 144/449/397 187/450/398 213/442/392 +f 187/450/398 166/446/394 213/442/392 +f 214/439/391 145/448/396 212/435/387 +f 145/448/396 143/451/399 212/435/387 +f 142/452/400 144/449/397 211/438/390 +f 144/449/397 213/442/392 211/438/390 +f 212/435/387 143/451/399 141/453/401 +f 212/435/387 141/453/401 165/436/388 +f 140/454/402 142/452/400 211/438/390 +f 140/454/402 211/438/390 164/437/389 +f 165/436/388 141/453/401 139/455/403 +f 165/436/388 139/455/403 177/456/404 +f 139/455/403 140/454/402 164/437/389 +f 139/455/403 164/437/389 177/456/404 +f 207/457/405 208/458/406 199/459/407 +f 207/457/405 199/459/407 205/460/408 +f 199/459/407 208/458/406 206/461/409 +f 199/459/407 206/461/409 204/462/410 +f 203/463/411 205/460/408 201/464/412 +f 205/460/408 199/459/407 201/464/412 +f 199/459/407 204/462/410 200/465/413 +f 204/462/410 202/466/414 200/465/413 +f 207/457/405 205/460/408 194/467/415 +f 207/457/405 194/467/415 192/468/416 +f 193/469/417 204/462/410 206/461/409 +f 193/469/417 206/461/409 191/470/418 +f 205/460/408 203/463/411 194/467/415 +f 203/463/411 196/471/419 194/467/415 +f 195/472/420 202/466/414 193/469/417 +f 202/466/414 204/462/410 193/469/417 +f 203/463/411 201/464/412 198/473/421 +f 203/463/411 198/473/421 196/471/419 +f 197/474/422 200/465/413 202/466/414 +f 197/474/422 202/466/414 195/472/420 +f 201/464/412 199/459/407 71/475/423 +f 201/464/412 71/475/423 198/473/421 +f 71/475/423 199/459/407 200/465/413 +f 71/475/423 200/465/413 197/474/422 +f 207/457/405 192/468/416 208/458/406 +f 192/468/416 70/476/424 208/458/406 +f 70/476/424 191/470/418 208/458/406 +f 191/470/418 206/461/409 208/458/406 +f 192/468/416 145/448/396 70/476/424 +f 145/448/396 190/477/425 70/476/424 +f 190/477/425 144/449/397 70/476/424 +f 144/449/397 191/470/418 70/476/424 +f 198/473/421 71/475/423 139/455/403 +f 71/478/423 138/479/426 139/480/403 +f 138/481/426 71/482/423 139/483/403 +f 71/475/423 197/474/422 139/455/403 +f 196/471/419 198/473/421 141/453/401 +f 198/473/421 139/455/403 141/453/401 +f 139/455/403 197/474/422 140/454/402 +f 197/474/422 195/472/420 140/454/402 +f 194/467/415 196/471/419 143/451/399 +f 196/471/419 141/453/401 143/451/399 +f 140/454/402 195/472/420 142/452/400 +f 195/472/420 193/469/417 142/452/400 +f 192/468/416 194/467/415 143/451/399 +f 192/468/416 143/451/399 145/448/396 +f 142/452/400 193/469/417 191/470/418 +f 142/452/400 191/470/418 144/449/397 +f 186/484/427 132/432/384 69/485/428 +f 132/432/384 130/434/386 69/485/428 +f 130/434/386 131/433/385 69/485/428 +f 131/433/385 185/486/429 69/485/428 +f 189/487/430 188/447/395 69/485/428 +f 188/447/395 186/484/427 69/485/428 +f 185/486/429 187/450/398 69/485/428 +f 187/450/398 189/487/430 69/485/428 +f 189/487/430 190/477/425 188/447/395 +f 190/477/425 145/448/396 188/447/395 +f 144/449/397 190/477/425 187/450/398 +f 190/477/425 189/487/430 187/450/398 +f 169/488/431 171/489/432 132/432/384 +f 169/488/431 132/432/384 186/484/427 +f 131/433/385 170/490/433 168/491/434 +f 131/433/385 168/491/434 185/486/429 +f 186/484/427 188/447/395 167/443/393 +f 186/484/427 167/443/393 169/488/431 +f 166/446/394 187/450/398 185/486/429 +f 166/446/394 185/486/429 168/491/434 +f 173/492/435 134/430/382 171/489/432 +f 134/430/382 132/432/384 171/489/432 +f 131/433/385 133/431/383 170/490/433 +f 133/431/383 172/493/436 170/490/433 +f 175/494/437 136/427/379 134/430/382 +f 175/494/437 134/430/382 173/492/435 +f 133/431/383 135/429/381 174/495/438 +f 133/431/383 174/495/438 172/493/436 +f 176/496/439 137/428/380 136/427/379 +f 176/496/439 136/427/379 175/494/437 +f 135/429/381 137/428/380 176/496/439 +f 135/429/381 176/496/439 174/495/438 +f 184/415/367 182/411/363 178/497/440 +f 182/411/363 177/456/404 178/497/440 +f 177/456/404 181/412/364 178/497/440 +f 181/412/364 183/416/368 178/497/440 +f 178/497/440 68/498/441 113/413/365 +f 178/497/440 113/413/365 184/415/367 +f 112/414/366 68/498/441 178/497/440 +f 112/414/366 178/497/440 183/416/368 +f 68/498/441 163/499/442 113/413/365 +f 163/499/442 111/391/343 113/413/365 +f 110/394/346 162/500/443 112/414/366 +f 162/500/443 68/498/441 112/414/366 +f 177/456/404 182/411/363 115/409/361 +f 177/456/404 115/409/361 165/436/388 +f 114/410/362 181/412/364 177/456/404 +f 114/410/362 177/456/404 164/437/389 +f 147/501/444 165/436/388 115/409/361 +f 147/501/444 115/409/361 117/407/359 +f 114/410/362 164/437/389 146/502/445 +f 114/410/362 146/502/445 116/408/360 +f 149/503/446 147/501/444 119/405/357 +f 147/501/444 117/407/359 119/405/357 +f 116/408/360 146/502/445 118/406/358 +f 146/502/445 148/504/447 118/406/358 +f 151/505/448 149/503/446 121/403/355 +f 149/503/446 119/405/357 121/403/355 +f 118/406/358 148/504/447 120/404/356 +f 148/504/447 150/506/449 120/404/356 +f 153/507/450 151/505/448 123/401/353 +f 151/505/448 121/403/355 123/401/353 +f 120/404/356 150/506/449 122/402/354 +f 150/506/449 152/508/451 122/402/354 +f 155/509/452 153/507/450 125/399/351 +f 153/507/450 123/401/353 125/399/351 +f 122/402/354 152/508/451 124/400/352 +f 152/508/451 154/510/453 124/400/352 +f 157/511/454 155/509/452 127/397/349 +f 155/509/452 125/399/351 127/397/349 +f 124/400/352 154/510/453 126/398/350 +f 154/510/453 156/512/455 126/398/350 +f 159/513/456 157/511/454 180/395/347 +f 157/511/454 127/397/349 180/395/347 +f 126/398/350 156/512/455 179/396/348 +f 156/512/455 158/514/457 179/396/348 +f 159/513/456 180/395/347 129/392/344 +f 159/513/456 129/392/344 161/515/458 +f 128/393/345 179/396/348 158/514/457 +f 128/393/345 158/514/457 160/516/459 +f 161/515/458 129/392/344 163/499/442 +f 129/392/344 111/391/343 163/499/442 +f 110/394/346 128/393/345 162/500/443 +f 128/393/345 160/516/459 162/500/443 +f 68/498/441 67/517/290 163/499/442 +f 67/517/290 109/518/288 163/499/442 +f 108/519/289 67/517/290 162/500/443 +f 67/517/290 68/498/441 162/500/443 +f 163/499/442 109/518/288 161/515/458 +f 109/518/288 107/520/286 161/515/458 +f 106/521/287 108/519/289 160/516/459 +f 108/519/289 162/500/443 160/516/459 +f 161/515/458 107/520/286 159/513/456 +f 107/520/286 105/522/284 159/513/456 +f 104/523/285 106/521/287 158/514/457 +f 106/521/287 160/516/459 158/514/457 +f 159/513/456 105/522/284 103/524/282 +f 159/513/456 103/524/282 157/511/454 +f 102/525/283 104/523/285 158/514/457 +f 102/525/283 158/514/457 156/512/455 +f 157/511/454 103/524/282 155/509/452 +f 103/524/282 101/526/280 155/509/452 +f 100/527/281 102/525/283 154/510/453 +f 102/525/283 156/512/455 154/510/453 +f 155/509/452 101/526/280 153/507/450 +f 101/526/280 99/528/278 153/507/450 +f 98/529/279 100/527/281 152/508/451 +f 100/527/281 154/510/453 152/508/451 +f 153/507/450 99/528/278 151/505/448 +f 99/528/278 97/530/276 151/505/448 +f 96/531/277 98/529/279 150/506/449 +f 98/529/279 152/508/451 150/506/449 +f 151/505/448 97/530/276 95/532/274 +f 151/505/448 95/532/274 149/503/446 +f 94/533/275 96/531/277 150/506/449 +f 94/533/275 150/506/449 148/504/447 +f 149/503/446 95/532/274 147/501/444 +f 95/532/274 93/280/240 147/501/444 +f 92/283/243 94/533/275 146/502/445 +f 94/533/275 148/504/447 146/502/445 +f 147/501/444 93/280/240 80/279/241 +f 147/501/444 80/279/241 165/436/388 +f 79/281/242 92/283/243 146/502/445 +f 79/281/242 146/502/445 164/437/389 +f 169/488/431 167/443/393 82/444/247 +f 169/488/431 82/444/247 84/534/251 +f 81/445/248 166/446/394 168/491/434 +f 81/445/248 168/491/434 83/535/252 +f 171/489/432 169/488/431 84/534/251 +f 171/489/432 84/534/251 86/536/264 +f 83/535/252 168/491/434 170/490/433 +f 83/535/252 170/490/433 85/537/265 +f 173/492/435 171/489/432 86/536/264 +f 173/492/435 86/536/264 88/538/266 +f 85/537/265 170/490/433 172/493/436 +f 85/537/265 172/493/436 87/539/267 +f 175/494/437 173/492/435 90/540/268 +f 173/492/435 88/538/266 90/540/268 +f 87/539/267 172/493/436 89/541/269 +f 172/493/436 174/495/438 89/541/269 +f 176/496/439 175/494/437 91/542/271 +f 175/494/437 90/540/268 91/542/271 +f 89/541/269 174/495/438 91/542/271 +f 174/495/438 176/496/439 91/542/271 +f 50/4/4 48/543/460 2/544/461 +f 50/4/4 2/544/461 66/5/5 +f 1/545/462 47/546/463 49/3/3 +f 1/545/462 49/3/3 65/2/2 +f 66/5/5 2/544/461 12/547/464 +f 66/5/5 12/547/464 64/8/8 +f 11/548/465 1/545/462 65/2/2 +f 11/548/465 65/2/2 63/7/7 +f 64/8/8 12/547/464 14/549/466 +f 64/8/8 14/549/466 60/10/10 +f 13/550/467 11/548/465 63/7/7 +f 13/550/467 63/7/7 59/9/9 +f 60/10/10 14/549/466 24/551/468 +f 60/10/10 24/551/468 58/12/12 +f 23/552/469 13/550/467 59/9/9 +f 23/552/469 59/9/9 57/11/11 +f 58/12/12 24/551/468 56/14/14 +f 24/551/468 26/553/470 56/14/14 +f 25/554/471 23/552/469 55/13/13 +f 23/552/469 57/11/11 55/13/13 +f 56/14/14 26/553/470 54/16/16 +f 26/553/470 36/555/472 54/16/16 +f 35/556/473 25/554/471 53/15/15 +f 25/554/471 55/13/13 53/15/15 +f 54/16/16 36/555/472 52/18/18 +f 36/555/472 38/557/474 52/18/18 +f 37/558/475 35/556/473 51/17/17 +f 35/556/473 53/15/15 51/17/17 +f 52/18/18 38/557/474 50/4/4 +f 38/557/474 48/543/460 50/4/4 +f 47/546/463 37/558/475 49/3/3 +f 37/558/475 51/17/17 49/3/3 +f 46/559/476 48/543/460 40/560/477 +f 48/543/460 38/557/474 40/560/477 +f 37/558/475 47/546/463 39/561/478 +f 47/546/463 45/562/479 39/561/478 +f 44/563/480 46/559/476 42/564/481 +f 46/559/476 40/560/477 42/564/481 +f 39/561/478 45/562/479 41/565/482 +f 45/562/479 43/566/483 41/565/482 +f 42/564/481 40/560/477 32/567/484 +f 40/560/477 34/568/485 32/567/484 +f 33/569/486 39/561/478 31/570/487 +f 39/561/478 41/565/482 31/570/487 +f 40/560/477 38/557/474 34/568/485 +f 38/557/474 36/555/472 34/568/485 +f 35/556/473 37/558/475 33/569/486 +f 37/558/475 39/561/478 33/569/486 +f 34/568/485 36/555/472 28/571/488 +f 36/555/472 26/553/470 28/571/488 +f 25/554/471 35/556/473 27/572/489 +f 35/556/473 33/569/486 27/572/489 +f 32/567/484 34/568/485 30/573/490 +f 34/568/485 28/571/488 30/573/490 +f 27/572/489 33/569/486 29/574/491 +f 33/569/486 31/570/487 29/574/491 +f 30/573/490 28/571/488 20/575/492 +f 28/571/488 22/576/493 20/575/492 +f 21/577/494 27/572/489 19/578/495 +f 27/572/489 29/574/491 19/578/495 +f 28/571/488 26/553/470 24/551/468 +f 28/571/488 24/551/468 22/576/493 +f 23/552/469 25/554/471 27/572/489 +f 23/552/469 27/572/489 21/577/494 +f 22/576/493 24/551/468 16/579/496 +f 24/551/468 14/549/466 16/579/496 +f 13/550/467 23/552/469 15/580/497 +f 23/552/469 21/577/494 15/580/497 +f 20/575/492 22/576/493 18/581/498 +f 22/576/493 16/579/496 18/581/498 +f 15/580/497 21/577/494 17/582/499 +f 21/577/494 19/578/495 17/582/499 +f 18/581/498 16/579/496 10/583/500 +f 18/581/498 10/583/500 8/584/501 +f 9/585/502 15/580/497 17/582/499 +f 9/585/502 17/582/499 7/586/503 +f 16/579/496 14/549/466 12/547/464 +f 16/579/496 12/547/464 10/583/500 +f 11/548/465 13/550/467 15/580/497 +f 11/548/465 15/580/497 9/585/502 +f 10/583/500 12/547/464 2/544/461 +f 10/583/500 2/544/461 4/587/504 +f 1/545/462 11/548/465 9/585/502 +f 1/545/462 9/585/502 3/588/505 +f 8/584/501 10/583/500 4/587/504 +f 8/584/501 4/587/504 6/589/506 +f 3/588/505 9/585/502 7/586/503 +f 3/588/505 7/586/503 5/590/507 +f 6/589/506 4/587/504 46/559/476 +f 6/589/506 46/559/476 44/563/480 +f 45/562/479 3/588/505 5/590/507 +f 45/562/479 5/590/507 43/566/483 +f 4/587/504 2/544/461 48/543/460 +f 4/587/504 48/543/460 46/559/476 +f 47/546/463 1/545/462 3/588/505 +f 47/546/463 3/588/505 45/562/479 diff --git a/demos/art/models/sponza/sponza.license b/demos/art/models/sponza/sponza.license new file mode 100644 index 0000000..78aefa0 --- /dev/null +++ b/demos/art/models/sponza/sponza.license @@ -0,0 +1,4 @@ +http://hdri.cgtechniques.com/~sponza/files/ + +Sponza modeled by Marko Dabrovic, with UVs and crack errors fixed by Kenzie Lamar at Vicarious Visions. +Bump maps painted by Morgan McGuire. diff --git a/engine/art/fx/editorOutline.fs b/engine/art/fx/editorOutline.fs new file mode 100644 index 0000000..57a7eee --- /dev/null +++ b/engine/art/fx/editorOutline.fs @@ -0,0 +1,21 @@ +/// tip:"Ensure colorbuffer is alpha clear before calling this one." + +uniform int thickness; /// set:2 +uniform vec4 border_color; /// set:1,1,0,1 + +void main() { + vec4 texel = texture(iChannel0, uv); + float outline = 0.0; + if( texel.a == 0.0 ) { + for( int x = -thickness; x <= thickness; x++ ) { + for( int y = -thickness;y <= thickness; y++ ) { + float sample = texture(iChannel0, uv+vec2(float(x)/iWidth, float(y)/iHeight)).a; + if( sample > 0.0 ) { + outline = 1.0; + } + } + } + } + + FRAGCOLOR = vec4(border_color.rgb, outline * border_color.a); // mix(texel, border_color, outline * border_color.a); +} \ No newline at end of file diff --git a/engine/bind/v4k.lua b/engine/bind/v4k.lua index a504dbd..b946a68 100644 --- a/engine/bind/v4k.lua +++ b/engine/bind/v4k.lua @@ -2313,7 +2313,7 @@ enum { NETWORK_USERID = 7, NETWORK_COUNT , NETWORK_CAPACITY }; extern void (*dtor[256])(); void* obj_initialize( void **ptr, char *type_and_info ); void *obj_tmpalloc; - int profile_enable(bool on); + int profiler_enable(bool on); struct profile_t { double stat; int32_t cost, avg; }; typedef struct { map base; struct { pair p; char * key; struct profile_t val; } tmp, *ptr; struct profile_t* tmpval; int (*typed_cmp)(char *, char *); uint64_t (*typed_hash)(char *); } * profiler_t; extern profiler_t profiler; @@ -2504,6 +2504,8 @@ int texture_width; void shader_destroy(unsigned shader); unsigned shader_properties(unsigned shader); char** shader_property(unsigned shader, unsigned property_no); + void shader_apply_param(unsigned shader, unsigned param_no); + void shader_apply_params(unsigned shader, const char *parameter_mask); int ui_shader(unsigned shader); int ui_shaders(); enum BUFFER_MODE { @@ -2515,8 +2517,8 @@ BUFFER_READ_WRITE void compute_dispatch(unsigned wx, unsigned wy, unsigned wz); void shader_image(texture_t t, unsigned unit, unsigned level, int layer, unsigned access); void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int layer, unsigned texel_type, unsigned access); - void image_write_barrier(); void write_barrier(); + void write_barrier_image(); enum SSBO_USAGE { STATIC_DRAW, STATIC_READ, @@ -2968,7 +2970,6 @@ PANEL_OPEN = 1, int ui_double(const char *label, double *value); int ui_buffer(const char *label, char *buffer, int buflen); int ui_string(const char *label, char **string); - int ui_text_wrap(const char *label, char *text); int ui_color3(const char *label, float *color3); int ui_color3f(const char *label, float *color3); int ui_color4(const char *label, float *color4); @@ -2990,18 +2991,17 @@ PANEL_OPEN = 1, int ui_subimage(const char *label, handle id, unsigned iw, unsigned ih, unsigned sx, unsigned sy, unsigned sw, unsigned sh); int ui_colormap(const char *label, colormap_t *cm); int ui_separator(); - int ui_bits8(const char *label, uint8_t *bits); - int ui_bits16(const char *label, uint16_t *bits); + int ui_bitmask8(const char *label, uint8_t *bits); + int ui_bitmask16(const char *label, uint16_t *bits); int ui_console(); int ui_clampf(const char *label, float *value, float minf, float maxf); int ui_label(const char *label); int ui_label2(const char *label, const char *caption); + int ui_label2_bool(const char *label, bool enabled); + int ui_label2_float(const char *label, float value); int ui_label2_toolbar(const char *label, const char *icons); int ui_slider(const char *label, float *value); int ui_slider2(const char *label, float *value, const char *caption); - int ui_const_bool(const char *label, const double value); - int ui_const_float(const char *label, const double value); - int ui_const_string(const char *label, const char *value); int ui_contextual_end(); int ui_collapse_clicked(); int ui_collapse_end(); @@ -3010,9 +3010,10 @@ 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 on); - int ui_enabled(); vec2 ui_get_dims(); + int ui_enable(); + int ui_enabled(); + int ui_disable(); int ui_has_menubar(); int ui_menu(const char *items); int ui_menu_editbox(char *buf, int bufcap); diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index e010f87..86fdc20 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -14226,14 +14226,14 @@ extern "C" { // system headers #ifndef _GNU_SOURCE -#define _GNU_SOURCE // for linux +#define _GNU_SOURCE ///- for linux #endif #if is(cl) && is(win32) // for VC IDE -#define _CRT_SECURE_NO_WARNINGS -#define _CRT_NONSTDC_NO_DEPRECATE -#define _WINSOCK_DEPRECATED_NO_WARNINGS -#define _WIN32_WINNT 0x0600 // 0x0502 // GetInfoAddrW/FreeAddrInfoW for X86 +#define _CRT_SECURE_NO_WARNINGS ///- +#define _CRT_NONSTDC_NO_DEPRECATE ///- +#define _WINSOCK_DEPRECATED_NO_WARNINGS ///- +#define _WIN32_WINNT 0x0600 ///- 0x0502 // GetInfoAddrW/FreeAddrInfoW for X86 #endif #if is(cl) @@ -16345,9 +16345,9 @@ static __thread void *obj_tmpalloc; # define profile(section) for(int macro(i) = 1; macro(i); macro(i) = 0) # define profile_incstat(name, accum) do {} while(0) # define profile_setstat(name, value) do {} while(0) -# define profile_init() do {} while(0) -# define profile_render() do {} while(0) -# define profile_enable(x) 0 +# define profiler_init() do {} while(0) +# define profiler_enable(x) 0 +# define ui_profiler() do {} while(0) #else # define profile(section) for( \ struct profile_t *found = profiler_enabled ? \ @@ -16360,7 +16360,7 @@ static __thread void *obj_tmpalloc; # define profile_setstat(name, value) for( \ struct profile_t *found = profiler_enabled ? map_find_or_add(profiler, name, (struct profile_t){0}) : NULL; \ found; found->stat = value, found = NULL) ///+ -API int profile_enable(bool on); +API int profiler_enable(bool on); struct profile_t { double stat; int32_t cost, avg; }; ///- typedef map(char *, struct profile_t) profiler_t; ///- @@ -16715,6 +16715,9 @@ API void shader_destroy(unsigned shader); API unsigned shader_properties(unsigned shader); API char** shader_property(unsigned shader, unsigned property_no); +API void shader_apply_param(unsigned shader, unsigned param_no); +API void shader_apply_params(unsigned shader, const char *parameter_mask); + API int ui_shader(unsigned shader); API int ui_shaders(); @@ -16759,12 +16762,12 @@ API void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int // gpu memory barriers -/// Blocks main thread until all image operations are done by the GPU. -API void image_write_barrier(); - /// Blocks main thread until all memory operations are done by the GPU. API void write_barrier(); +/// Blocks main thread until all image operations are done by the GPU. +API void write_barrier_image(); + // ssbo /// `STATIC`, `DYNAMIC` AND `STREAM` specify the frequency at which we intend to access the data. /// `DRAW` favors CPU->GPU operations. @@ -17485,7 +17488,6 @@ API int ui_float4(const char *label, float value[4]); API int ui_double(const char *label, double *value); API int ui_buffer(const char *label, char *buffer, int buflen); API int ui_string(const char *label, char **string); -API int ui_text_wrap(const char *label, char *text); API int ui_color3(const char *label, float *color3); //[0..255] API int ui_color3f(const char *label, float *color3); //[0..1] API int ui_color4(const char *label, float *color4); //[0..255] @@ -17507,18 +17509,17 @@ API int ui_image(const char *label, handle id, unsigned w, unsigned h); //(w, API int ui_subimage(const char *label, handle id, unsigned iw, unsigned ih, unsigned sx, unsigned sy, unsigned sw, unsigned sh); API int ui_colormap(const char *label, colormap_t *cm); // returns num member changed: 1 for color, 2 for texture map API int ui_separator(); -API int ui_bits8(const char *label, uint8_t *bits); -API int ui_bits16(const char *label, uint16_t *bits); +API int ui_bitmask8(const char *label, uint8_t *bits); +API int ui_bitmask16(const char *label, uint16_t *bits); API int ui_console(); API int ui_clampf(const char *label, float *value, float minf, float maxf); API int ui_label(const char *label); API int ui_label2(const char *label, const char *caption); +API int ui_label2_bool(const char *label, bool enabled); +API int ui_label2_float(const char *label, float value); API int ui_label2_toolbar(const char *label, const char *icons); API int ui_slider(const char *label, float *value); API int ui_slider2(const char *label, float *value, const char *caption); -API int ui_const_bool(const char *label, const double value); -API int ui_const_float(const char *label, const double value); -API int ui_const_string(const char *label, const char *value); API int ui_contextual_end(); API int ui_collapse_clicked(); API int ui_collapse_end(); @@ -17528,10 +17529,12 @@ 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(int on); -API int ui_enabled(); API vec2 ui_get_dims(); +API int ui_enable(); +API int ui_enabled(); +API int ui_disable(); + API int ui_has_menubar(); API int ui_menu(const char *items); // semicolon-separated or comma-separated items API int ui_menu_editbox(char *buf, int bufcap); @@ -330739,6 +330742,9 @@ float audio_volume_master(float gain) { } int audio_play_gain_pitch_pan( audio_t a, int flags, float gain, float pitch, float pan ) { + static bool muted = 0; do_once muted = flag("--mute") || flag("--muted"); + if(muted) return 1; + if( flags & AUDIO_IGNORE_MIXER_GAIN ) { // do nothing, gain used as-is } else { @@ -333133,6 +333139,7 @@ int cook_jobs() { void cook_config( const char *pathfile_to_cook_ini ) { // @todo: test run-from-"bin/" case on Linux. COOK_INI = pathfile_to_cook_ini; + ASSERT( file_exist(COOK_INI) ); } #line 0 @@ -337536,32 +337543,37 @@ bool input_touch_active() { void input_demo() { if( ui_panel("Input",0) ) { ui_section("Keyboard"); - ui_const_bool("[Key 1]", input(KEY_1)); - ui_const_bool("[Key 2]", input(KEY_2)); - ui_const_bool("[Key 3]", input(KEY_3)); - ui_const_bool("[Key 4]", input(KEY_4)); - ui_const_bool("[Key 5]", input(KEY_5)); - ui_const_bool("[Key 6]", input(KEY_6)); - ui_const_bool("[Key 7]", input(KEY_7)); + + uint8_t keymap = 0; + keymap |= (!!input(KEY_1)) << 7; + keymap |= (!!input(KEY_2)) << 6; + keymap |= (!!input(KEY_3)) << 5; + keymap |= (!!input(KEY_4)) << 4; + keymap |= (!!input(KEY_5)) << 3; + keymap |= (!!input(KEY_6)) << 2; + keymap |= (!!input(KEY_7)) << 1; + keymap |= (!!input(KEY_8)) << 0; + ui_bitmask8("[Keys 1..8]", &keymap); + ui_separator(); - ui_const_bool("[Key 1] Down event", input_down(KEY_1) ); - ui_const_bool("[Key 2] Held event", input_held(KEY_2) ); - ui_const_bool("[Key 3] Up event", input_up(KEY_3) ); - ui_const_bool("[Key 4] Idle event", input_idle(KEY_4) ); - ui_const_bool("[Key 5] Click event", input_click(KEY_5,500) ); - ui_const_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); - ui_const_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); + ui_label2_bool("[Key 1] Down event", input_down(KEY_1) ); + ui_label2_bool("[Key 2] Held event", input_held(KEY_2) ); + ui_label2_bool("[Key 3] Up event", input_up(KEY_3) ); + ui_label2_bool("[Key 4] Idle event", input_idle(KEY_4) ); + ui_label2_bool("[Key 5] Click event", input_click(KEY_5,500) ); + ui_label2_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); + ui_label2_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); ui_separator(); ui_section("Mouse"); - ui_const_float("X", input(MOUSE_X)); - ui_const_float("Y", input(MOUSE_Y)); + ui_label2_float("X", input(MOUSE_X)); + ui_label2_float("Y", input(MOUSE_Y)); ui_separator(); - ui_const_float("Wheel", input(MOUSE_W)); + ui_label2_float("Wheel", input(MOUSE_W)); ui_separator(); - ui_const_bool("Left", input(MOUSE_L)); - ui_const_bool("Middle", input(MOUSE_M)); - ui_const_bool("Right", input(MOUSE_R)); + ui_label2_bool("Left", input(MOUSE_L)); + ui_label2_bool("Middle", input(MOUSE_M)); + ui_label2_bool("Right", input(MOUSE_R)); ui_separator(); for( int i = 0; i <= CURSOR_SW_AUTO; ++i ) if(ui_button(va("Cursor shape #%d", i))) window_cursor_shape(i); ui_separator(); @@ -337573,45 +337585,45 @@ void input_demo() { input_use(gamepad_id); - ui_const_string("Name", input_frames(GAMEPAD_NAME,0)); - ui_const_bool("Connected", input(GAMEPAD_CONNECTED)); + ui_label2("Name", input_frames(GAMEPAD_NAME,0)); + ui_label2_bool("Connected", input(GAMEPAD_CONNECTED)); ui_separator(); - ui_const_bool("A", input(GAMEPAD_A) ); - ui_const_bool("B", input(GAMEPAD_B) ); - ui_const_bool("X", input(GAMEPAD_X) ); - ui_const_bool("Y", input(GAMEPAD_Y) ); - ui_const_bool("Up", input(GAMEPAD_UP) ); - ui_const_bool("Down", input(GAMEPAD_DOWN) ); - ui_const_bool("Left", input(GAMEPAD_LEFT) ); - ui_const_bool("Right", input(GAMEPAD_RIGHT) ); - ui_const_bool("Menu", input(GAMEPAD_MENU) ); - ui_const_bool("Start", input(GAMEPAD_START) ); + ui_label2_bool("A", input(GAMEPAD_A) ); + ui_label2_bool("B", input(GAMEPAD_B) ); + ui_label2_bool("X", input(GAMEPAD_X) ); + ui_label2_bool("Y", input(GAMEPAD_Y) ); + ui_label2_bool("Up", input(GAMEPAD_UP) ); + ui_label2_bool("Down", input(GAMEPAD_DOWN) ); + ui_label2_bool("Left", input(GAMEPAD_LEFT) ); + ui_label2_bool("Right", input(GAMEPAD_RIGHT) ); + ui_label2_bool("Menu", input(GAMEPAD_MENU) ); + ui_label2_bool("Start", input(GAMEPAD_START) ); ui_separator(); - ui_const_float("Left pad x", input(GAMEPAD_LPADX) ); - ui_const_float("Left pad y", input(GAMEPAD_LPADY) ); - ui_const_float("Left trigger", input(GAMEPAD_LT) ); - ui_const_bool("Left bumper", input(GAMEPAD_LB) ); - ui_const_bool("Left thumb", input(GAMEPAD_LTHUMB) ); + ui_label2_float("Left pad x", input(GAMEPAD_LPADX) ); + ui_label2_float("Left pad y", input(GAMEPAD_LPADY) ); + ui_label2_float("Left trigger", input(GAMEPAD_LT) ); + ui_label2_bool("Left bumper", input(GAMEPAD_LB) ); + ui_label2_bool("Left thumb", input(GAMEPAD_LTHUMB) ); vec2 v = input_filter_deadzone( input2(GAMEPAD_LPADX), 0.1f ); - ui_const_float("Filtered pad x", v.x); - ui_const_float("Filtered pad y", v.y); + ui_label2_float("Filtered pad x", v.x); + ui_label2_float("Filtered pad y", v.y); ui_separator(); - ui_const_float("Right pad x", input(GAMEPAD_RPADX) ); - ui_const_float("Right pad y", input(GAMEPAD_RPADY) ); - ui_const_float("Right trigger", input(GAMEPAD_RT) ); - ui_const_bool("Right bumper", input(GAMEPAD_RB) ); - ui_const_bool("Right thumb", input(GAMEPAD_RTHUMB) ); + ui_label2_float("Right pad x", input(GAMEPAD_RPADX) ); + ui_label2_float("Right pad y", input(GAMEPAD_RPADY) ); + ui_label2_float("Right trigger", input(GAMEPAD_RT) ); + ui_label2_bool("Right bumper", input(GAMEPAD_RB) ); + ui_label2_bool("Right thumb", input(GAMEPAD_RTHUMB) ); vec2 w = input_filter_deadzone( input2(GAMEPAD_RPADX), 0.1f ); - ui_const_float("Filtered pad x", w.x); - ui_const_float("Filtered pad y", w.y); + ui_label2_float("Filtered pad x", w.x); + ui_label2_float("Filtered pad y", w.y); input_use(0); @@ -339909,22 +339921,23 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char 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)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if(fs) for each_substring(fs, "\r\n", line) { - if( strstr(line, "/""//") && !strbeg(line,"//") ) { - array_push(props, STRDUP(line)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if(gs) for each_substring(gs, "\r\n", line) { - if( strstr(line, "/""//") && !strbeg(line,"//") ) { - array_push(props, STRDUP(line)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if( props ) { map_insert(shader_reflect, program, props); + for( int i = 0; i < array_count(props); ++i ) shader_apply_param(program, i); } return program; @@ -339937,7 +339950,60 @@ unsigned shader_properties(unsigned shader) { char** shader_property(unsigned shader, unsigned property) { array(char*) *found = map_find(shader_reflect, shader); - return found ? &(*found)[property] : NULL; + return found && property < array_count(*found) ? &(*found)[property] : NULL; +} + +void shader_apply_param(unsigned shader, unsigned param_no) { + unsigned num_properties = shader_properties(shader); + if( param_no < num_properties ) { + char *line = *shader_property(shader, param_no); + + char type[32], name[32]; + if( sscanf(line, "%*s %s %[^ =;/]", type, name) != 2 ) return; + + 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); + + 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); + + if( !strstr(line, "max:") ) { + if(setv.x > maxv.x) maxv.x = setv.x; + if(setv.y > maxv.y) maxv.y = setv.y; + if(setv.z > maxv.z) maxv.z = setv.z; + if(setv.w > maxv.w) maxv.w = setv.w; + } + + setv = clamp4(setv, minv, maxv); + + if( strchr("ibfv", type[0]) ) { + 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] == 'b') 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); + } + } +} + +void shader_apply_params(unsigned shader, const char *parameter_mask) { + unsigned num_properties = shader_properties(shader); + for( unsigned i = 0; i < num_properties; ++i ) { + char *line = *shader_property(shader,i); + + char name[32]; + if( sscanf(line, "%*s %*s %s", name) != 1 ) continue; + if( !strmatch(name, parameter_mask) ) continue; + shader_apply_param(shader, i); + } } int ui_shader(unsigned shader) { @@ -339948,25 +340014,43 @@ int ui_shader(unsigned shader) { 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; + char* tip = strstr(line, "tip:"); tip = tip && tip[4] ? tip + 4 : 0; + + char uniform[32], type[32], name[32], early_exit = '\0'; + if( sscanf(line, "%s %s %[^ =;/]", uniform, type, name) != 3 ) continue; // @todo optimize: move to shader() + if( strcmp(uniform, "uniform") && strcmp(uniform, "}uniform") ) { if(tip) ui_label(va(ICON_MD_INFO "%s", tip)); continue; } // @todo optimize: move to shader() 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); + va("%c%s " ICON_MD_INFO "@%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); + if(minv.x > maxv.x) swapf(&minv.x, &maxv.x); // @optimize: move to shader() + if(minv.y > maxv.y) swapf(&minv.y, &maxv.y); // @optimize: move to shader() + if(minv.z > maxv.z) swapf(&minv.z, &maxv.z); // @optimize: move to shader() + if(minv.w > maxv.w) swapf(&minv.w, &maxv.w); // @optimize: move to shader() + + if( !strstr(line, "max:") ) { + if(setv.x > maxv.x) maxv.x = setv.x; + if(setv.y > maxv.y) maxv.y = setv.y; + if(setv.z > maxv.z) maxv.z = setv.z; + if(setv.w > maxv.w) maxv.w = setv.w; + } + + setv = clamp4(setv, minv, maxv); // supports int,float,vec2/3/4,color3/4 int touched = 0; - if( type[0] == 'i' ) { + if( type[0] == 'b' ) { + bool v = !!setv.x; + + if( (touched = ui_bool(label, &v)) != 0 ) { + setv.x = v; + } + } + else if( type[0] == 'i' ) { int v = setv.x; if( (touched = ui_int(label, &v)) != 0 ) { @@ -339974,9 +340058,11 @@ int ui_shader(unsigned shader) { } } else if( type[0] == 'f' ) { - setv.x = (clampf(setv.x, minv.x, maxv.x) - minv.x) / (maxv.x - minv.x); + setv.x = clampf(setv.x, minv.x, maxv.x); + char *caption = va("%5.2f", setv.x); + setv.x = (setv.x - minv.x) / (maxv.x - minv.x); - if( (touched = ui_slider2(label, &setv.x, va("%5.2f", setv.x))) != 0 ) { + if( (touched = ui_slider2(label, &setv.x, caption)) != 0 ) { setv.x = clampf(minv.x + setv.x * (maxv.x-minv.x), minv.x, maxv.x); // min..max range } } @@ -340001,28 +340087,20 @@ int ui_shader(unsigned shader) { setv = clamp4(setv,minv,maxv); } } + else if( tip ) ui_label( tip ); 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:""); + // apply + shader_apply_param(shader, i); + changed = 1; } } - if(num_properties) ui_separator(); - return changed; } @@ -340030,13 +340108,14 @@ int ui_shaders() { if( !map_count(shader_reflect) ) return 0; 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)); + int open = 0, clicked_or_toggled = 0; + char *id = va("##SHD%d", *k); + char *title = va("Shader %d", *k); + for( int p = (open = ui_collapse(title, id)), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_label(va("Shader %d",*k)); changed |= ui_shader(*k); } - (has_menu ? ui_window_end : ui_panel_end)(); } return changed; } @@ -340091,7 +340170,7 @@ void write_barrier(){ glMemoryBarrier(GL_ALL_BARRIER_BITS); } -void image_write_barrier(){ +void write_barrier_image(){ glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } @@ -342949,9 +343028,9 @@ void postfx_clear(postfx *fx) { int ui_postfx(postfx *fx, int pass) { int on = ui_enabled(); - ui_enable( postfx_enabled(fx,pass) ); + ( postfx_enabled(fx,pass) ? ui_enable : ui_disable )(); int rc = ui_shader(fx->pass[pass].program); - ui_enable( on ); + ( on ? ui_enable : ui_disable )(); return rc; } @@ -343132,16 +343211,12 @@ int ui_fxs() { if(!fx.num_loaded) return 0; int changed = 0; - int has_menu = ui_has_menubar(); - if( (has_menu ? ui_window("FX", 0) : ui_panel("FX", 0) ) ) { for( int i = 0; i < 64; ++i ) { 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); } - (has_menu ? ui_window_end : ui_panel_end)(); - } return changed; } @@ -347179,8 +347254,8 @@ default_hue = 0.52; struct nk_color active = nk_hsv_f( 0.600, 0.00, 0.150); // bright b/w struct nk_color table[NK_COLOR_COUNT] = {0}; table[NK_COLOR_TEXT] = nk_rgba(210, 210, 210, 255); - table[NK_COLOR_WINDOW] = nk_rgba(42, 42, 42, 215); - table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 220); + table[NK_COLOR_WINDOW] = nk_rgba(42, 42, 42, 245); + table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 245); table[NK_COLOR_BORDER] = nk_rgba(46, 46, 46, 255); table[NK_COLOR_BUTTON] = main; table[NK_COLOR_BUTTON_HOVER] = hover; @@ -347571,7 +347646,7 @@ int ui_active() { } static -int ui_enable_(int enabled) { +int ui_set_enable_(int enabled) { static struct nk_style off, on; do_once { off = on = ui_ctx->style; @@ -347809,8 +347884,11 @@ int ui_enable_(int enabled) { } static int ui_is_enabled = 1; -int ui_enable(int on) { - return ui_is_enabled == on ? 0 : ui_enable_(ui_is_enabled = on); +int ui_enable() { + return ui_is_enabled == 1 ? 0 : ui_set_enable_(ui_is_enabled = 1); +} +int ui_disable() { + return ui_is_enabled == 0 ? 0 : ui_set_enable_(ui_is_enabled = 0); } int ui_enabled() { return ui_is_enabled; @@ -348592,6 +348670,20 @@ ui_label_icon_clicked_R.x = is_hovering ? ( (int)((input->mouse.pos.x - bounds.x return ui_label_icon_clicked_R.x; } +int ui_label2_bool(const char *text, bool value) { + bool b = !!value; + return ui_bool(text, &b), 0; +} +int ui_label2_float(const char *text, float value) { + float f = (float)value; + return ui_float(text, &f), 0; +} +int ui_label2_wrap(const char *label, const char *str) { // @fixme: does not work (remove dynamic layout?) + nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + ui_label_(label, NK_TEXT_LEFT); + nk_text_wrap(ui_ctx, str, strlen(str)); + return 0; +} int ui_label2_toolbar(const char *label, const char *icons) { int mouse_click = ui_label2(label, va(">%s", icons)); int choice = !mouse_click ? 0 : 1 + -mouse_click / (UI_ICON_FONTSIZE + UI_ICON_SPACING_X); // divided by px per ICON_MD_ glyph approximately @@ -348706,18 +348798,6 @@ int ui_button(const char *s) { return ui_buttons(1, s); } -int ui_const_bool(const char *text, const double value) { - bool b = !!value; - return ui_bool(text, &b), 0; -} -int ui_const_float(const char *text, const double value) { - float f = (float)value; - return ui_float(text, &f), 0; -} -int ui_const_string(const char *label, const char *text) { - return ui_label2(label, text); -} - int ui_toggle(const char *label, bool *value) { nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); ui_label_(label, NK_TEXT_LEFT); @@ -348981,13 +349061,6 @@ int ui_buffer(const char *label, char *buffer, int buflen) { return !!(active & NK_EDIT_COMMITED) ? nk_edit_unfocus(ui_ctx), 1 : 0; } -int ui_text_wrap(const char *label, char *text) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); - ui_label_(label, NK_TEXT_LEFT); - nk_text_wrap(ui_ctx, text, strlen(text)); - return 0; -} - int ui_string(const char *label, char **str) { char *bak = va("%s%c", *str ? *str : "", '\0'); int rc = ui_buffer(label, bak, strlen(bak)+2); @@ -349111,8 +349184,8 @@ int ui_dialog(const char *title, const char *text, int choices, bool *show) { // return *show; } -#define ui_bits_template(X) \ -int ui_bits##X(const char *label, uint##X##_t *enabled) { \ +#define ui_bitmask_template(X) \ +int ui_bitmask##X(const char *label, uint##X##_t *enabled) { \ /* @fixme: better way to retrieve widget width? nk_layout_row_dynamic() seems excessive */ \ nk_layout_row_dynamic(ui_ctx, 1, 1); \ struct nk_rect bounds = nk_widget_bounds(ui_ctx); \ @@ -349143,9 +349216,9 @@ int ui_bits##X(const char *label, uint##X##_t *enabled) { \ return copy ^ *enabled; \ } -ui_bits_template(8); -ui_bits_template(16); -//ui_bits_template(32); +ui_bitmask_template(8); +ui_bitmask_template(16); +//ui_bitmask_template(32); int ui_console() { // @fixme: buggy static char *cmd = 0; @@ -349306,13 +349379,15 @@ 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_enable(0); + if( disable_all ) ui_disable(); if( ui_browse(&browsed_file, &show_browser) ) puts(browsed_file); if( ui_section("Labels")) {} if( ui_label("my label")) {} if( ui_label("my label with tooltip@built on " __DATE__ " " __TIME__)) {} + if( ui_label2_toolbar("my toolbar", ICON_MD_STAR ICON_MD_STAR_OUTLINE ICON_MD_BOOKMARK ICON_MD_BOOKMARK_BORDER) ) {} + //if( ui_label2_wrap("my long label", "and some long long long long text wrapped")) {} if( ui_section("Types")) {} if( ui_bool("my bool", &boolean) ) puts("bool changed"); @@ -349345,7 +349420,7 @@ int ui_demo(int do_windows) { } if( ui_section("Others")) {} - if( ui_bits8("my bitmask", &bitmask) ) printf("bitmask changed %x\n", bitmask); + if( ui_bitmask8("my bitmask", &bitmask) ) printf("bitmask changed %x\n", bitmask); if( ui_toggle("my toggle", &toggle) ) printf("toggle %s\n", toggle ? "on":"off"); if( ui_image("my image", texture_checker().id, 0, 0) ) { puts("image clicked"); } @@ -349355,7 +349430,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(1); + if( disable_all ) ui_enable(); // restore enabled state ui_panel_end(); } @@ -349447,30 +349522,14 @@ int ui_demo(int do_windows) { profiler_t profiler; int profiler_enabled = 1; -void (profile_init)() { map_init(profiler, less_str, hash_str); profiler_enabled &= !!profiler; } -int (profile_enable)(bool on) { return profiler_enabled = on; } -void (profile_render)() { - // @transparent - static bool has_transparent_attrib = 0; do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE; - if( has_transparent_attrib ) return; - // @transparent - - int has_menu = ui_has_menubar(); - if( !has_menu ) { - static int cook_on_demand; do_once cook_on_demand = COOK_ON_DEMAND; - if( !cook_on_demand ) { - // render profiler, unless we are in the cook progress screen - static unsigned frames = 0; if(frames <= 0) frames += cook_progress() >= 100; - if( frames <= 0 ) return; - } - } - - if( has_menu ? ui_window("Profiler", 0) : ui_panel("Profiler", 0) ) { +void (profiler_init)() { map_init(profiler, less_str, hash_str); profiler_enabled &= !!profiler; } +int (profiler_enable)(bool on) { return profiler_enabled = on; } +void (ui_profiler)() { + // @todo: ui_plot() double fps = window_fps(); profile_setstat("Render.num_fps", fps); - if(1) { // @todo: ui_plot() // draw fps-meter: 300 samples, [0..70] range each, 70px height plot. nk_layout_row_dynamic(ui_ctx, 70, 1); @@ -349499,7 +349558,6 @@ void (profile_render)() { if( index >= 0 ) { nk_tooltipf(ui_ctx, "%.2f fps", (float)values[index]); } - } for each_map_ptr_sorted(profiler, const char *, key, struct profile_t, val ) { if( isnan(val->stat) ) { @@ -349510,9 +349568,6 @@ void (profile_render)() { ui_slider2(*key, &v, va("%.2f", val->stat)); val->stat = 0; } - } - - (has_menu ? ui_window_end : ui_panel_end)(); } } #endif @@ -350109,7 +350164,7 @@ bool window_create_from_handle(void *handle, float scale, unsigned flags) { #if is(ems) if( FLAGS_FULLSCREEN ) window_fullscreen(1); #else - gladLoadGL(glfwGetProcAddress); + int gl_version = gladLoadGL(glfwGetProcAddress); #endif glDebugEnable(); @@ -350133,6 +350188,8 @@ bool window_create_from_handle(void *handle, float scale, unsigned flags) { PRINTF("GPU driver: %s\n", glGetString(GL_VERSION)); #if !is(ems) + PRINTF("GPU OpenGL: %d.%d\n", GLAD_VERSION_MAJOR(gl_version), GLAD_VERSION_MINOR(gl_version)); + if( FLAGS_TRANSPARENT ) { // @transparent glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_FALSE); if( scale >= 1 ) glfwMaximizeWindow(window); @@ -350261,10 +350318,51 @@ int window_frame_begin() { ui_create(); - profile_render(); + bool may_render_stats = 1; - ui_shaders(); + int has_menu = ui_has_menubar(); + if( !has_menu ) { + static int cook_on_demand; do_once cook_on_demand = COOK_ON_DEMAND; + if( !cook_on_demand ) { + // render profiler, unless we are in the cook progress screen + static unsigned frames = 0; if(frames <= 0) frames += cook_progress() >= 100; + may_render_stats = (frames > 0); + } + } + + // @transparent + static bool has_transparent_attrib = 0; do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE; + if( has_transparent_attrib ) may_render_stats = 0; + // @transparent + + // generate Debug panel contents + if( may_render_stats ) { + if( has_menu ? ui_window("Debug", 0) : ui_panel("Debug", 0) ) { + + int open = 0, clicked_or_toggled = 0; + + for( int p = (open = ui_collapse("FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_fxs(); + } + for( int p = (open = ui_collapse("Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_profiler(); + } + for( int p = (open = ui_collapse("Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_shaders(); + } + for( int p = (open = ui_collapse("Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + for( int p = (open = ui_collapse("Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + for( int p = (open = ui_collapse("Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + + (has_menu ? ui_window_end : ui_panel_end)(); + } + } #if 0 // deprecated // run user-defined hooks @@ -352277,22 +352375,20 @@ int main() { // ---------------------------------------------------------------------------- static void v4k_pre_init() { - window_icon(va("%s.png", app_name())); - ifdef(win32,window_icon(va("%s.ico", app_name()))); + const char *appname = app_name(); + window_icon(va("%s.png", appname)); + ifdef(win32,window_icon(va("%s.ico", appname))); glfwPollEvents(); int i; -#if 1 // #ifdef PARALLEL_INIT #pragma omp parallel for -#endif for( i = 0; i <= 3; ++i) { /**/ if( i == 0 ) ddraw_init();// init this on thread#0 since it will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up else if( i == 1 ) sprite_init(); - else if( i == 2 ) profile_init(); + else if( i == 2 ) profiler_init(); else if( i == 3 ) storage_mount("save/"), storage_read(), touch_init(); // for ems } - ; // window_swap(); } diff --git a/engine/split/v4k_audio.c b/engine/split/v4k_audio.c index 71abc45..c64f76e 100644 --- a/engine/split/v4k_audio.c +++ b/engine/split/v4k_audio.c @@ -386,6 +386,9 @@ float audio_volume_master(float gain) { } int audio_play_gain_pitch_pan( audio_t a, int flags, float gain, float pitch, float pan ) { + static bool muted = 0; do_once muted = flag("--mute") || flag("--muted"); + if(muted) return 1; + if( flags & AUDIO_IGNORE_MIXER_GAIN ) { // do nothing, gain used as-is } else { diff --git a/engine/split/v4k_config.h b/engine/split/v4k_config.h index 27185e2..888453b 100644 --- a/engine/split/v4k_config.h +++ b/engine/split/v4k_config.h @@ -211,14 +211,14 @@ // system headers #ifndef _GNU_SOURCE -#define _GNU_SOURCE // for linux +#define _GNU_SOURCE ///- for linux #endif #if is(cl) && is(win32) // for VC IDE -#define _CRT_SECURE_NO_WARNINGS -#define _CRT_NONSTDC_NO_DEPRECATE -#define _WINSOCK_DEPRECATED_NO_WARNINGS -#define _WIN32_WINNT 0x0600 // 0x0502 // GetInfoAddrW/FreeAddrInfoW for X86 +#define _CRT_SECURE_NO_WARNINGS ///- +#define _CRT_NONSTDC_NO_DEPRECATE ///- +#define _WINSOCK_DEPRECATED_NO_WARNINGS ///- +#define _WIN32_WINNT 0x0600 ///- 0x0502 // GetInfoAddrW/FreeAddrInfoW for X86 #endif #if is(cl) diff --git a/engine/split/v4k_cooker.c b/engine/split/v4k_cooker.c index 8350172..d32becf 100644 --- a/engine/split/v4k_cooker.c +++ b/engine/split/v4k_cooker.c @@ -804,4 +804,5 @@ int cook_jobs() { void cook_config( const char *pathfile_to_cook_ini ) { // @todo: test run-from-"bin/" case on Linux. COOK_INI = pathfile_to_cook_ini; + ASSERT( file_exist(COOK_INI) ); } diff --git a/engine/split/v4k_input.c b/engine/split/v4k_input.c index 0fb28a0..7be527e 100644 --- a/engine/split/v4k_input.c +++ b/engine/split/v4k_input.c @@ -626,32 +626,37 @@ bool input_touch_active() { void input_demo() { if( ui_panel("Input",0) ) { ui_section("Keyboard"); - ui_const_bool("[Key 1]", input(KEY_1)); - ui_const_bool("[Key 2]", input(KEY_2)); - ui_const_bool("[Key 3]", input(KEY_3)); - ui_const_bool("[Key 4]", input(KEY_4)); - ui_const_bool("[Key 5]", input(KEY_5)); - ui_const_bool("[Key 6]", input(KEY_6)); - ui_const_bool("[Key 7]", input(KEY_7)); + + uint8_t keymap = 0; + keymap |= (!!input(KEY_1)) << 7; + keymap |= (!!input(KEY_2)) << 6; + keymap |= (!!input(KEY_3)) << 5; + keymap |= (!!input(KEY_4)) << 4; + keymap |= (!!input(KEY_5)) << 3; + keymap |= (!!input(KEY_6)) << 2; + keymap |= (!!input(KEY_7)) << 1; + keymap |= (!!input(KEY_8)) << 0; + ui_bitmask8("[Keys 1..8]", &keymap); + ui_separator(); - ui_const_bool("[Key 1] Down event", input_down(KEY_1) ); - ui_const_bool("[Key 2] Held event", input_held(KEY_2) ); - ui_const_bool("[Key 3] Up event", input_up(KEY_3) ); - ui_const_bool("[Key 4] Idle event", input_idle(KEY_4) ); - ui_const_bool("[Key 5] Click event", input_click(KEY_5,500) ); - ui_const_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); - ui_const_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); + ui_label2_bool("[Key 1] Down event", input_down(KEY_1) ); + ui_label2_bool("[Key 2] Held event", input_held(KEY_2) ); + ui_label2_bool("[Key 3] Up event", input_up(KEY_3) ); + ui_label2_bool("[Key 4] Idle event", input_idle(KEY_4) ); + ui_label2_bool("[Key 5] Click event", input_click(KEY_5,500) ); + ui_label2_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); + ui_label2_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); ui_separator(); ui_section("Mouse"); - ui_const_float("X", input(MOUSE_X)); - ui_const_float("Y", input(MOUSE_Y)); + ui_label2_float("X", input(MOUSE_X)); + ui_label2_float("Y", input(MOUSE_Y)); ui_separator(); - ui_const_float("Wheel", input(MOUSE_W)); + ui_label2_float("Wheel", input(MOUSE_W)); ui_separator(); - ui_const_bool("Left", input(MOUSE_L)); - ui_const_bool("Middle", input(MOUSE_M)); - ui_const_bool("Right", input(MOUSE_R)); + ui_label2_bool("Left", input(MOUSE_L)); + ui_label2_bool("Middle", input(MOUSE_M)); + ui_label2_bool("Right", input(MOUSE_R)); ui_separator(); for( int i = 0; i <= CURSOR_SW_AUTO; ++i ) if(ui_button(va("Cursor shape #%d", i))) window_cursor_shape(i); ui_separator(); @@ -663,45 +668,45 @@ void input_demo() { input_use(gamepad_id); - ui_const_string("Name", input_frames(GAMEPAD_NAME,0)); - ui_const_bool("Connected", input(GAMEPAD_CONNECTED)); + ui_label2("Name", input_frames(GAMEPAD_NAME,0)); + ui_label2_bool("Connected", input(GAMEPAD_CONNECTED)); ui_separator(); - ui_const_bool("A", input(GAMEPAD_A) ); - ui_const_bool("B", input(GAMEPAD_B) ); - ui_const_bool("X", input(GAMEPAD_X) ); - ui_const_bool("Y", input(GAMEPAD_Y) ); - ui_const_bool("Up", input(GAMEPAD_UP) ); - ui_const_bool("Down", input(GAMEPAD_DOWN) ); - ui_const_bool("Left", input(GAMEPAD_LEFT) ); - ui_const_bool("Right", input(GAMEPAD_RIGHT) ); - ui_const_bool("Menu", input(GAMEPAD_MENU) ); - ui_const_bool("Start", input(GAMEPAD_START) ); + ui_label2_bool("A", input(GAMEPAD_A) ); + ui_label2_bool("B", input(GAMEPAD_B) ); + ui_label2_bool("X", input(GAMEPAD_X) ); + ui_label2_bool("Y", input(GAMEPAD_Y) ); + ui_label2_bool("Up", input(GAMEPAD_UP) ); + ui_label2_bool("Down", input(GAMEPAD_DOWN) ); + ui_label2_bool("Left", input(GAMEPAD_LEFT) ); + ui_label2_bool("Right", input(GAMEPAD_RIGHT) ); + ui_label2_bool("Menu", input(GAMEPAD_MENU) ); + ui_label2_bool("Start", input(GAMEPAD_START) ); ui_separator(); - ui_const_float("Left pad x", input(GAMEPAD_LPADX) ); - ui_const_float("Left pad y", input(GAMEPAD_LPADY) ); - ui_const_float("Left trigger", input(GAMEPAD_LT) ); - ui_const_bool("Left bumper", input(GAMEPAD_LB) ); - ui_const_bool("Left thumb", input(GAMEPAD_LTHUMB) ); + ui_label2_float("Left pad x", input(GAMEPAD_LPADX) ); + ui_label2_float("Left pad y", input(GAMEPAD_LPADY) ); + ui_label2_float("Left trigger", input(GAMEPAD_LT) ); + ui_label2_bool("Left bumper", input(GAMEPAD_LB) ); + ui_label2_bool("Left thumb", input(GAMEPAD_LTHUMB) ); vec2 v = input_filter_deadzone( input2(GAMEPAD_LPADX), 0.1f ); - ui_const_float("Filtered pad x", v.x); - ui_const_float("Filtered pad y", v.y); + ui_label2_float("Filtered pad x", v.x); + ui_label2_float("Filtered pad y", v.y); ui_separator(); - ui_const_float("Right pad x", input(GAMEPAD_RPADX) ); - ui_const_float("Right pad y", input(GAMEPAD_RPADY) ); - ui_const_float("Right trigger", input(GAMEPAD_RT) ); - ui_const_bool("Right bumper", input(GAMEPAD_RB) ); - ui_const_bool("Right thumb", input(GAMEPAD_RTHUMB) ); + ui_label2_float("Right pad x", input(GAMEPAD_RPADX) ); + ui_label2_float("Right pad y", input(GAMEPAD_RPADY) ); + ui_label2_float("Right trigger", input(GAMEPAD_RT) ); + ui_label2_bool("Right bumper", input(GAMEPAD_RB) ); + ui_label2_bool("Right thumb", input(GAMEPAD_RTHUMB) ); vec2 w = input_filter_deadzone( input2(GAMEPAD_RPADX), 0.1f ); - ui_const_float("Filtered pad x", w.x); - ui_const_float("Filtered pad y", w.y); + ui_label2_float("Filtered pad x", w.x); + ui_label2_float("Filtered pad y", w.y); input_use(0); diff --git a/engine/split/v4k_main.c b/engine/split/v4k_main.c index ac27eba..991fef2 100644 --- a/engine/split/v4k_main.c +++ b/engine/split/v4k_main.c @@ -1,22 +1,20 @@ // ---------------------------------------------------------------------------- static void v4k_pre_init() { - window_icon(va("%s.png", app_name())); - ifdef(win32,window_icon(va("%s.ico", app_name()))); + const char *appname = app_name(); + window_icon(va("%s.png", appname)); + ifdef(win32,window_icon(va("%s.ico", appname))); glfwPollEvents(); int i; -#if 1 // #ifdef PARALLEL_INIT #pragma omp parallel for -#endif for( i = 0; i <= 3; ++i) { /**/ if( i == 0 ) ddraw_init();// init this on thread#0 since it will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up else if( i == 1 ) sprite_init(); - else if( i == 2 ) profile_init(); + else if( i == 2 ) profiler_init(); else if( i == 3 ) storage_mount("save/"), storage_read(), touch_init(); // for ems } - ; // window_swap(); } diff --git a/engine/split/v4k_profile.c b/engine/split/v4k_profile.c index dcb77ee..f26ba84 100644 --- a/engine/split/v4k_profile.c +++ b/engine/split/v4k_profile.c @@ -2,30 +2,14 @@ profiler_t profiler; int profiler_enabled = 1; -void (profile_init)() { map_init(profiler, less_str, hash_str); profiler_enabled &= !!profiler; } -int (profile_enable)(bool on) { return profiler_enabled = on; } -void (profile_render)() { - // @transparent - static bool has_transparent_attrib = 0; do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE; - if( has_transparent_attrib ) return; - // @transparent - - int has_menu = ui_has_menubar(); - if( !has_menu ) { - static int cook_on_demand; do_once cook_on_demand = COOK_ON_DEMAND; - if( !cook_on_demand ) { - // render profiler, unless we are in the cook progress screen - static unsigned frames = 0; if(frames <= 0) frames += cook_progress() >= 100; - if( frames <= 0 ) return; - } - } - - if( has_menu ? ui_window("Profiler", 0) : ui_panel("Profiler", 0) ) { +void (profiler_init)() { map_init(profiler, less_str, hash_str); profiler_enabled &= !!profiler; } +int (profiler_enable)(bool on) { return profiler_enabled = on; } +void (ui_profiler)() { + // @todo: ui_plot() double fps = window_fps(); profile_setstat("Render.num_fps", fps); - if(1) { // @todo: ui_plot() // draw fps-meter: 300 samples, [0..70] range each, 70px height plot. nk_layout_row_dynamic(ui_ctx, 70, 1); @@ -54,7 +38,6 @@ void (profile_render)() { if( index >= 0 ) { nk_tooltipf(ui_ctx, "%.2f fps", (float)values[index]); } - } for each_map_ptr_sorted(profiler, const char *, key, struct profile_t, val ) { if( isnan(val->stat) ) { @@ -65,9 +48,6 @@ void (profile_render)() { ui_slider2(*key, &v, va("%.2f", val->stat)); val->stat = 0; } - } - - (has_menu ? ui_window_end : ui_panel_end)(); } } #endif diff --git a/engine/split/v4k_profile.h b/engine/split/v4k_profile.h index 15198d8..7c5124d 100644 --- a/engine/split/v4k_profile.h +++ b/engine/split/v4k_profile.h @@ -5,9 +5,9 @@ # define profile(section) for(int macro(i) = 1; macro(i); macro(i) = 0) # define profile_incstat(name, accum) do {} while(0) # define profile_setstat(name, value) do {} while(0) -# define profile_init() do {} while(0) -# define profile_render() do {} while(0) -# define profile_enable(x) 0 +# define profiler_init() do {} while(0) +# define profiler_enable(x) 0 +# define ui_profiler() do {} while(0) #else # define profile(section) for( \ struct profile_t *found = profiler_enabled ? \ @@ -20,7 +20,7 @@ # define profile_setstat(name, value) for( \ struct profile_t *found = profiler_enabled ? map_find_or_add(profiler, name, (struct profile_t){0}) : NULL; \ found; found->stat = value, found = NULL) ///+ -API int profile_enable(bool on); +API int profiler_enable(bool on); struct profile_t { double stat; int32_t cost, avg; }; ///- typedef map(char *, struct profile_t) profiler_t; ///- diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index be54907..ddaa218 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -194,22 +194,23 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char 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)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if(fs) for each_substring(fs, "\r\n", line) { - if( strstr(line, "/""//") && !strbeg(line,"//") ) { - array_push(props, STRDUP(line)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if(gs) for each_substring(gs, "\r\n", line) { - if( strstr(line, "/""//") && !strbeg(line,"//") ) { - array_push(props, STRDUP(line)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if( props ) { map_insert(shader_reflect, program, props); + for( int i = 0; i < array_count(props); ++i ) shader_apply_param(program, i); } return program; @@ -222,7 +223,60 @@ unsigned shader_properties(unsigned shader) { char** shader_property(unsigned shader, unsigned property) { array(char*) *found = map_find(shader_reflect, shader); - return found ? &(*found)[property] : NULL; + return found && property < array_count(*found) ? &(*found)[property] : NULL; +} + +void shader_apply_param(unsigned shader, unsigned param_no) { + unsigned num_properties = shader_properties(shader); + if( param_no < num_properties ) { + char *line = *shader_property(shader, param_no); + + char type[32], name[32]; + if( sscanf(line, "%*s %s %[^ =;/]", type, name) != 2 ) return; + + 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); + + 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); + + if( !strstr(line, "max:") ) { + if(setv.x > maxv.x) maxv.x = setv.x; + if(setv.y > maxv.y) maxv.y = setv.y; + if(setv.z > maxv.z) maxv.z = setv.z; + if(setv.w > maxv.w) maxv.w = setv.w; + } + + setv = clamp4(setv, minv, maxv); + + if( strchr("ibfv", type[0]) ) { + 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] == 'b') 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); + } + } +} + +void shader_apply_params(unsigned shader, const char *parameter_mask) { + unsigned num_properties = shader_properties(shader); + for( unsigned i = 0; i < num_properties; ++i ) { + char *line = *shader_property(shader,i); + + char name[32]; + if( sscanf(line, "%*s %*s %s", name) != 1 ) continue; + if( !strmatch(name, parameter_mask) ) continue; + shader_apply_param(shader, i); + } } int ui_shader(unsigned shader) { @@ -233,25 +287,43 @@ int ui_shader(unsigned shader) { 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; + char* tip = strstr(line, "tip:"); tip = tip && tip[4] ? tip + 4 : 0; + + char uniform[32], type[32], name[32], early_exit = '\0'; + if( sscanf(line, "%s %s %[^ =;/]", uniform, type, name) != 3 ) continue; // @todo optimize: move to shader() + if( strcmp(uniform, "uniform") && strcmp(uniform, "}uniform") ) { if(tip) ui_label(va(ICON_MD_INFO "%s", tip)); continue; } // @todo optimize: move to shader() 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); + va("%c%s " ICON_MD_INFO "@%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); + if(minv.x > maxv.x) swapf(&minv.x, &maxv.x); // @optimize: move to shader() + if(minv.y > maxv.y) swapf(&minv.y, &maxv.y); // @optimize: move to shader() + if(minv.z > maxv.z) swapf(&minv.z, &maxv.z); // @optimize: move to shader() + if(minv.w > maxv.w) swapf(&minv.w, &maxv.w); // @optimize: move to shader() + + if( !strstr(line, "max:") ) { + if(setv.x > maxv.x) maxv.x = setv.x; + if(setv.y > maxv.y) maxv.y = setv.y; + if(setv.z > maxv.z) maxv.z = setv.z; + if(setv.w > maxv.w) maxv.w = setv.w; + } + + setv = clamp4(setv, minv, maxv); // supports int,float,vec2/3/4,color3/4 int touched = 0; - if( type[0] == 'i' ) { + if( type[0] == 'b' ) { + bool v = !!setv.x; + + if( (touched = ui_bool(label, &v)) != 0 ) { + setv.x = v; + } + } + else if( type[0] == 'i' ) { int v = setv.x; if( (touched = ui_int(label, &v)) != 0 ) { @@ -259,9 +331,11 @@ int ui_shader(unsigned shader) { } } else if( type[0] == 'f' ) { - setv.x = (clampf(setv.x, minv.x, maxv.x) - minv.x) / (maxv.x - minv.x); + setv.x = clampf(setv.x, minv.x, maxv.x); + char *caption = va("%5.2f", setv.x); + setv.x = (setv.x - minv.x) / (maxv.x - minv.x); - if( (touched = ui_slider2(label, &setv.x, va("%5.2f", setv.x))) != 0 ) { + if( (touched = ui_slider2(label, &setv.x, caption)) != 0 ) { setv.x = clampf(minv.x + setv.x * (maxv.x-minv.x), minv.x, maxv.x); // min..max range } } @@ -286,28 +360,20 @@ int ui_shader(unsigned shader) { setv = clamp4(setv,minv,maxv); } } + else if( tip ) ui_label( tip ); 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:""); + // apply + shader_apply_param(shader, i); + changed = 1; } } - if(num_properties) ui_separator(); - return changed; } @@ -315,13 +381,14 @@ int ui_shaders() { if( !map_count(shader_reflect) ) return 0; 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)); + int open = 0, clicked_or_toggled = 0; + char *id = va("##SHD%d", *k); + char *title = va("Shader %d", *k); + for( int p = (open = ui_collapse(title, id)), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_label(va("Shader %d",*k)); changed |= ui_shader(*k); } - (has_menu ? ui_window_end : ui_panel_end)(); } return changed; } @@ -376,7 +443,7 @@ void write_barrier(){ glMemoryBarrier(GL_ALL_BARRIER_BITS); } -void image_write_barrier(){ +void write_barrier_image(){ glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } @@ -3234,9 +3301,9 @@ void postfx_clear(postfx *fx) { int ui_postfx(postfx *fx, int pass) { int on = ui_enabled(); - ui_enable( postfx_enabled(fx,pass) ); + ( postfx_enabled(fx,pass) ? ui_enable : ui_disable )(); int rc = ui_shader(fx->pass[pass].program); - ui_enable( on ); + ( on ? ui_enable : ui_disable )(); return rc; } @@ -3417,16 +3484,12 @@ int ui_fxs() { if(!fx.num_loaded) return 0; int changed = 0; - int has_menu = ui_has_menubar(); - if( (has_menu ? ui_window("FX", 0) : ui_panel("FX", 0) ) ) { for( int i = 0; i < 64; ++i ) { 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); } - (has_menu ? ui_window_end : ui_panel_end)(); - } return changed; } diff --git a/engine/split/v4k_render.h b/engine/split/v4k_render.h index 994e594..afb4079 100644 --- a/engine/split/v4k_render.h +++ b/engine/split/v4k_render.h @@ -343,6 +343,9 @@ API void shader_destroy(unsigned shader); API unsigned shader_properties(unsigned shader); API char** shader_property(unsigned shader, unsigned property_no); +API void shader_apply_param(unsigned shader, unsigned param_no); +API void shader_apply_params(unsigned shader, const char *parameter_mask); + API int ui_shader(unsigned shader); API int ui_shaders(); @@ -387,12 +390,12 @@ API void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int // gpu memory barriers -/// Blocks main thread until all image operations are done by the GPU. -API void image_write_barrier(); - /// Blocks main thread until all memory operations are done by the GPU. API void write_barrier(); +/// Blocks main thread until all image operations are done by the GPU. +API void write_barrier_image(); + // ssbo /// `STATIC`, `DYNAMIC` AND `STREAM` specify the frequency at which we intend to access the data. /// `DRAW` favors CPU->GPU operations. diff --git a/engine/split/v4k_ui.c b/engine/split/v4k_ui.c index e6ed4d0..764b9a7 100644 --- a/engine/split/v4k_ui.c +++ b/engine/split/v4k_ui.c @@ -145,8 +145,8 @@ default_hue = 0.52; struct nk_color active = nk_hsv_f( 0.600, 0.00, 0.150); // bright b/w struct nk_color table[NK_COLOR_COUNT] = {0}; table[NK_COLOR_TEXT] = nk_rgba(210, 210, 210, 255); - table[NK_COLOR_WINDOW] = nk_rgba(42, 42, 42, 215); - table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 220); + table[NK_COLOR_WINDOW] = nk_rgba(42, 42, 42, 245); + table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 245); table[NK_COLOR_BORDER] = nk_rgba(46, 46, 46, 255); table[NK_COLOR_BUTTON] = main; table[NK_COLOR_BUTTON_HOVER] = hover; @@ -537,7 +537,7 @@ int ui_active() { } static -int ui_enable_(int enabled) { +int ui_set_enable_(int enabled) { static struct nk_style off, on; do_once { off = on = ui_ctx->style; @@ -775,8 +775,11 @@ int ui_enable_(int enabled) { } static int ui_is_enabled = 1; -int ui_enable(int on) { - return ui_is_enabled == on ? 0 : ui_enable_(ui_is_enabled = on); +int ui_enable() { + return ui_is_enabled == 1 ? 0 : ui_set_enable_(ui_is_enabled = 1); +} +int ui_disable() { + return ui_is_enabled == 0 ? 0 : ui_set_enable_(ui_is_enabled = 0); } int ui_enabled() { return ui_is_enabled; @@ -1558,6 +1561,20 @@ ui_label_icon_clicked_R.x = is_hovering ? ( (int)((input->mouse.pos.x - bounds.x return ui_label_icon_clicked_R.x; } +int ui_label2_bool(const char *text, bool value) { + bool b = !!value; + return ui_bool(text, &b), 0; +} +int ui_label2_float(const char *text, float value) { + float f = (float)value; + return ui_float(text, &f), 0; +} +int ui_label2_wrap(const char *label, const char *str) { // @fixme: does not work (remove dynamic layout?) + nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + ui_label_(label, NK_TEXT_LEFT); + nk_text_wrap(ui_ctx, str, strlen(str)); + return 0; +} int ui_label2_toolbar(const char *label, const char *icons) { int mouse_click = ui_label2(label, va(">%s", icons)); int choice = !mouse_click ? 0 : 1 + -mouse_click / (UI_ICON_FONTSIZE + UI_ICON_SPACING_X); // divided by px per ICON_MD_ glyph approximately @@ -1672,18 +1689,6 @@ int ui_button(const char *s) { return ui_buttons(1, s); } -int ui_const_bool(const char *text, const double value) { - bool b = !!value; - return ui_bool(text, &b), 0; -} -int ui_const_float(const char *text, const double value) { - float f = (float)value; - return ui_float(text, &f), 0; -} -int ui_const_string(const char *label, const char *text) { - return ui_label2(label, text); -} - int ui_toggle(const char *label, bool *value) { nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); ui_label_(label, NK_TEXT_LEFT); @@ -1947,13 +1952,6 @@ int ui_buffer(const char *label, char *buffer, int buflen) { return !!(active & NK_EDIT_COMMITED) ? nk_edit_unfocus(ui_ctx), 1 : 0; } -int ui_text_wrap(const char *label, char *text) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); - ui_label_(label, NK_TEXT_LEFT); - nk_text_wrap(ui_ctx, text, strlen(text)); - return 0; -} - int ui_string(const char *label, char **str) { char *bak = va("%s%c", *str ? *str : "", '\0'); int rc = ui_buffer(label, bak, strlen(bak)+2); @@ -2077,8 +2075,8 @@ int ui_dialog(const char *title, const char *text, int choices, bool *show) { // return *show; } -#define ui_bits_template(X) \ -int ui_bits##X(const char *label, uint##X##_t *enabled) { \ +#define ui_bitmask_template(X) \ +int ui_bitmask##X(const char *label, uint##X##_t *enabled) { \ /* @fixme: better way to retrieve widget width? nk_layout_row_dynamic() seems excessive */ \ nk_layout_row_dynamic(ui_ctx, 1, 1); \ struct nk_rect bounds = nk_widget_bounds(ui_ctx); \ @@ -2109,9 +2107,9 @@ int ui_bits##X(const char *label, uint##X##_t *enabled) { \ return copy ^ *enabled; \ } -ui_bits_template(8); -ui_bits_template(16); -//ui_bits_template(32); +ui_bitmask_template(8); +ui_bitmask_template(16); +//ui_bitmask_template(32); int ui_console() { // @fixme: buggy static char *cmd = 0; @@ -2272,13 +2270,15 @@ 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_enable(0); + if( disable_all ) ui_disable(); if( ui_browse(&browsed_file, &show_browser) ) puts(browsed_file); if( ui_section("Labels")) {} if( ui_label("my label")) {} if( ui_label("my label with tooltip@built on " __DATE__ " " __TIME__)) {} + if( ui_label2_toolbar("my toolbar", ICON_MD_STAR ICON_MD_STAR_OUTLINE ICON_MD_BOOKMARK ICON_MD_BOOKMARK_BORDER) ) {} + //if( ui_label2_wrap("my long label", "and some long long long long text wrapped")) {} if( ui_section("Types")) {} if( ui_bool("my bool", &boolean) ) puts("bool changed"); @@ -2311,7 +2311,7 @@ int ui_demo(int do_windows) { } if( ui_section("Others")) {} - if( ui_bits8("my bitmask", &bitmask) ) printf("bitmask changed %x\n", bitmask); + if( ui_bitmask8("my bitmask", &bitmask) ) printf("bitmask changed %x\n", bitmask); if( ui_toggle("my toggle", &toggle) ) printf("toggle %s\n", toggle ? "on":"off"); if( ui_image("my image", texture_checker().id, 0, 0) ) { puts("image clicked"); } @@ -2321,7 +2321,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(1); + if( disable_all ) ui_enable(); // restore enabled state ui_panel_end(); } diff --git a/engine/split/v4k_ui.h b/engine/split/v4k_ui.h index 6c71ec7..129c24b 100644 --- a/engine/split/v4k_ui.h +++ b/engine/split/v4k_ui.h @@ -25,7 +25,6 @@ API int ui_float4(const char *label, float value[4]); API int ui_double(const char *label, double *value); API int ui_buffer(const char *label, char *buffer, int buflen); API int ui_string(const char *label, char **string); -API int ui_text_wrap(const char *label, char *text); API int ui_color3(const char *label, float *color3); //[0..255] API int ui_color3f(const char *label, float *color3); //[0..1] API int ui_color4(const char *label, float *color4); //[0..255] @@ -47,18 +46,17 @@ API int ui_image(const char *label, handle id, unsigned w, unsigned h); //(w, API int ui_subimage(const char *label, handle id, unsigned iw, unsigned ih, unsigned sx, unsigned sy, unsigned sw, unsigned sh); API int ui_colormap(const char *label, colormap_t *cm); // returns num member changed: 1 for color, 2 for texture map API int ui_separator(); -API int ui_bits8(const char *label, uint8_t *bits); -API int ui_bits16(const char *label, uint16_t *bits); +API int ui_bitmask8(const char *label, uint8_t *bits); +API int ui_bitmask16(const char *label, uint16_t *bits); API int ui_console(); API int ui_clampf(const char *label, float *value, float minf, float maxf); API int ui_label(const char *label); API int ui_label2(const char *label, const char *caption); +API int ui_label2_bool(const char *label, bool enabled); +API int ui_label2_float(const char *label, float value); API int ui_label2_toolbar(const char *label, const char *icons); API int ui_slider(const char *label, float *value); API int ui_slider2(const char *label, float *value, const char *caption); -API int ui_const_bool(const char *label, const double value); -API int ui_const_float(const char *label, const double value); -API int ui_const_string(const char *label, const char *value); API int ui_contextual_end(); API int ui_collapse_clicked(); API int ui_collapse_end(); @@ -68,10 +66,12 @@ 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(int on); -API int ui_enabled(); API vec2 ui_get_dims(); +API int ui_enable(); +API int ui_enabled(); +API int ui_disable(); + API int ui_has_menubar(); API int ui_menu(const char *items); // semicolon-separated or comma-separated items API int ui_menu_editbox(char *buf, int bufcap); diff --git a/engine/split/v4k_window.c b/engine/split/v4k_window.c index d1b752f..65e2f28 100644 --- a/engine/split/v4k_window.c +++ b/engine/split/v4k_window.c @@ -356,7 +356,7 @@ bool window_create_from_handle(void *handle, float scale, unsigned flags) { #if is(ems) if( FLAGS_FULLSCREEN ) window_fullscreen(1); #else - gladLoadGL(glfwGetProcAddress); + int gl_version = gladLoadGL(glfwGetProcAddress); #endif glDebugEnable(); @@ -380,6 +380,8 @@ bool window_create_from_handle(void *handle, float scale, unsigned flags) { PRINTF("GPU driver: %s\n", glGetString(GL_VERSION)); #if !is(ems) + PRINTF("GPU OpenGL: %d.%d\n", GLAD_VERSION_MAJOR(gl_version), GLAD_VERSION_MINOR(gl_version)); + if( FLAGS_TRANSPARENT ) { // @transparent glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_FALSE); if( scale >= 1 ) glfwMaximizeWindow(window); @@ -508,10 +510,51 @@ int window_frame_begin() { ui_create(); - profile_render(); + bool may_render_stats = 1; - ui_shaders(); + int has_menu = ui_has_menubar(); + if( !has_menu ) { + static int cook_on_demand; do_once cook_on_demand = COOK_ON_DEMAND; + if( !cook_on_demand ) { + // render profiler, unless we are in the cook progress screen + static unsigned frames = 0; if(frames <= 0) frames += cook_progress() >= 100; + may_render_stats = (frames > 0); + } + } + + // @transparent + static bool has_transparent_attrib = 0; do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE; + if( has_transparent_attrib ) may_render_stats = 0; + // @transparent + + // generate Debug panel contents + if( may_render_stats ) { + if( has_menu ? ui_window("Debug", 0) : ui_panel("Debug", 0) ) { + + int open = 0, clicked_or_toggled = 0; + + for( int p = (open = ui_collapse("FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_fxs(); + } + for( int p = (open = ui_collapse("Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_profiler(); + } + for( int p = (open = ui_collapse("Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_shaders(); + } + for( int p = (open = ui_collapse("Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + for( int p = (open = ui_collapse("Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + for( int p = (open = ui_collapse("Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + + (has_menu ? ui_window_end : ui_panel_end)(); + } + } #if 0 // deprecated // run user-defined hooks diff --git a/engine/v4k.c b/engine/v4k.c index 8b0d1c4..a3b95c7 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -1346,6 +1346,9 @@ float audio_volume_master(float gain) { } int audio_play_gain_pitch_pan( audio_t a, int flags, float gain, float pitch, float pan ) { + static bool muted = 0; do_once muted = flag("--mute") || flag("--muted"); + if(muted) return 1; + if( flags & AUDIO_IGNORE_MIXER_GAIN ) { // do nothing, gain used as-is } else { @@ -3740,6 +3743,7 @@ int cook_jobs() { void cook_config( const char *pathfile_to_cook_ini ) { // @todo: test run-from-"bin/" case on Linux. COOK_INI = pathfile_to_cook_ini; + ASSERT( file_exist(COOK_INI) ); } #line 0 @@ -8143,32 +8147,37 @@ bool input_touch_active() { void input_demo() { if( ui_panel("Input",0) ) { ui_section("Keyboard"); - ui_const_bool("[Key 1]", input(KEY_1)); - ui_const_bool("[Key 2]", input(KEY_2)); - ui_const_bool("[Key 3]", input(KEY_3)); - ui_const_bool("[Key 4]", input(KEY_4)); - ui_const_bool("[Key 5]", input(KEY_5)); - ui_const_bool("[Key 6]", input(KEY_6)); - ui_const_bool("[Key 7]", input(KEY_7)); + + uint8_t keymap = 0; + keymap |= (!!input(KEY_1)) << 7; + keymap |= (!!input(KEY_2)) << 6; + keymap |= (!!input(KEY_3)) << 5; + keymap |= (!!input(KEY_4)) << 4; + keymap |= (!!input(KEY_5)) << 3; + keymap |= (!!input(KEY_6)) << 2; + keymap |= (!!input(KEY_7)) << 1; + keymap |= (!!input(KEY_8)) << 0; + ui_bitmask8("[Keys 1..8]", &keymap); + ui_separator(); - ui_const_bool("[Key 1] Down event", input_down(KEY_1) ); - ui_const_bool("[Key 2] Held event", input_held(KEY_2) ); - ui_const_bool("[Key 3] Up event", input_up(KEY_3) ); - ui_const_bool("[Key 4] Idle event", input_idle(KEY_4) ); - ui_const_bool("[Key 5] Click event", input_click(KEY_5,500) ); - ui_const_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); - ui_const_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); + ui_label2_bool("[Key 1] Down event", input_down(KEY_1) ); + ui_label2_bool("[Key 2] Held event", input_held(KEY_2) ); + ui_label2_bool("[Key 3] Up event", input_up(KEY_3) ); + ui_label2_bool("[Key 4] Idle event", input_idle(KEY_4) ); + ui_label2_bool("[Key 5] Click event", input_click(KEY_5,500) ); + ui_label2_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); + ui_label2_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); ui_separator(); ui_section("Mouse"); - ui_const_float("X", input(MOUSE_X)); - ui_const_float("Y", input(MOUSE_Y)); + ui_label2_float("X", input(MOUSE_X)); + ui_label2_float("Y", input(MOUSE_Y)); ui_separator(); - ui_const_float("Wheel", input(MOUSE_W)); + ui_label2_float("Wheel", input(MOUSE_W)); ui_separator(); - ui_const_bool("Left", input(MOUSE_L)); - ui_const_bool("Middle", input(MOUSE_M)); - ui_const_bool("Right", input(MOUSE_R)); + ui_label2_bool("Left", input(MOUSE_L)); + ui_label2_bool("Middle", input(MOUSE_M)); + ui_label2_bool("Right", input(MOUSE_R)); ui_separator(); for( int i = 0; i <= CURSOR_SW_AUTO; ++i ) if(ui_button(va("Cursor shape #%d", i))) window_cursor_shape(i); ui_separator(); @@ -8180,45 +8189,45 @@ void input_demo() { input_use(gamepad_id); - ui_const_string("Name", input_frames(GAMEPAD_NAME,0)); - ui_const_bool("Connected", input(GAMEPAD_CONNECTED)); + ui_label2("Name", input_frames(GAMEPAD_NAME,0)); + ui_label2_bool("Connected", input(GAMEPAD_CONNECTED)); ui_separator(); - ui_const_bool("A", input(GAMEPAD_A) ); - ui_const_bool("B", input(GAMEPAD_B) ); - ui_const_bool("X", input(GAMEPAD_X) ); - ui_const_bool("Y", input(GAMEPAD_Y) ); - ui_const_bool("Up", input(GAMEPAD_UP) ); - ui_const_bool("Down", input(GAMEPAD_DOWN) ); - ui_const_bool("Left", input(GAMEPAD_LEFT) ); - ui_const_bool("Right", input(GAMEPAD_RIGHT) ); - ui_const_bool("Menu", input(GAMEPAD_MENU) ); - ui_const_bool("Start", input(GAMEPAD_START) ); + ui_label2_bool("A", input(GAMEPAD_A) ); + ui_label2_bool("B", input(GAMEPAD_B) ); + ui_label2_bool("X", input(GAMEPAD_X) ); + ui_label2_bool("Y", input(GAMEPAD_Y) ); + ui_label2_bool("Up", input(GAMEPAD_UP) ); + ui_label2_bool("Down", input(GAMEPAD_DOWN) ); + ui_label2_bool("Left", input(GAMEPAD_LEFT) ); + ui_label2_bool("Right", input(GAMEPAD_RIGHT) ); + ui_label2_bool("Menu", input(GAMEPAD_MENU) ); + ui_label2_bool("Start", input(GAMEPAD_START) ); ui_separator(); - ui_const_float("Left pad x", input(GAMEPAD_LPADX) ); - ui_const_float("Left pad y", input(GAMEPAD_LPADY) ); - ui_const_float("Left trigger", input(GAMEPAD_LT) ); - ui_const_bool("Left bumper", input(GAMEPAD_LB) ); - ui_const_bool("Left thumb", input(GAMEPAD_LTHUMB) ); + ui_label2_float("Left pad x", input(GAMEPAD_LPADX) ); + ui_label2_float("Left pad y", input(GAMEPAD_LPADY) ); + ui_label2_float("Left trigger", input(GAMEPAD_LT) ); + ui_label2_bool("Left bumper", input(GAMEPAD_LB) ); + ui_label2_bool("Left thumb", input(GAMEPAD_LTHUMB) ); vec2 v = input_filter_deadzone( input2(GAMEPAD_LPADX), 0.1f ); - ui_const_float("Filtered pad x", v.x); - ui_const_float("Filtered pad y", v.y); + ui_label2_float("Filtered pad x", v.x); + ui_label2_float("Filtered pad y", v.y); ui_separator(); - ui_const_float("Right pad x", input(GAMEPAD_RPADX) ); - ui_const_float("Right pad y", input(GAMEPAD_RPADY) ); - ui_const_float("Right trigger", input(GAMEPAD_RT) ); - ui_const_bool("Right bumper", input(GAMEPAD_RB) ); - ui_const_bool("Right thumb", input(GAMEPAD_RTHUMB) ); + ui_label2_float("Right pad x", input(GAMEPAD_RPADX) ); + ui_label2_float("Right pad y", input(GAMEPAD_RPADY) ); + ui_label2_float("Right trigger", input(GAMEPAD_RT) ); + ui_label2_bool("Right bumper", input(GAMEPAD_RB) ); + ui_label2_bool("Right thumb", input(GAMEPAD_RTHUMB) ); vec2 w = input_filter_deadzone( input2(GAMEPAD_RPADX), 0.1f ); - ui_const_float("Filtered pad x", w.x); - ui_const_float("Filtered pad y", w.y); + ui_label2_float("Filtered pad x", w.x); + ui_label2_float("Filtered pad y", w.y); input_use(0); @@ -10516,22 +10525,23 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char 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)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if(fs) for each_substring(fs, "\r\n", line) { - if( strstr(line, "/""//") && !strbeg(line,"//") ) { - array_push(props, STRDUP(line)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if(gs) for each_substring(gs, "\r\n", line) { - if( strstr(line, "/""//") && !strbeg(line,"//") ) { - array_push(props, STRDUP(line)); - } + const char *found = strstr(line, "/""//"); + if( found > line && line[0] == '/' && line[1] == '/' ) continue; + if( found ) array_push(props, STRDUP(line)); } if( props ) { map_insert(shader_reflect, program, props); + for( int i = 0; i < array_count(props); ++i ) shader_apply_param(program, i); } return program; @@ -10544,7 +10554,60 @@ unsigned shader_properties(unsigned shader) { char** shader_property(unsigned shader, unsigned property) { array(char*) *found = map_find(shader_reflect, shader); - return found ? &(*found)[property] : NULL; + return found && property < array_count(*found) ? &(*found)[property] : NULL; +} + +void shader_apply_param(unsigned shader, unsigned param_no) { + unsigned num_properties = shader_properties(shader); + if( param_no < num_properties ) { + char *line = *shader_property(shader, param_no); + + char type[32], name[32]; + if( sscanf(line, "%*s %s %[^ =;/]", type, name) != 2 ) return; + + 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); + + 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); + + if( !strstr(line, "max:") ) { + if(setv.x > maxv.x) maxv.x = setv.x; + if(setv.y > maxv.y) maxv.y = setv.y; + if(setv.z > maxv.z) maxv.z = setv.z; + if(setv.w > maxv.w) maxv.w = setv.w; + } + + setv = clamp4(setv, minv, maxv); + + if( strchr("ibfv", type[0]) ) { + 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] == 'b') 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); + } + } +} + +void shader_apply_params(unsigned shader, const char *parameter_mask) { + unsigned num_properties = shader_properties(shader); + for( unsigned i = 0; i < num_properties; ++i ) { + char *line = *shader_property(shader,i); + + char name[32]; + if( sscanf(line, "%*s %*s %s", name) != 1 ) continue; + if( !strmatch(name, parameter_mask) ) continue; + shader_apply_param(shader, i); + } } int ui_shader(unsigned shader) { @@ -10555,25 +10618,43 @@ int ui_shader(unsigned shader) { 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; + char* tip = strstr(line, "tip:"); tip = tip && tip[4] ? tip + 4 : 0; + + char uniform[32], type[32], name[32], early_exit = '\0'; + if( sscanf(line, "%s %s %[^ =;/]", uniform, type, name) != 3 ) continue; // @todo optimize: move to shader() + if( strcmp(uniform, "uniform") && strcmp(uniform, "}uniform") ) { if(tip) ui_label(va(ICON_MD_INFO "%s", tip)); continue; } // @todo optimize: move to shader() 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); + va("%c%s " ICON_MD_INFO "@%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); + if(minv.x > maxv.x) swapf(&minv.x, &maxv.x); // @optimize: move to shader() + if(minv.y > maxv.y) swapf(&minv.y, &maxv.y); // @optimize: move to shader() + if(minv.z > maxv.z) swapf(&minv.z, &maxv.z); // @optimize: move to shader() + if(minv.w > maxv.w) swapf(&minv.w, &maxv.w); // @optimize: move to shader() + + if( !strstr(line, "max:") ) { + if(setv.x > maxv.x) maxv.x = setv.x; + if(setv.y > maxv.y) maxv.y = setv.y; + if(setv.z > maxv.z) maxv.z = setv.z; + if(setv.w > maxv.w) maxv.w = setv.w; + } + + setv = clamp4(setv, minv, maxv); // supports int,float,vec2/3/4,color3/4 int touched = 0; - if( type[0] == 'i' ) { + if( type[0] == 'b' ) { + bool v = !!setv.x; + + if( (touched = ui_bool(label, &v)) != 0 ) { + setv.x = v; + } + } + else if( type[0] == 'i' ) { int v = setv.x; if( (touched = ui_int(label, &v)) != 0 ) { @@ -10581,9 +10662,11 @@ int ui_shader(unsigned shader) { } } else if( type[0] == 'f' ) { - setv.x = (clampf(setv.x, minv.x, maxv.x) - minv.x) / (maxv.x - minv.x); + setv.x = clampf(setv.x, minv.x, maxv.x); + char *caption = va("%5.2f", setv.x); + setv.x = (setv.x - minv.x) / (maxv.x - minv.x); - if( (touched = ui_slider2(label, &setv.x, va("%5.2f", setv.x))) != 0 ) { + if( (touched = ui_slider2(label, &setv.x, caption)) != 0 ) { setv.x = clampf(minv.x + setv.x * (maxv.x-minv.x), minv.x, maxv.x); // min..max range } } @@ -10608,28 +10691,20 @@ int ui_shader(unsigned shader) { setv = clamp4(setv,minv,maxv); } } + else if( tip ) ui_label( tip ); 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:""); + // apply + shader_apply_param(shader, i); + changed = 1; } } - if(num_properties) ui_separator(); - return changed; } @@ -10637,13 +10712,14 @@ int ui_shaders() { if( !map_count(shader_reflect) ) return 0; 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)); + int open = 0, clicked_or_toggled = 0; + char *id = va("##SHD%d", *k); + char *title = va("Shader %d", *k); + for( int p = (open = ui_collapse(title, id)), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_label(va("Shader %d",*k)); changed |= ui_shader(*k); } - (has_menu ? ui_window_end : ui_panel_end)(); } return changed; } @@ -10698,7 +10774,7 @@ void write_barrier(){ glMemoryBarrier(GL_ALL_BARRIER_BITS); } -void image_write_barrier(){ +void write_barrier_image(){ glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } @@ -13556,9 +13632,9 @@ void postfx_clear(postfx *fx) { int ui_postfx(postfx *fx, int pass) { int on = ui_enabled(); - ui_enable( postfx_enabled(fx,pass) ); + ( postfx_enabled(fx,pass) ? ui_enable : ui_disable )(); int rc = ui_shader(fx->pass[pass].program); - ui_enable( on ); + ( on ? ui_enable : ui_disable )(); return rc; } @@ -13739,16 +13815,12 @@ int ui_fxs() { if(!fx.num_loaded) return 0; int changed = 0; - int has_menu = ui_has_menubar(); - if( (has_menu ? ui_window("FX", 0) : ui_panel("FX", 0) ) ) { for( int i = 0; i < 64; ++i ) { 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); } - (has_menu ? ui_window_end : ui_panel_end)(); - } return changed; } @@ -17786,8 +17858,8 @@ default_hue = 0.52; struct nk_color active = nk_hsv_f( 0.600, 0.00, 0.150); // bright b/w struct nk_color table[NK_COLOR_COUNT] = {0}; table[NK_COLOR_TEXT] = nk_rgba(210, 210, 210, 255); - table[NK_COLOR_WINDOW] = nk_rgba(42, 42, 42, 215); - table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 220); + table[NK_COLOR_WINDOW] = nk_rgba(42, 42, 42, 245); + table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 245); table[NK_COLOR_BORDER] = nk_rgba(46, 46, 46, 255); table[NK_COLOR_BUTTON] = main; table[NK_COLOR_BUTTON_HOVER] = hover; @@ -18178,7 +18250,7 @@ int ui_active() { } static -int ui_enable_(int enabled) { +int ui_set_enable_(int enabled) { static struct nk_style off, on; do_once { off = on = ui_ctx->style; @@ -18416,8 +18488,11 @@ int ui_enable_(int enabled) { } static int ui_is_enabled = 1; -int ui_enable(int on) { - return ui_is_enabled == on ? 0 : ui_enable_(ui_is_enabled = on); +int ui_enable() { + return ui_is_enabled == 1 ? 0 : ui_set_enable_(ui_is_enabled = 1); +} +int ui_disable() { + return ui_is_enabled == 0 ? 0 : ui_set_enable_(ui_is_enabled = 0); } int ui_enabled() { return ui_is_enabled; @@ -19199,6 +19274,20 @@ ui_label_icon_clicked_R.x = is_hovering ? ( (int)((input->mouse.pos.x - bounds.x return ui_label_icon_clicked_R.x; } +int ui_label2_bool(const char *text, bool value) { + bool b = !!value; + return ui_bool(text, &b), 0; +} +int ui_label2_float(const char *text, float value) { + float f = (float)value; + return ui_float(text, &f), 0; +} +int ui_label2_wrap(const char *label, const char *str) { // @fixme: does not work (remove dynamic layout?) + nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + ui_label_(label, NK_TEXT_LEFT); + nk_text_wrap(ui_ctx, str, strlen(str)); + return 0; +} int ui_label2_toolbar(const char *label, const char *icons) { int mouse_click = ui_label2(label, va(">%s", icons)); int choice = !mouse_click ? 0 : 1 + -mouse_click / (UI_ICON_FONTSIZE + UI_ICON_SPACING_X); // divided by px per ICON_MD_ glyph approximately @@ -19313,18 +19402,6 @@ int ui_button(const char *s) { return ui_buttons(1, s); } -int ui_const_bool(const char *text, const double value) { - bool b = !!value; - return ui_bool(text, &b), 0; -} -int ui_const_float(const char *text, const double value) { - float f = (float)value; - return ui_float(text, &f), 0; -} -int ui_const_string(const char *label, const char *text) { - return ui_label2(label, text); -} - int ui_toggle(const char *label, bool *value) { nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); ui_label_(label, NK_TEXT_LEFT); @@ -19588,13 +19665,6 @@ int ui_buffer(const char *label, char *buffer, int buflen) { return !!(active & NK_EDIT_COMMITED) ? nk_edit_unfocus(ui_ctx), 1 : 0; } -int ui_text_wrap(const char *label, char *text) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); - ui_label_(label, NK_TEXT_LEFT); - nk_text_wrap(ui_ctx, text, strlen(text)); - return 0; -} - int ui_string(const char *label, char **str) { char *bak = va("%s%c", *str ? *str : "", '\0'); int rc = ui_buffer(label, bak, strlen(bak)+2); @@ -19718,8 +19788,8 @@ int ui_dialog(const char *title, const char *text, int choices, bool *show) { // return *show; } -#define ui_bits_template(X) \ -int ui_bits##X(const char *label, uint##X##_t *enabled) { \ +#define ui_bitmask_template(X) \ +int ui_bitmask##X(const char *label, uint##X##_t *enabled) { \ /* @fixme: better way to retrieve widget width? nk_layout_row_dynamic() seems excessive */ \ nk_layout_row_dynamic(ui_ctx, 1, 1); \ struct nk_rect bounds = nk_widget_bounds(ui_ctx); \ @@ -19750,9 +19820,9 @@ int ui_bits##X(const char *label, uint##X##_t *enabled) { \ return copy ^ *enabled; \ } -ui_bits_template(8); -ui_bits_template(16); -//ui_bits_template(32); +ui_bitmask_template(8); +ui_bitmask_template(16); +//ui_bitmask_template(32); int ui_console() { // @fixme: buggy static char *cmd = 0; @@ -19913,13 +19983,15 @@ 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_enable(0); + if( disable_all ) ui_disable(); if( ui_browse(&browsed_file, &show_browser) ) puts(browsed_file); if( ui_section("Labels")) {} if( ui_label("my label")) {} if( ui_label("my label with tooltip@built on " __DATE__ " " __TIME__)) {} + if( ui_label2_toolbar("my toolbar", ICON_MD_STAR ICON_MD_STAR_OUTLINE ICON_MD_BOOKMARK ICON_MD_BOOKMARK_BORDER) ) {} + //if( ui_label2_wrap("my long label", "and some long long long long text wrapped")) {} if( ui_section("Types")) {} if( ui_bool("my bool", &boolean) ) puts("bool changed"); @@ -19952,7 +20024,7 @@ int ui_demo(int do_windows) { } if( ui_section("Others")) {} - if( ui_bits8("my bitmask", &bitmask) ) printf("bitmask changed %x\n", bitmask); + if( ui_bitmask8("my bitmask", &bitmask) ) printf("bitmask changed %x\n", bitmask); if( ui_toggle("my toggle", &toggle) ) printf("toggle %s\n", toggle ? "on":"off"); if( ui_image("my image", texture_checker().id, 0, 0) ) { puts("image clicked"); } @@ -19962,7 +20034,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(1); + if( disable_all ) ui_enable(); // restore enabled state ui_panel_end(); } @@ -20054,30 +20126,14 @@ int ui_demo(int do_windows) { profiler_t profiler; int profiler_enabled = 1; -void (profile_init)() { map_init(profiler, less_str, hash_str); profiler_enabled &= !!profiler; } -int (profile_enable)(bool on) { return profiler_enabled = on; } -void (profile_render)() { - // @transparent - static bool has_transparent_attrib = 0; do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE; - if( has_transparent_attrib ) return; - // @transparent - - int has_menu = ui_has_menubar(); - if( !has_menu ) { - static int cook_on_demand; do_once cook_on_demand = COOK_ON_DEMAND; - if( !cook_on_demand ) { - // render profiler, unless we are in the cook progress screen - static unsigned frames = 0; if(frames <= 0) frames += cook_progress() >= 100; - if( frames <= 0 ) return; - } - } - - if( has_menu ? ui_window("Profiler", 0) : ui_panel("Profiler", 0) ) { +void (profiler_init)() { map_init(profiler, less_str, hash_str); profiler_enabled &= !!profiler; } +int (profiler_enable)(bool on) { return profiler_enabled = on; } +void (ui_profiler)() { + // @todo: ui_plot() double fps = window_fps(); profile_setstat("Render.num_fps", fps); - if(1) { // @todo: ui_plot() // draw fps-meter: 300 samples, [0..70] range each, 70px height plot. nk_layout_row_dynamic(ui_ctx, 70, 1); @@ -20106,7 +20162,6 @@ void (profile_render)() { if( index >= 0 ) { nk_tooltipf(ui_ctx, "%.2f fps", (float)values[index]); } - } for each_map_ptr_sorted(profiler, const char *, key, struct profile_t, val ) { if( isnan(val->stat) ) { @@ -20117,9 +20172,6 @@ void (profile_render)() { ui_slider2(*key, &v, va("%.2f", val->stat)); val->stat = 0; } - } - - (has_menu ? ui_window_end : ui_panel_end)(); } } #endif @@ -20716,7 +20768,7 @@ bool window_create_from_handle(void *handle, float scale, unsigned flags) { #if is(ems) if( FLAGS_FULLSCREEN ) window_fullscreen(1); #else - gladLoadGL(glfwGetProcAddress); + int gl_version = gladLoadGL(glfwGetProcAddress); #endif glDebugEnable(); @@ -20740,6 +20792,8 @@ bool window_create_from_handle(void *handle, float scale, unsigned flags) { PRINTF("GPU driver: %s\n", glGetString(GL_VERSION)); #if !is(ems) + PRINTF("GPU OpenGL: %d.%d\n", GLAD_VERSION_MAJOR(gl_version), GLAD_VERSION_MINOR(gl_version)); + if( FLAGS_TRANSPARENT ) { // @transparent glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_FALSE); if( scale >= 1 ) glfwMaximizeWindow(window); @@ -20868,10 +20922,51 @@ int window_frame_begin() { ui_create(); - profile_render(); + bool may_render_stats = 1; - ui_shaders(); + int has_menu = ui_has_menubar(); + if( !has_menu ) { + static int cook_on_demand; do_once cook_on_demand = COOK_ON_DEMAND; + if( !cook_on_demand ) { + // render profiler, unless we are in the cook progress screen + static unsigned frames = 0; if(frames <= 0) frames += cook_progress() >= 100; + may_render_stats = (frames > 0); + } + } + + // @transparent + static bool has_transparent_attrib = 0; do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE; + if( has_transparent_attrib ) may_render_stats = 0; + // @transparent + + // generate Debug panel contents + if( may_render_stats ) { + if( has_menu ? ui_window("Debug", 0) : ui_panel("Debug", 0) ) { + + int open = 0, clicked_or_toggled = 0; + + for( int p = (open = ui_collapse("FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_fxs(); + } + for( int p = (open = ui_collapse("Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_profiler(); + } + for( int p = (open = ui_collapse("Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_shaders(); + } + for( int p = (open = ui_collapse("Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + for( int p = (open = ui_collapse("Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + for( int p = (open = ui_collapse("Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + + } + + (has_menu ? ui_window_end : ui_panel_end)(); + } + } #if 0 // deprecated // run user-defined hooks @@ -22884,22 +22979,20 @@ int main() { // ---------------------------------------------------------------------------- static void v4k_pre_init() { - window_icon(va("%s.png", app_name())); - ifdef(win32,window_icon(va("%s.ico", app_name()))); + const char *appname = app_name(); + window_icon(va("%s.png", appname)); + ifdef(win32,window_icon(va("%s.ico", appname))); glfwPollEvents(); int i; -#if 1 // #ifdef PARALLEL_INIT #pragma omp parallel for -#endif for( i = 0; i <= 3; ++i) { /**/ if( i == 0 ) ddraw_init();// init this on thread#0 since it will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up else if( i == 1 ) sprite_init(); - else if( i == 2 ) profile_init(); + else if( i == 2 ) profiler_init(); else if( i == 3 ) storage_mount("save/"), storage_read(), touch_init(); // for ems } - ; // window_swap(); } diff --git a/engine/v4k.h b/engine/v4k.h index d9d29a0..d983ee4 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -309,14 +309,14 @@ extern "C" { // system headers #ifndef _GNU_SOURCE -#define _GNU_SOURCE // for linux +#define _GNU_SOURCE ///- for linux #endif #if is(cl) && is(win32) // for VC IDE -#define _CRT_SECURE_NO_WARNINGS -#define _CRT_NONSTDC_NO_DEPRECATE -#define _WINSOCK_DEPRECATED_NO_WARNINGS -#define _WIN32_WINNT 0x0600 // 0x0502 // GetInfoAddrW/FreeAddrInfoW for X86 +#define _CRT_SECURE_NO_WARNINGS ///- +#define _CRT_NONSTDC_NO_DEPRECATE ///- +#define _WINSOCK_DEPRECATED_NO_WARNINGS ///- +#define _WIN32_WINNT 0x0600 ///- 0x0502 // GetInfoAddrW/FreeAddrInfoW for X86 #endif #if is(cl) @@ -2428,9 +2428,9 @@ static __thread void *obj_tmpalloc; # define profile(section) for(int macro(i) = 1; macro(i); macro(i) = 0) # define profile_incstat(name, accum) do {} while(0) # define profile_setstat(name, value) do {} while(0) -# define profile_init() do {} while(0) -# define profile_render() do {} while(0) -# define profile_enable(x) 0 +# define profiler_init() do {} while(0) +# define profiler_enable(x) 0 +# define ui_profiler() do {} while(0) #else # define profile(section) for( \ struct profile_t *found = profiler_enabled ? \ @@ -2443,7 +2443,7 @@ static __thread void *obj_tmpalloc; # define profile_setstat(name, value) for( \ struct profile_t *found = profiler_enabled ? map_find_or_add(profiler, name, (struct profile_t){0}) : NULL; \ found; found->stat = value, found = NULL) ///+ -API int profile_enable(bool on); +API int profiler_enable(bool on); struct profile_t { double stat; int32_t cost, avg; }; ///- typedef map(char *, struct profile_t) profiler_t; ///- @@ -2798,6 +2798,9 @@ API void shader_destroy(unsigned shader); API unsigned shader_properties(unsigned shader); API char** shader_property(unsigned shader, unsigned property_no); +API void shader_apply_param(unsigned shader, unsigned param_no); +API void shader_apply_params(unsigned shader, const char *parameter_mask); + API int ui_shader(unsigned shader); API int ui_shaders(); @@ -2842,12 +2845,12 @@ API void shader_image_unit(unsigned texture, unsigned unit, unsigned level, int // gpu memory barriers -/// Blocks main thread until all image operations are done by the GPU. -API void image_write_barrier(); - /// Blocks main thread until all memory operations are done by the GPU. API void write_barrier(); +/// Blocks main thread until all image operations are done by the GPU. +API void write_barrier_image(); + // ssbo /// `STATIC`, `DYNAMIC` AND `STREAM` specify the frequency at which we intend to access the data. /// `DRAW` favors CPU->GPU operations. @@ -3568,7 +3571,6 @@ API int ui_float4(const char *label, float value[4]); API int ui_double(const char *label, double *value); API int ui_buffer(const char *label, char *buffer, int buflen); API int ui_string(const char *label, char **string); -API int ui_text_wrap(const char *label, char *text); API int ui_color3(const char *label, float *color3); //[0..255] API int ui_color3f(const char *label, float *color3); //[0..1] API int ui_color4(const char *label, float *color4); //[0..255] @@ -3590,18 +3592,17 @@ API int ui_image(const char *label, handle id, unsigned w, unsigned h); //(w, API int ui_subimage(const char *label, handle id, unsigned iw, unsigned ih, unsigned sx, unsigned sy, unsigned sw, unsigned sh); API int ui_colormap(const char *label, colormap_t *cm); // returns num member changed: 1 for color, 2 for texture map API int ui_separator(); -API int ui_bits8(const char *label, uint8_t *bits); -API int ui_bits16(const char *label, uint16_t *bits); +API int ui_bitmask8(const char *label, uint8_t *bits); +API int ui_bitmask16(const char *label, uint16_t *bits); API int ui_console(); API int ui_clampf(const char *label, float *value, float minf, float maxf); API int ui_label(const char *label); API int ui_label2(const char *label, const char *caption); +API int ui_label2_bool(const char *label, bool enabled); +API int ui_label2_float(const char *label, float value); API int ui_label2_toolbar(const char *label, const char *icons); API int ui_slider(const char *label, float *value); API int ui_slider2(const char *label, float *value, const char *caption); -API int ui_const_bool(const char *label, const double value); -API int ui_const_float(const char *label, const double value); -API int ui_const_string(const char *label, const char *value); API int ui_contextual_end(); API int ui_collapse_clicked(); API int ui_collapse_end(); @@ -3611,10 +3612,12 @@ 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(int on); -API int ui_enabled(); API vec2 ui_get_dims(); +API int ui_enable(); +API int ui_enabled(); +API int ui_disable(); + API int ui_has_menubar(); API int ui_menu(const char *items); // semicolon-separated or comma-separated items API int ui_menu_editbox(char *buf, int bufcap); diff --git a/hello.c b/hello.c index ad83a44..94e9de6 100644 --- a/hello.c +++ b/hello.c @@ -27,8 +27,7 @@ int main() { // animated models loading (no flags) model_t girl = model("kgirl/kgirls01.fbx", 0); - vec3 pos = vec3(0,0,0), sca = vec3(2,2,2), rot = vec3(-90,0,0); - compose44( girl.pivot, pos, eulerq(rot), sca); // position, rotation, scale + compose44( girl.pivot, vec3(0,0,0), eulerq(vec3(-90,0,0)), vec3(2,2,2)); // position, rotation, scale // camera camera_t cam = camera(); @@ -38,7 +37,7 @@ int main() { // audio (both clips & streams) audio_t SFX1 = audio_clip( "coin.wav" ), SFX2 = audio_clip( "pew.sfxr" ); - audio_t BGM1 = audio_stream( "waterworld-map.fur"), BGM2 = audio_stream( "larry.mid" ), BGM = BGM1; + audio_t BGM1 = audio_stream( "waterworld-map.fur" ), BGM2 = audio_stream( "larry.mid" ), BGM = BGM1; audio_play(SFX1, 0); audio_play(BGM, 0); @@ -60,18 +59,18 @@ int main() { camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); camera_fps(&cam, mouse.x,mouse.y); window_cursor( !active ); - - // debug draw - ddraw_grid(0); - if(do_debugdraw) ddraw_demo(); // showcase many debugdraw shapes - ddraw_flush(); - - // draw skybox - skybox_render(&sky, cam.proj, cam.view); // apply post-fxs from here fx_begin(); + // debug draw + ddraw_ground(0); + if(do_debugdraw) ddraw_demo(); // showcase many debugdraw shapes + ddraw_flush(); + + // draw skybox + skybox_render(&sky, cam.proj, cam.view); + // animate girl float delta = window_delta() * 30; // 30fps anim girl.curframe = model_animate(girl, girl.curframe + delta); @@ -82,10 +81,6 @@ int main() { // post-fxs end here fx_end(); - gizmo(&pos, &rot, &sca); - model_render_skeleton(girl, girl.pivot); - compose44( girl.pivot, pos, eulerq(rot), sca); // position, rotation, scale - // font demo font_print(va(FONT_BOTTOM FONT_RIGHT FONT_H6 "%5.2f FPS", window_fps())); @@ -115,12 +110,6 @@ int main() { if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(SFX1, 0); if( ui_label2_toolbar("SFX: Pew", ICON_MD_VOLUME_UP)) audio_play(SFX2, 0); - ui_section("FX"); - for( int i = 0, on; i < 64 && fx_name(i); ++i ) { - bool enabled = fx_enabled(i); - if( ui_bool(fx_name(i), &enabled) ) fx_enable(i, enabled); - } - ui_panel_end(); } }