{"id":13759483,"url":"https://github.com/audulus/vger","last_synced_at":"2025-04-06T11:08:50.661Z","repository":{"id":43325096,"uuid":"360318943","full_name":"audulus/vger","owner":"audulus","description":"2D GPU renderer for dynamic UIs","archived":false,"fork":false,"pushed_at":"2024-09-05T17:38:42.000Z","size":6079,"stargazers_count":292,"open_issues_count":4,"forks_count":17,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-05T19:49:08.087Z","etag":null,"topics":["2d-graphics","c","ios","macos","metal","nanovg","objective-c","swift","vector-graphics","vger"],"latest_commit_sha":null,"homepage":"","language":"C","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/audulus.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}},"created_at":"2021-04-21T22:08:46.000Z","updated_at":"2025-03-28T12:04:31.000Z","dependencies_parsed_at":"2024-05-27T19:00:45.271Z","dependency_job_id":"a6a480da-77c0-4b78-b1ae-431a17063571","html_url":"https://github.com/audulus/vger","commit_stats":{"total_commits":903,"total_committers":4,"mean_commits":225.75,"dds":"0.056478405315614655","last_synced_commit":"be7ccc6ace2e55422ffdf9cb2ca7d53498c62656"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/audulus%2Fvger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/audulus%2Fvger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/audulus%2Fvger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/audulus%2Fvger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/audulus","download_url":"https://codeload.github.com/audulus/vger/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247471520,"owners_count":20944158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","c","ios","macos","metal","nanovg","objective-c","swift","vector-graphics","vger"],"created_at":"2024-08-03T13:00:53.826Z","updated_at":"2025-04-06T11:08:50.632Z","avatar_url":"https://github.com/audulus.png","language":"C","readme":"# vger\n\n![build status](https://github.com/audulus/vger/actions/workflows/build.yml/badge.svg)\n\u003cimg src=\"https://img.shields.io/badge/SPM-5.3-blue.svg?style=flat\"\n     alt=\"Swift Package Manager (SPM) compatible\" /\u003e\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Faudulus%2Fvger%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/audulus/vger)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Faudulus%2Fvger%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/audulus/vger)\n\nvger is a vector graphics renderer which renders a limited set of primitives, but does so almost entirely on the GPU. Works on iOS and macOS. API is plain C. Used to render [Audulus](https://audulus.com). Rust port is [here](https://github.com/audulus/vger-rs).\n\n\u003cimg src=\"demo.png\" alt=\"demo\" width=\"300\" height=\"450\"\u003e\n\nEach primitive can be filled with a solid color, gradient, or texture. vger renders primitives as instanced quads, with most of the calculations done in the fragment shader.\n\nHere's a screenshot of vger rendering the Audulus UI:\n\n\u003cimg src=\"screenshot.png\"\u003e\n\nHere's it rendering that svg tiger (the cubic curves are converted to quadratic by a lousy method, and I've omitted the strokes):\n\n\u003cimg src=\"tiger.png\"\u003e\n\n## Why?\n\nI was previously using nanovg for Audulus, which was consuming too much CPU for the immediate-mode UI. nanovg is certainly more full featured, but for Audulus, vger maintains 120fps while nanovg falls to 30fps on my 120Hz iPad because of CPU-side path tessellation, and other overhead. vger renders analytically without tessellation, leaning heavily on the fragment shader.\n\nIf you're interested in non-apple platforms, check out [the rust port](https://github.com/audulus/vger-rs).\n\n## How it works\n\nvger draws a quad for each primitive and computes the actual primitive shape in the fragment function. For path fills, vger splits paths into horizontal slabs (see `vgerPathScanner`) to reduce the number of tests in the fragment function.\n\nThe bezier path fill case is somewhat original. To avoid having to solve quadratic equations (which has numerical issues), the fragment function uses a sort-of reverse Loop-Blinn. To determine if a point is inside or outside, vger tests against the lines formed between the endpoints of each bezier curve, flipping inside/outside for each intersection with a +x ray from the point. Then vger tests the point against the area between the bezier segment and the line, flipping inside/outside again if inside. This avoids the pre-computation of [Loop-Blinn](https://www.microsoft.com/en-us/research/wp-content/uploads/2005/01/p1000-loop.pdf), and the AA issues of [Kokojima](https://dl.acm.org/doi/10.1145/1179849.1179997).\n\n## Status\n\n- ✅ Quadratic bezier strokes \n- ✅ Round Rectangles\n- ✅ Circles\n- ✅ Line segments (need square ends for Audulus)\n- ✅ Arcs\n- ✅ Text (Audulus only uses one font, but could add support for more if anyone is interested)\n- ✅ Multi-line text\n- ✅ Path Fills.\n\n## Installation\n\nTo add vger to your Xcode project, select File -\u003e Swift Packages -\u003e Add Package Depedancy. Enter https://github.com/audulus/vger for the URL. Check the use branch option and enter `main`.\n\n## Usage\n\nSee [`vger.h`](https://github.com/audulus/vger/blob/main/Sources/vger/include/vger.h) for the complete API. You can get a good sense of the usage by looking at [these tests](https://github.com/audulus/vger/blob/main/Tests/vgerTests/vgerTests.mm).\n\nVger has a C interface and can be used from C, C++, ObjC, or Swift. `vgerEncode` must be called from either ObjC or Swift since it takes a `MTLCommandBuffer`.\n\nSee [the demo app](https://github.com/audulus/vger/blob/main/Demo) for an example of using vger in a iOS/macOS SwiftUI app. vger includes `VgerView` to make it really easy to use Vger within SwiftUI:\n\n```swift\nimport SwiftUI\nimport vger      // C/C++/ObjC interface.\nimport vgerSwift // Swift nicities.\n\nstruct HelloView: View {\n\n    let cyan = SIMD4\u003cFloat\u003e(0,1,1,1)\n\n    var body: some View {\n        VgerView(renderCallback: { vger in\n            vgerText(vger, \"Hello world. This is V'Ger.\", cyan, 0)\n        })\n    }\n}\n```\n","funding_links":[],"categories":["C"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faudulus%2Fvger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faudulus%2Fvger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faudulus%2Fvger/lists"}