Giter Site home page Giter Site logo

r-lyeh / fwk.2022 Goto Github PK

View Code? Open in Web Editor NEW
498.0 19.0 30.0 444.26 MB

💎 3D game engine/framework in C, with Luajit and Python bindings now.

Home Page: https://bit.ly/fwk2023

Shell 0.05% C 57.76% GLSL 0.63% Lua 1.15% C++ 26.50% Python 0.02% CSS 0.03% HTML 12.15% Roff 1.71% Makefile 0.01% Batchfile 0.01% Assembly 0.01% CMake 0.01%
public-domain gamedev 3d 2d game-framework c assimp game-engine unlicense lua game-development luajit pbr 3d-engine 3d-graphics python game-editor

fwk.2022's Introduction

3D game framework in C, with Luajit and Python bindings now.
Archived repo. Development moved to https://github.com/r-lyeh/FWK


Goals

  • C++. C.
  • Fast. Naive.
  • Modern. Simple.
  • Full featured. Small.
  • Rich build system. Single file.
  • Royaltie fee. Free and unlicensed.

Features ᕦ(ᐛ)ᕤ

  • Pipeline: configurable and integrated asset pipeline.
  • Embedded: single-file header, all dependencies included.
  • Projects: Visual Studio, XCode, Ninja, gmake.
  • Compiler: MSVC, MINGW64, TCC, GCC, clang, clang-cl and emscripten.
  • Linkage: Both static linkage and dynamic .dll/.so/.dylib support.
  • Platform: Windows, Linux and OSX. Partial HTML5/Web support.
  • DS: hash, sort, array/vector, map, set.
  • Math: rand, noise, ease, vec2/3/4, mat33/34/44, quat.
  • Geometry: ray, line, plane, aabb, sphere, capsule, triangle, poly and frustum.
  • Window: windowed, soft/hard fullscreen, msaa, icon, cursor handling.
  • Input: keyboard, mouse and gamepads.
  • Script: Lua scripting, Luajit bindings.
  • Network: downloads (HTTPS) and sockets (TCP/UDP).
  • AI: Swarm/Boids.
  • UI: button, list, slider, toggle, checkbox, editbox, dialog, color, image, menu, window, notify...
  • Font: TTF, OTF and TTC. Basic syntax highlighter. Glyph ranges. Atlasing.
  • Localization/I18N: XLSX and INI. Unicode.
  • Image: JPG, PNG, BMP, PSD, PIC, PNM, ICO.
  • Texture: KTX/2, PVR, DDS, ASTC, BASIS, HDR, TGA.
  • Texel: Depth, R, RG, RGB, RGBA, BC1/2/3/4/5/6/7, PVRI/II, ETC1/2, ASTC.
  • Audio: WAV/FLAC, OGG/MP1/MP3, FUR, MOD/XM/S3M/IT, SFXR and MID+SF2/SF3.
  • Video: MP4, MPG, OGV, MKV, WMV and AVI. Also, MP4 recording with MPEG-1 fallback.
  • Model: IQM/E, GLTF/2, GLB, FBX, OBJ, DAE, BLEND, MD3/5, MS3D, SMD, X, 3DS, BVH, DXF, LWO.
  • Render: PBR (metallic-roughness) workflow.
  • Render: Cubemaps, panoramas and spherical harmonics. Rayleigh/Mie scattering.
  • Render: Post-effects (SSAO,FXAA1/3,CRT,Contrast,Grain,Outline,Vignette...).
  • Render: 3D Anims, skeletal anims, hardware skinning and instanced rendering.
  • Render: 3D Debugdraw, batching and vectorial font.
  • Render: 2D Sprites, spritesheets, AA zooming and batching.
  • Render: 2D Tilemaps and tilesets: TMX, TSX.
  • Compression: DEFLATE, LZMA, LZ4, ULZ, BALZ, BCM, CRUSH, LZW3, LZSS and PPP.
  • Virtual filesystem: ZIP, PAK, TAR and DIR.
  • Level data: JSON, JSON5, SJSON, XML, INI.
  • Disk cache.
  • Scene handling.
  • Profiler, stats and leaks finder.
  • Editor (wip).
  • Documentation (wip).

Hello FWK

#include "fwk.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 FWK from C!");
    }
}
#include "fwk.h" // Minimal HTML5 sample
void render(void *arg) {
    if( !input(KEY_ESC) ) puts("hello FWK from HTML5!");
}
int main() {
    window_create(75.0, 0); // 75% size, no extra flags
    window_loop(render, NULL); // game loop
}
local fwk = require("fwk") -- Minimal Lua sample
fwk.window_create(75.0,0) -- 75% size, no extra flags
while fwk.window_swap() and fwk.input(fwk.KEY_ESC) == 0 do -- game loop
    print("hello FWK from Lua!")
