FWK.2022
FWK.2022 copied to clipboard
đ 3D game engine/framework in C, with Luajit and Python bindings now.
F·W·K
3D game framework in C, with Luajit bindings now.
Goals
- [x] ~~C++~~. C.
- [x] ~~Fast~~. Naive.
- [x] ~~Modern~~. Simple.
- [x] ~~Full featured~~. Small.
- [x] ~~Rich build system~~. Single file.
- [x] ~~Royaltie fee~~. Free and unlicensed.
Features áŠ(á)á€
- [x] Pipeline: configurable and integrated asset pipeline.
- [x] Embedded: single-file, all dependencies included.
- [x] Compiler: MSVC, MINGW64, TCC, GCC, clang and emscripten.
- [x] Linkage: Both static linkage and dynamic .dll/.so/.dylib support.
- [x] Platform: Windows, Linux and OSX. Partial HTML5/Web support.
- [x] DS: hash, sort, array/vector, map, set.
- [x] Math: rand, noise, ease, vec2/3/4, mat33/34/44, quat.
- [x] Geometry: ray, line, plane, aabb, sphere, capsule, triangle, poly and frustum.
- [x] Window: windowed, soft/hard fullscreen, msaa, icon, cursor handling.
- [x] Input: keyboard, mouse and gamepads.
- [x] Script: Lua scripting, Luajit bindings.
- [x] Network: downloads (HTTPS) and sockets (TCP/UDP).
- [x] UI: color3/4, button, list, slider, toggle, checkbox, editbox, dialog, image, menus, windows
- [x] Font: TTF, OTF and TTC. Basic syntax highlighter. Glyph ranges. Atlasing.
- [x] Localization/I18N: XLSX and INI. Unicode.
- [x] Image: JPG, PNG, BMP, PSD, PIC, PNM, ICO.
- [x] Texture: KTX/2, PVR, DDS, ASTC, BASIS, HDR, TGA.
- [x] Texel: Depth, R, RG, RGB, RGBA, BC1/2/3/4/5/6/7, PVRI/II, ETC1/2, ASTC.
- [x] Audio: WAV/FLAC, OGG/MP1/MP3, MOD/XM/S3M/IT, SFXR and MID.
- [x] Video: MP4, MPG, OGV, MKV, WMV and AVI. Also, MP4 recording with MPEG-1 fallback.
- [x] Model: IQM/E, GLTF/2, GLB, FBX, OBJ, DAE, BLEND, MD3/5, MS3D, SMD, X, 3DS, BVH, DXF, LWO.
- [x] Render: PBR (metallic-roughness) workflow.
- [x] Render: Cubemaps, panoramas and spherical harmonics. Rayleigh/Mie scattering.
- [x] Render: Post-effects (SSAO,FXAA1/3,CRT,Contrast,Grain,Outline,Vignette...).
- [x] Render: 3D Anims, skeletal anims, hardware skinning and instanced rendering.
- [x] Render: 3D Debugdraw, batching and vectorial font.
- [x] Render: 2D Sprites, spritesheets, AA zooming and batching.
- [x] Compression: DEFLATE, LZMA, LZ4, ULZ, BALZ, BCM, CRUSH, LZW3, LZSS and PPP.
- [x] Virtual filesystem: ZIP, PAK, TAR and DIR.
- [x] Level data: JSON, JSON5, SJSON, XML, INI.
- [x] Disk cache.
- [x] Scene handling.
- [x] Profiler, stats and leaks finder.
- [x] Documentation (wip).
Roadmap á(á)á (in order of arrival; â±: partial support)
- [ ] Editor: gizmosâ±, scene tree, property editorâ±, load/saveâ±, undo/redoâ±, copy/paste.
- [ ] Level objects: volumesâ±, triggers, platforms, streaming.
- [ ] World: W/ECS, gameobj, serialization/merge, diff/patch.
- [ ] Scene: toggles on/off (billboardsâ±, materials, un/lit, cast shadows, wireframe, skyboxâ±/mieâ±, collideâ±, physics).
- [ ] Scene: node singleton display, node console, node labels, node outlinesâ±.
- [ ] Math: quat2, bezier, catmull.
- [ ] Render: Materials (colorsâ±, texturesâ±, matcapsâ±, videosâ±, shadertoysâ±). Shadertoys as post-fxâ±.
- [ ] Render: Hard/soft shadow mapping and baked lightmaps.
- [ ] Script: DLLâ± (module->plugin/sys), Luaâ±, Luajitâ±, Tealâ± and TypeScript.
- [ ] Network: NAT traversal. Socketless API, message API and pub/sub wrappers (enet/websocket).
- [ ] Pipeline: Extend: shaders, bindings. Per-platformâ±, per-typeâ±, per-asset options. GIF, PKM.
- [ ] Pipeline: Extend atlas (sprite/lightmaps). Fit packing (sprites).
- [ ] Pipeline: Extend bindings and messaging: parse C headers during cooking stage.
- [ ] Maybe: AI/Logic pass.
- [ ] Maybe: Animation pass.
- [ ] Maybe: VM/Replication pass.
- [ ] Maybe: Mobile/WASM/HTML5â± pass.
- [ ] Maybe: Lighting pass.
- [ ] Maybe: Node/Graph editor.
- [ ] Maybe: Tiled maps and 2D spines. Sprite parallaxs.
- [ ] Maybe: Font text layout and shaping, underlining, soft/hard shadows, outlines.
- [ ] API: Fewer and better examples.
- [ ] API: Discuss API and freeze it.
- [ ] API: Document everything.
Gallery
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!");
}
}
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
#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
}
Build (as static library)
Type MAKE.bat static
(Win) or sh MAKE.bat static
(Linux/OSX) to build everything dynamically. Alternatively,
echo Win(vc) && cl demo.c fwk.c
echo Win(tcc) && tcc demo.c fwk.c
echo Win(gcc) && gcc demo.c fwk.c -lws2_32 -lgdi32 -lwinmm -ldbghelp -lole32 -lcomdlg32
echo Linux(gcc+clang+tcc) && cc demo.c fwk.c -lm -ldl -lpthread -lX11
echo OSX(gcc+clang) && cc demo.c -ObjC fwk.c -framework cocoa -framework iokit
- Note: TCC is partially supported on Windows+Linux. Beware, no threading.
Build (as dynamic library)
Type MAKE.bat dll
(Win) or sh MAKE.bat dll
(Linux/OSX) to build everything staticly. Alternatively,
echo Win(vc) && cl fwk.c /LD /DAPI=EXPORT && cl demo.c fwk.lib /DAPI=IMPORT
echo Win(tcc) && tcc fwk.c -shared -DAPI=EXPORT && tcc demo.c fwk.def -DAPI=IMPORT
echo Win(gcc) && gcc fwk.c -shared -DAPI=EXPORT -o fwk.dll -lws2_32 -lwinmm -ldbghelp -lole32 -lgdi32 -lcomdlg32 -Wl,--out-implib,fwk.a && gcc demo.c fwk.a -DAPI=IMPORT
echo Linux && cc -fPIC -shared -o libfwk.so fwk.c -lX11 && cc demo.c libfwk.so -DAPI=IMPORT -Wl,-rpath,./
echo OSX && cc -ObjC -dynamiclib -o libfwk.dylib fwk.c -framework cocoa -framework iokit && cc demo.c libfwk.dylib -DAPI=IMPORT
Cook
- Most asset types need to be cooked before being used in your application. Other assets like
.png
do not. - Cooker is already embedded into you application and will scan for new contents & cook assets automatically.
- In order to achieve this, your binary needs to keep both
fwk.ini
file andtools/
folder close together. - Cooked assets will be written into .zipfiles close to your executable, and mounted before entering game loop.
- When distributing your game, only your binary and these .zipfiles are required.
Amalgamation
- Depending on your IDE, you might need to split all amalgamated files when debugging FWK.
- Split FWK into separate files by running
MAKE.bat split
(orsh MAKE.bat split
in Linux/OSX). - Merge those files back into FWK by running
MAKE.bat join
(orsh MAKE.bat join
in Linux/OSX). - Optionally, generate a single-header distribution by executing following script:
echo // This C file is a header that you can #include. Do #define FWK_C > fwk-single-header.h
echo // early in **one** C compilation unit to unroll the implementation >> fwk-single-header.h
echo // The FWK_C symbol **must be defined in a C file**; C++ wont work. >> fwk-single-header.h
type art\docs\ref\3rd\3rd_glad.h >> fwk-single-header.h
type fwk.h >> fwk-single-header.h
echo #ifdef FWK_C >> fwk-single-header.h
echo #pragma once >> fwk-single-header.h
echo #define FWK_3RD >> fwk-single-header.h
type fwk >> fwk-single-header.h
type fwk.c >> fwk-single-header.h
echo #endif // FWK_C >> fwk-single-header.h
Extra tips
- Any ico/png file matching the executable name will be automatically used as app icon.
- Dropped files into game window will be imported & saved into
art/import
folder. - Update the gamepad controller database by upgrading the
gamecontrollerdb.txt
file. - Cancel entire cooking stage by pressing
ESC key
(not recommended). - Disable automatic cooking by using
--with-cook-jobs=0
flag (not recommended). - Cook from command-line by running
cook.*
binaries. - Linux/OSX users can optionally install wine and use the Windows pipeline instead (by using
--with-wine
flag). - Generate a Visual Studio solution by dropping
fwk.h, fwk.c and fwk
files into it. - Faster builds by typing
MAKE.bat tcc
(Win/Linux). - Get smaller .exes by compiling with
/Os /Ox /O2 /Oy /GL /GF /MT /DNDEBUG /Gw /link /OPT:ICF /LTCG
(vc).
Bindings
- Luajit: Luajit bindings are provided in the auto-generated fwk.lua file.
- Nelua: Nelua bindings provided by Rabia Alhaffar.
Credits (Artwork + demos)
- DavidLam, for tokamak physics engine (ZLIB).
- FMS_Cat, for nicest VHS/VCR shader around (MIT).
- Goblin165cm, for witch 3D model (CC BY 4.0).
- Nanofactory, for kgirls01 3D model (CC BY-NC-ND 4.0).
- Quaternius, for the lovely 3D robots (CC0).
- Rxi, for lovely sprites & cats demo (MIT).
- wwwtyro, for nicest rayleigh/mie scattering shader around (CC0).
Credits (Tools)
- Aaron Barany, for cuttlefish (APACHE2).
- Arseny Kapoulkine, for pugixml (MIT).
- Assimp authors, for assimp (BSD3).
- Bernhard Schelling, for tml.h (Zlib) and tsf.h (MIT).
- ffmpeg authors, for ffmpeg (LGPL21).
- Imagination, for pvrtextoolcli (ITL).
- Krzysztof Gabis, for split.py/join.py (MIT).
- Lee Salzman, for iqm.cpp (PD).
- MartĂn Lucas Golini, for emscripten-fs.html (CC0).
- Mattias Gustavsson, for mid.h (PD).
- Michael Schmoock, for lcpp (MIT).
- Morgan McGuire, for markdeep (BSD2).
- Olivier Lapicque, Konstanty Bialkowski, for libmodplug (PD).
- Polyglot Team, for polyglot gamedev (CC0).
- Tomas Pettersson, for sfxr (PD).
- Tor Andersson, for assiqe.c (BSD).
Credits (Runtime)
- Barerose, for swrap (CC0).
- Camilla Löwy, for glfw3 (Zlib).
- Dave Rand for ppp (PD).
- David Herberth, for glad generated code (PD).
- David Reid, for miniaudio (PD).
- Dominic Szablewski, for pl_mpeg (MIT).
- Dominik MadarĂĄsz, for json5 parser (PD).
- Eduard Suica, for tlse (PD).
- Gargaj+cce/Peisik, for Foxotron/PBR shaders (UNLICENSE).
- Guillaume Vareille, for tinyfiledialogs (ZLIB).
- Haruhiko Okumura for lzss (PD).
- Igor Pavlov for LZMA (PD).
- Ilya Muravyov for bcm, balz, crush, ulz, lz4x (PD).
- Jon Olick, for jo_mp1 and jo_mpeg (PD).
- Joonas Pihlajamaa, for JUnzip library (PD).
- Juliette Focault, for the generated MD header (ZLIB).
- Lee Salzman, for IQM spec & player (PD).
- Lee Salzman, V.Hrytsenko, D.MadarĂĄsz, for enet (MIT).
- Libtomcrypt, for libtomcrypt (Unlicense).
- Lua authors, for Lua language (MIT).
- Mattias Gustavsson, for thread.h and https.h (PD).
- Micha Mettke, Chris Willcocks, Dmitry Hrabrov, for nuklear (PD).
- Omar Cornut, vaiorabbit, for tables of unicode ranges (MIT-0).
- Rabia Alhaffar, for ice_batt.h (PD).
- Rich Geldreich, for miniz (PD).
- Ross Williams for lzrw3a (PD).
- Samuli Raivio, for bq_websocket (PD).
- Sean Barrett, for stb_image, stb_image_write, stb_sprintf, stb_truetype and stb_vorbis (PD).
- Sebastian Steinhauer, for sts_mixer (PD).
- Stefan Gustavson, for simplex noise (PD).
- Vassvik, for mv_easy_font (Unlicense).
- Special thanks to @ands, @barerose, @datenwolf, @evanw, @glampert, @krig, @sgorsten and @vurtun for their math libraries (PD,CC0,WTFPL2,CC0,PD,CC0,Unlicense,PD).
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
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, opensource, ouzel, pez, pixie, punity, ricotech, rizz, tigr, yourgamelib