{"id":43792533,"url":"https://github.com/elcritch/figdraw","last_synced_at":"2026-02-05T20:34:49.224Z","repository":{"id":332236927,"uuid":"1133084848","full_name":"elcritch/figdraw","owner":"elcritch","description":"2D GPU renderer library using SDFs for UI elements with fast shadows and text support! ","archived":false,"fork":false,"pushed_at":"2026-02-02T11:45:36.000Z","size":2655,"stargazers_count":14,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-02T22:33:06.916Z","etag":null,"topics":["2d-graphics","gpu-acceleration","gui","opengl","rendering","ui"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elcritch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-12T21:29:59.000Z","updated_at":"2026-02-02T11:45:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/elcritch/figdraw","commit_stats":null,"previous_names":["elcritch/figdraw"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/elcritch/figdraw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elcritch%2Ffigdraw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elcritch%2Ffigdraw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elcritch%2Ffigdraw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elcritch%2Ffigdraw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elcritch","download_url":"https://codeload.github.com/elcritch/figdraw/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elcritch%2Ffigdraw/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29133400,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T19:36:52.185Z","status":"ssl_error","status_checked_at":"2026-02-05T19:35:40.941Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2d-graphics","gpu-acceleration","gui","opengl","rendering","ui"],"created_at":"2026-02-05T20:34:49.148Z","updated_at":"2026-02-05T20:34:49.210Z","avatar_url":"https://github.com/elcritch.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FigDraw\n\n`figdraw` is a pure Nim rendering library for building and rendering 2D scene graphs\n(`Fig` nodes) with a focus on:\n\n- A thread-safe renderer pipeline (render tree construction and preparation can be done off the main thread; OpenGL submission stays on the GL thread).\n- An OpenGL backend with SDF (signed-distance-field) primitives for crisp rounded-rect rendering and gaussian based shadows.\n- Modern and fast text rendering and layout using [Pixie](https://github.com/treeform/pixie/) with a thread-safe API.\n- Image rendering using an GPU texture atlas.\n- Rendering with OpenGL / Metal - (Vulkan coming soon!)\n- Supports layering and multiple \"roots\" per layer - great for menus, overlays, etc.\n- Lightweight and high performance by design! Low allocations for each frame.\n\n## What's It Look Like?\n\nHere's the primary rounded rect primitive with corners, borders, and shadows:\n\n![RGB boxes render](tests/expected/render_rgb_boxes_sdf.png)\n\nHere's it running as an overlay on top of a 3D scene:\n\n![3D Pyramid overlay](data/Pyramid-3D-Overlay.png)\n\nHere's text rendering curtesy of Pixie. Note that Pixie's layout can be used or custom layout, e.g. for monospaced renderers:\n\n![Text Rendering](data/Text-Example.png)\n\nHere's a video example (unfortunately capped at 30fps) of real time shadows, borders, and corners chaning fluidly at 120 FPS:\n\nhttps://github.com/user-attachments/assets/aca4783c-86c6-4e52-9a16-0a8556ad1300\n\n## Status\n\nThis repo is still under development but the core support for SDF is running! \nOpenGL backend is the only supported renderer right now\n(`src/figdraw/opengl/`). However there's some work toward supporting Vulkan.\n\nFuture directions may include adding support for SDF textures for text rendering using Valve's SDF-text mapping technique. Other directions in that area would be supporting vector images rasterized to SDF textures as well. \n\nThe next big item is hopefully setting up some examples of doing WebGL version with Windy.\n\nFinally there will be a C API and a setup to compile FigDraw as a shared library. \n\n## Requirements\n\n- Nim `\u003e= 2.0.10` (ARC/ORC-based memory managers; required by `src/figdraw/common/rchannels.nim`)\n- OpenGL (desktop GL by default; GLES/emscripten shader paths via `-d:useOpenGlEs` and/or `-d:emscripten`)\n\n## Quick Start\n\nThis part assumes a recent Atlas (\u003e= 0.9.6) version:\n\n```sh\n# Try the repo:\ngit clone https://github.com/elcritch/figdraw\ncd figdraw\natlas install --feature:windy --feature:sdl2\n\n# Run an example:\nnim c -r examples/windy_renderlist.nim\n```\n\n```sh\n# Use as a dependency (in your own project):\natlas use https://github.com/elcritch/figdraw\n```\n\nAlternatively Nimble should work as well:\n```sh\nnimble install https://github.com/elcritch/figdraw\n```\n\n**NOTE**: If you get errors you may need to install a newer version of Nimble or Atlas that support \"features\".\n\n### Install / Usage Notes\n\nNote that to use features like windy, you'll want to add it to requires:\n\n```nim\nrequires \"https://github.com/elcritch/figdraw[windy]\"\n```\n\nAlternatively, install metalx and pass `-d:figdraw.metal=true`.\n\n## Using Library\n\nThe most stable entry points today are:\n\n- Core types/utilities: `import figdraw/commons`\n- Scene graph nodes: `import figdraw/fignodes`\n- OpenGL backend: `import figdraw/figrender`\n\nRender list example (build a small scene tree):\n\n```nim\nimport figdraw/commons\nimport figdraw/fignodes\nimport chroma\n\nproc makeRenders(w, h: float32): Renders =\n  var list = RenderList()\n\n  let rootIdx = list.addRoot(Fig(\n    kind: nkRectangle,\n    screenBox: rect(0, 0, w, h),\n    fill: rgba(255, 255, 255, 255).color,\n  ))\n\n  list.addChild(rootIdx, Fig(\n    kind: nkRectangle,\n    screenBox: rect(80, 60, 240, 140),\n    fill: rgba(220, 40, 40, 255).color,\n    corners: [12.0'f32, 12.0, 12.0, 12.0],\n    stroke: RenderStroke(weight: 3.0, color: rgba(0, 0, 0, 255).color),\n  ))\n\n  result = Renders(layers: initOrderedTable[ZLevel, RenderList]())\n  result.layers[0.ZLevel] = list\n```\n\nFeed the resulting `Renders` into the OpenGL backend; see the examples below for a full render loop.\n\nFor a complete working example (window + GL context + render loop), see:\n\n- `examples/windy_renderlist.nim`\n- `examples/sdl2_renderlist.nim`\n\n## Layers and ZLevel\n\n`Renders` is an ordered table of `ZLevel -\u003e RenderList`. Lower zlevels are drawn first, so higher\nzlevels appear on top. Each layer can contain multiple roots (useful for overlays, HUDs, menus, etc).\n\nShort example:\n\n```nim\nimport figdraw/commons\nimport figdraw/fignodes\nimport chroma\n\nproc makeRenders(w, h: float32): Renders =\n  var bg = RenderList()\n  discard bg.addRoot(Fig(\n    kind: nkRectangle,\n    screenBox: rect(0, 0, w, h),\n    fill: rgba(245, 245, 245, 255).color,\n  ))\n\n  var overlay = RenderList()\n  discard overlay.addRoot(Fig(\n    kind: nkRectangle,\n    zlevel: 10.ZLevel,\n    screenBox: rect(40, 40, 220, 120),\n    fill: rgba(43, 159, 234, 255).color,\n    corners: [10.0'f32, 10.0, 10.0, 10.0],\n  ))\n\n  result = Renders(layers: initOrderedTable[ZLevel, RenderList]())\n  result.layers[0.ZLevel] = bg\n  result.layers[10.ZLevel] = overlay\n  result.layers.sort(proc(x, y: auto): int = cmp(x[0], y[0]))\n```\n\n## MSDF Bitmap based SDF Rendering\n\nThis has many benefits over regular textures for rendering vector shapes. It acts as a sort of \"compression\" technique allow us to scale the size of the shape while maintaining sharp edges with small texture sizes. Generally 64x64 can scale up to a fullscreen object with reasonable quality.\n\nThe other benefit is being able to draw shadows / strokes / etc similar to regular SDFs! See the blue stroked start below using the same SDF glyph as the others:\n\n\u003cimg width=\"1136\" height=\"780\" alt=\"Screenshot 2026-02-03 at 5 56 30 PM\" src=\"https://github.com/user-attachments/assets/728e7b59-d8db-4408-bc50-637742237022\" /\u003e\n\n\nSee [examples/windy_msdf_star.nim](examples/windy_msdf_star.nim) for more info.\n\n## Run Tests\n\nRuns all tests + compiles all examples listed in `config.nims`:\n\n```sh\nnim test\n```\n\nRun a single test:\n\n```sh\nnim r tests/trender_rgb_boxes.nim\n```\n\n## SDF Rendering (default)\n\nThe OpenGL backend renders rounded rectangles and shadows using an SDF shader\npath by default:\n\n```sh\nnim r examples/windy_renderlist.nim\n```\n\nTo force the older texture path, compile with `-d:useFigDrawTextures`.\n\nNotes:\n\n- The main OpenGL shader combines atlas sampling and SDF rendering, switching per-draw via an `sdfMode` attribute (no shader swaps for SDF vs atlas).\n- Masks still use a separate mask shader program.\n- Current SDF modes include clip/AA fills, annular (outline) modes, and drop/inset shadow modes used by the renderer.\n\n## Useful Defines\n\n- `-d:figdraw.names=true`: enables `Fig.name` for debugging (enabled for tests in `tests/config.nims`)\n- `-d:useOpenGlEs`: select GLES/emscripten shader sources when GLSL 3.30 is not available\n- `-d:useFigDrawTextures`: force the legacy texture-based shape rendering path (disables SDF shapes)\n- `-d:openglMajor=3 -d:openglMinor=3`: override the requested OpenGL version (see `src/figdraw/utils/glutils.nim`)\n\n## Thread Safety Notes\n\n- Rendering is structured so that preparing render lists/trees can be done off-thread.\n- GPU resource submission (OpenGL calls) must happen on the GL thread; the backend enforces this separation.\n\n## License\n\nSee `LICENSE`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felcritch%2Ffigdraw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felcritch%2Ffigdraw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felcritch%2Ffigdraw/lists"}