end

Quickstart

  • Double-click MAKE.bat (Win) or sh MAKE.bat (Linux/OSX) to compile everything.
  • MAKE.bat sln (Win) or sh MAKE.bat sln (Linux/OSX) to generate solutions/makefiles.
  • MAKE.bat help (Win) or sh MAKE.bat help (Linux/OSX) for a bunch of options.
  • MAKE.bat hello.c (Win) or sh MAKE.bat hello.c (Linux/OSX) to build a single executable.
  • Alternatively,
echo win/vc       && cl hello.c
echo win/clang-cl && clang-cl hello.c
echo win/tcc      && tcc   hello.c -m64
echo win/mingw    && gcc   hello.c -lws2_32 -lwinmm -ldbghelp -lole32 -luser32 -lgdi32 -lcomdlg32
echo win/clang    && clang hello.c -lws2_32 -lwinmm -ldbghelp -lole32 -luser32 -lgdi32 -lcomdlg32
echo linux        && cc  hello.c -lm -ldl -lpthread -lX11
echo linux/tcc    && tcc hello.c -lm -ldl -lpthread -lX11 -D__STDC_NO_VLA__
echo osx          && cc -ObjC hello.c -framework cocoa -framework iokit -framework audiotoolbox

Cook

  • Most asset types need to be cooked before being used in your application. Some other assets like .png do not.
  • Cooked assets will be written into .zipfiles close to your executable, and mounted before entering game loop.
  • Cooked .zipfiles and your executable are the only required assets when releasing your game.
  • Cook manually your assets by invoking supplied tools/cook standalone binary.
  • Cook automatically your assets by just playing your game: a runtime cook is already embedded into your binary.
    • In order to achieve this, ensure the tools/ folder is close to your executable.
    • This folder contains all the related binaries to perform any asset conversion plus the cookbook to do so.

Extra tips

  • Any ico/png file named after the executable name will be automatically used as app icon.
  • Similar to the ico/png case above, the cooked .zipfiles can be named after the main executable as well.
  • Dropped files into game window will be imported & saved into import/ folder.
  • Update the gamepad controller database by upgrading the gamecontrollerdb.txt file.
  • Depending on your IDE, you might need to browse to engine/split/ sources when debugging FWK.
  • Cook assets on demand, as opposed to cook all existing assets on depot, by using --cook-on-demand flag.
  • Linux/OSX users can optionally install wine and use the Windows tools instead (by using --cook-wine flag).
  • Disable automatic cooking by using --cook-jobs=0 flag (not recommended).
  • Generate a project solution by dropping engine/fwk.h, fwk.c and fwk files into it, or MAKE.bat sln.
  • Much faster builds by typing MAKE.bat tcc (Win/Linux). Beware: compiler has no thread-locals support.

Bindings

Credits (Artwork + demos)

Credits (Tools)

Credits (Runtime)

Unlicense

This software is released into the public domain. Also dual-licensed as 0-BSD or MIT (No Attribution) for those countries where public domain is a concern (sigh). Any contribution to this repository is implicitly subjected to the same release conditions aforementioned.

Links

Issues Discord

Still looking for alternatives? amulet, aroma, astera, blendelf, bullordengine, candle, cave, chickpea, corange, cute, dos-like, ejoy2d, exengine, gunslinger, hate, island, juno, l, lgf, limbus, love, lovr, mini3d, mintaro, mio, olive.c, opensource, ouzel, pez, pixie, punity, r96, ricotech, rizz, tigr, yourgamelib

fwk.2022's People

Contributors

r-lyeh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fwk.2022's Issues

Problems decoding mp1 files with jo_mp1

Hello.

I'm looking into using the jo_mp1 header from this repository to play mp1 audio files. I'm using the mp2enc program from the mjpegtool package to prepare my mp1 files with the command mp2enc -b 64 -l 1 -o test.mp1 -r 44100 -m < test.wav. I have an example wav and mp1 that I'm testing with attached.

I'm having an issue whereby jo_mp1 only decodes about half of the mp1 input file.

My source code is at https://github.com/deltabeard/mp12wav/blob/master/src/mp12wav.c I've tested my mp1 input file with ffmpeg, which converts to wav correctly.

Many thanks.

test_files.zip

  • test_input.wav: original wav file
  • test.mp1: file converted from wav to mp1 with mp2enc
  • test_ffmpeg.wav: file converted from test.mp1 with ffmpeg
  • test_jo_mp1.wav: file converted from test.mp1 with jo_mp1 header in this repo

sfxr2wav.osx: No such file or directory

CC # sh MAKE.bat
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file ... target_directory
chmod: art/tools/sfxr2wav.osx: No such file or directory

CC # uname -ms
Darwin x86_64

macos 10.15

Lovely project! I would like to run demo_luajit.lua on macOS

On macOS 11.6.1, every other C demo runs fine, but running luajit demo_luajit.lua with LuaJIT 2.1.0-beta3 I get:

luajit: dlopen(libfwk.dylib, 5): Symbol not found: _glad_glEnable
  Referenced from: libfwk.dylib
  Expected in: flat namespace
 in libfwk.dylib

I built libfwk.dylib with the following commands:

cc -c -ObjC fwk.c -w -g $*
cc -dynamiclib -undefined suppress -flat_namespace *.o -o libfwk.dylib -framework cocoa -framework iokit -framework opengl

I looks like I need to install glad2 somehow. Checked on the homebrew side but found no available formula with that name.

Thank you for any help getting past this point and good luck with your awesome project!

Last commit gives errors when building dylib on macOS

Hi @r-lyeh

Just a quick heads up regarding building as a dylib on macOS.

I am getting the usual warnings but the following errors are preventing the build:

fwk_obj.c:10:6: error: conflicting types for 'obj_free'
void obj_free( void *obj ) {
     ^
fwk_obj.h:53:17: note: previous declaration is here
API void        obj_free( const void *obj );
                ^
fwk_obj.c:17:6: error: conflicting types for 'obj_del'
void obj_del( void *obj ) {
     ^
fwk_obj.h:63:17: note: previous declaration is here
API void        obj_del( const void *obj );
                ^
fwk_obj.c:85:17: error: called object type 'int' is not a function or function pointer
    return MSIZE(ptr) - sizeof(void*);
           ~~~~~^
fwk_obj.c:176:7: error: conflicting types for 'obj_ref'
void* obj_ref(void *obj) {
      ^
fwk_obj.h:65:17: note: previous declaration is here
API void*       obj_ref( const void *obj );
                ^
fwk_obj.c:192:7: error: conflicting types for 'obj_unref'
void* obj_unref(void *obj) {
      ^
fwk_obj.h:66:17: note: previous declaration is here
API void*       obj_unref( const void *obj );
                ^
154 warnings and 5 errors generated.

Thanks

'luajit demo_luajit_model.lua' terminated by signal SIGSEGV (Address boundary error)

Hi @r-lyeh,

I'm getting this crash with the last commit:

luajit demo_luajit_model.lua
000.000s|Monitor: Color LCD (60Hz, vsync=1)w_create_from_handle|fwk_window.c:153
000.000s|GPU device: AMD Radeon Pro 450 OpenGL Enginerom_handle|fwk_window.c:154
000.000s|GPU driver: 4.1 ATI-4.6.20  |window_create_from_handle|fwk_window.c:155
000.018s|Compiling shader                               |shader|fwk_render.c:833
000.019s|Shader.attribute[0]=att_position               |shader|fwk_render.c:860
Deleting 000% art//demos/audio/larry.txt
'luajit demo_luajit_model.lua' terminated by signal SIGSEGV (Address boundary error)

I hope the error message gives you enough clues.

Thanks

Expose sprite_update

Currently I cannot apply fx to sprites since it gets applied to the debug ui as well. Exposing sprite_update allows fx to work. Also tried using window_flush but this didn't work.

Thank you

I noticed Planimeter/lgf, which I author, mentioned here in your repository. I also greatly enjoy C game engines. Thank you for your contributions to this space. FWK is very impressive.

-Andrew

REQUESTS

Feel free to submit here all your feature requests & suggestions. Ideally, specify only a suggestion per written comment, rather than starting a whole chat/discussion in the thread.

  • render: raster sprites in resolution independant way (@SushilRagoonath)
  • render: helper function to debug/raster fbos in screen (by using either tile() or sprite(), with bool do_flipping option) (@SushilRagoonath)
  • window: more flexibility when creating windows (since I dont want users to enter (w,h) resolution, maybe I should allow WINDOW_16_9, WINDOW_3_2, WINDOW_3_4, etc;) (@SushilRagoonath)
  • render: maybe support for Vulkan, DirectX, and OpenGL ES? (@Rabios)
  • platform: html5: consider going schellingb/wajic#1 (@r-lyeh)

BACKLOG

Small quick issues grouped together.

  • ui: abnormal behavior on osx.
  • video: audio buffers may exhaust. do a better mixer.
  • video: stutters shortly when fast seeking.
  • editor: gizmo crashes sometimes.
  • editor: gizmo make it better resolution independent.
  • editor: gizmo handlers do overlap often.
  • editor: 3-gizmos 1-view.
  • render: billboards stopped working sometime ago.
  • render: fx_end() should flush all retained renderers (debugdraw, sprites, ...)
  • sprite: expose ortho-2d camera for sprites somehow.
  • sprite: hud sprites (resolution independent, z-index, no fx).
  • sprite: parallax, tiled map loader.
  • sprite: normals, lighting.
  • profile: ensure we add up different calls from matching section names.
  • demo_script/demo_socket: might use some more fancy demo (windowed).
  • demo_shadertoy: move logic to materials. then rename to demo_material.c
  • demo_cubemap: might showcase pipeline/asset options? turn models 90º
  • demo_model: ackward controller, not working yet
  • demo_scene: two_sided option stopped working?
  • demo_scene: fuse with demo_model? demo_editor+materials instead?
  • demo_scene: bounding box should be enabled by default to showcase it.
  • demo_pbr: move all rendering logic from this demo into fwk.c
  • tcc+win: not working always, see #10
  • clang-cl: not working because of faulty toolchain, see #10 hints here https://bugs.llvm.org/show_bug.cgi?id=25305
  • https: not working in DLL form (fixed?)
  • linux: cuttlefish /lib/x86_64-linux-gnu/libm.so.6: version GLIBC_2.27 not found (required by art/tools/libcuttlefish.so.2) (reported by procedural)
  • win+nvidia+fullscreen: adaptive vsync not working ok (low/inconsistent framerate) (reported by sushil)

Thank you for the LuaJIT model demo

Hi @r-lyeh,

The demo runs and is very low on CPU and memory.

The model seems to load:

000.107s|Loading VFS (kgirl/)kgirls01.fbx

I do see a new tiny grid in the middle. However, I can't see the character and I don't know how to zoom in. I tried the usual keyboard keys to navigate in the viewport like in Maya or Blender without success. I can only rotate around the "world" axis when I move the cursor. BTW, I do not have a mouse and I'm doing this with the trackpad.

Any idea on how I can navigate in the viewport and especially how can I zoom in to check if the character is there.

That's all really awesome. Thanks!

Can I reflog the commits?

@r-lyeh I'm not sure you're squashing your commits but is there any means I can follow the minute changes between two successive "commits"?

Links

Shurmano please, don't be a perro and put the actual links in the readme rather than a google search link :D

Compile error clang/gcc

all tested on windows
Cannot compile gcc 9,2,0 with error message
C:\Users\Sushil\AppData\Local\Temp\ccmRZhxT.s: Assembler messages:
C:\Users\Sushil\AppData\Local\Temp\ccmRZhxT.s:546187: Error: incorrect register %eax' used with q' suffix
not sure how to get better error.

Cannot compile clang 12.0.0 with msvc(2022 preview)
fwk-f22eb2.o : error LNK2019: unresolved external symbol __udivti3 referenced in function mp_count_bits

I'm actually trying to build fwk as a dll so I create a better workflow but msvc wants __declspec so I'd rather try gcc/clang.
Also tcc is crashing after the cooking stage but I don't know how to debug it.

Expression failed: memory 3rd_nuklear.h in luajit demo_luajit.lua

Now I'm getting this in luajit demo_luajit.lua:

000.195s|Expression failed: memory 3rd_nuklear.h:17451reakpoint|fwk_system.c:778

001: 0x0000000f810fd5 breakpoint
002: 0x0000000f82ec93 nk_font_atlas_add_from_memory
003: 0x0000000fa14cdc nk_config_custom_fonts
004: 0x0000000f967aec fwk_post_init
005: 0x0000000f967927 window_create_from_handle
006: 0x0000000f95fff3 window_create
007: 0x0000010f66b905 main
008: 0x0000010f6b7cb3 luaL_openlibs
'luajit demo_luajit.lua' terminated by signal SIGSEGV (Address boundary error)

warn: material[3] not found in demo_scene

Hi @r-lyeh,

It's not a biggie but the texture of the cute fighting character is missing.

000.797s|Loading VFS (demos/art/models/kgirl/)g01_texture.png (cached)file.c:543
000.798s|warn: material[3] not found: 01 - Default+g01_texture.png_render.c:3499
000.798s|warn: using placeholder material[3]=texture_checkeres|fwk_render.c:3500

Compiling errors when using the command

HI dear author,
It's truly a honor to write a letter to you, I'm build your project nowadays and found the error when building as following, I wonder if there is a chance that you know the reason? :)

image

thank you
best regards to you
William

error: use of undeclared identifier 'NSString'; did you mean 'cString'?

Hi @r-lyeh,

I can't get past this point while compiling with sh MAKE.bat:

editor
demo_audio
In file included from editor.c:67:
In file included from ./fwk.c:93:
3rd_glfw3.h:33606:5: error: use of undeclared identifier 'NSString'; did you mean 'cString'?
    NSString* appName = nil;
    ^~~~~~~~
    cString
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Carbon.framework/Frameworks/OpenScripting.framework/Headers/ASRegistry.h:212:3: note: 'cString' declared here
  cString                       = cStringClass /* old name for cStringClass - can't be used in .r files*/
  ^
In file included from editor.c:67:
In file included from ./fwk.c:93:
3rd_glfw3.h:33606:15: error: use of undeclared identifier 'appName'
    NSString* appName = nil;

This should not happen since -framework cocoa normally also includes Foundation. I also tried adding -framework foundation to no avail.

P.S. - I'm looking forward to trying the new editor 👍

demo_scene crashes on Quit

Hey @r-lyeh,

demo_scene is crashing on Quit with this error message:

demo_scene(65581,0x11ea25e00) malloc: *** error for object 0x7fffde85c227: pointer being freed was not allocated
demo_scene(65581,0x11ea25e00) malloc: *** set a breakpoint in malloc_error_break to debug
'./demo_scene' terminated by signal SIGABRT (Abort)

P.S. - I guess you're going to ask me for a backtrace ;)

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x00007fff2031a92e libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff203495bd libsystem_pthread.dylib`pthread_kill + 263
    frame #2: 0x00007fff2029e406 libsystem_c.dylib`abort + 125
    frame #3: 0x00007fff2017e165 libsystem_malloc.dylib`malloc_vreport + 548
    frame #4: 0x00007fff201812aa libsystem_malloc.dylib`malloc_report + 151
    frame #5: 0x00000001001e0215 demo_scene`callstack(traces=10) at fwk_system.c:219:13
    frame #6: 0x00000001000bffe5 demo_scene`breakpoint(reason="!Expression failed: atlas->temporary.alloc 3rd_nuklear.h:17762\n") at fwk_system.c:777:47
    frame #7: 0x00000001000e2cac demo_scene`nk_font_atlas_clear(atlas=0x000000010866bfc8) at 3rd_nuklear.h:17762:5
    frame #8: 0x000000010011667c demo_scene`nk_glfw3_shutdown(glfw=0x0000000108667940) at 3rd_nuklear_glfw_gl3.h:539:5
    frame #9: 0x000000010021545a demo_scene`glfw_quit at fwk_window.c:129:21
    frame #10: 0x00007fff20278d30 libsystem_c.dylib`__cxa_finalize_ranges + 327
    frame #11: 0x00007fff20279010 libsystem_c.dylib`exit + 53
    frame #12: 0x000000010021f7b7 demo_scene`editor at fwk_editor.c:205:30
    frame #13: 0x0000000100003a9a demo_scene`main at demo_scene.c:113:13
    frame #14: 0x00007fff20364f3d libdyld.dylib`start + 1
    frame #15: 0x00007fff20364f3d libdyld.dylib`start + 1

Errors building with the last commit on macOS

Hi @r-lyeh,

I'm only displaying the errors (warnings disabled with -w switch):

cc -w -ObjC -dynamiclib -o libfwk.dylib fwk.c -framework cocoa -framework iokit

fwk_system.c:214:20: error: subscript of pointer to function type 'void *(int)'
        if( dladdr(stack[i], &info) && info.dli_sname ) {
                   ^~~~~
fwk_system.c:217:21: error: use of undeclared identifier 'demangled'
            strcpy( demangled, dmgbuf ? dmgbuf : info.dli_sname );
                    ^
fwk_system.c:217:21: error: use of undeclared identifier 'demangled'
fwk_system.c:218:26: error: use of undeclared identifier 'demangled'
            symbols[i] = demangled;
                         ^
4 errors generated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.