{"id":13731803,"url":"https://github.com/nyorain/rvg","last_synced_at":"2026-01-14T18:28:11.806Z","repository":{"id":86447799,"uuid":"123917763","full_name":"nyorain/rvg","owner":"nyorain","description":"High level vulkan 2D vector-like graphics api (C++)","archived":false,"fork":false,"pushed_at":"2021-02-14T12:01:50.000Z","size":1928,"stargazers_count":192,"open_issues_count":3,"forks_count":11,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-06-02T09:19:23.962Z","etag":null,"topics":["graphics","vector","vulkan"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nyorain.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":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-05T12:41:51.000Z","updated_at":"2025-03-21T02:16:53.000Z","dependencies_parsed_at":"2023-03-07T01:30:18.420Z","dependency_job_id":null,"html_url":"https://github.com/nyorain/rvg","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/nyorain/rvg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nyorain%2Frvg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nyorain%2Frvg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nyorain%2Frvg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nyorain%2Frvg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nyorain","download_url":"https://codeload.github.com/nyorain/rvg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nyorain%2Frvg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28430820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T16:38:47.836Z","status":"ssl_error","status_checked_at":"2026-01-14T16:34:59.695Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["graphics","vector","vulkan"],"created_at":"2024-08-03T02:01:38.779Z","updated_at":"2026-01-14T18:28:11.798Z","avatar_url":"https://github.com/nyorain.png","language":"C","readme":"# Retained vulkan/vector graphics\n\n**NOTE: this isn't very actively maintained at the moment. It might still\nbe useful as a proof of concept. Just for reference, you might prefer to look\nat an [experimental rework](https://github.com/nyorain/tokonoma/tree/master/src/guitest) \nI worked on for a while, where rendering is a lot more optimized.\nDevelopment here might be resumed in future**\n\nVulkan library for high-level 2D vector-like rendering in modern C++17.\nModeled loosely after svg, inspired by nanoVG.\nUses an object-oriented, retained mode idiom for rendering which makes it\nhighly efficient for rendering with vulkan since curves and shapes are not\nrecomputed and uploaded every frame but just once (or when changed).\nDoes not even need a command buffer rerecord every frame,\neven things like paints, shapes or transforms can be\nchanged without triggering the need for a command buffer rerecord which makes\nit use way less cpu performance than immediate mode alternatives.\nAims to provide a compromise between high level drawing functionality\nand an api that can efficiently be implemented on the gpu.\nCould e.g. easily be used for a vulkan gui library.\n\nThe project builds upon tested and proven libraries where possible, such as\n[fontstash](https://github.com/memononen/fontstash) for font atlas building and\nsome [stb headers](https://github.com/nothings/stb).\nNote that the project is still in a rather early stage, please report\nall issues and questions (simple things such as spelling errors\nor missing docs on a function are appreciated as well).\n\nFor more information check out the example concepts below, the\n[example](example/example_glfw.cpp) showing off many features,\nor read the [introduction](docs/intro.md) which documents some basic\nconcepts and shows how to integrate rvg in more detail.\n\n# Example\n\nSince rvg uses a retained mode you will first have to create the resources\nyou might to use/draw and then actually draw them (via recording into\na command buffer).\nThe example below shows initialization of some basic rvg resources (on\nthe highest abstraction level), there are more and more advanced settings,\nrefer to the inline documentation in the [headers](include/rvg):\n\n```cpp\ninit(vpp::Device\u0026 dev, vk::RenderPass renderPass) {\n\t// First create a rvg context: creates pipelines and such\n\t// We have to specify the renderPass and subpass we want to use it\n\t// (There are much more settings like pipelineCache/anti aliasing or\n\t// enabled features, see rvg/context.hpp).\n\trvg::Context context {dev, {renderPass, 0u}};\n\n\t// Now we can create resources\n\t// rectangle at {100, 100} with size {200, 200}\n\t// the last parameter is the draw mode: in this case we want to\n\t// build fill data but will never stroke it\n\tauto rect = rvg::RectShape(ctx, {100, 100}, {200, 200}, {true, 0.f});\n\n\t// a circle at {300, 300} with radius 10 that we can\n\t// stroke (with thickness 3.f) and fill\n\tauto circle = rvg::CircleShape(ctx, {300, 300}, 10, {true, 3.f});\n\n\t// a scissor that only render into the given rect (at {50, 50} with size\n\t// {100, 100})\n\tauto scissor = rvg::Scissor(ctx, {{50, 50}, {100, 100}});\n\n\t// a transform that transforms coordinates from the space we just used\n\t// (which may e.g. be level or window coordinates) to normalized\n\t// vulkan coords ([-1, 1] x [-1, 1])\n\tauto transform = rvg::Transform(ctx, \u003ctransform matrix\u003e);\n\n\t// a paint that will specify how shapes are filled/stroked\n\tauto colorPaint1 = rvg::Paint(ctx, rvg::colorPaint(rvg::Color::red));\n\tauto colorPaint2 = rvg::Paint(ctx, rvg::colorPaint({255u, 128u, 190u}));\n\n\t// rvg does also support gradients and texture paints\n\t// linear gradient from ({100, 100}: red) to ({200, 200}: green)\n\tauto gradient = rvg::Paint(ctx, rvg::linearGradient(\n\t\t{100, 100}, {200, 200},\n\t\trvg::Color::red, rvg::Color::green));\n\n\t// create a FontAtlas and load a font\n\t// rvg uses the font handling from nuklear (using stb truetype \u0026 rectpack)\n\trvg::FontAtlas fontAtlas(ctx);\n\trvg::Font font(fontAtlas, \"OpenSans.ttf\");\n\tfontAtlas.bake();\n\n\t// using the font we can now create a text object at {400, 100}\n\t// we could also align it using the metrics information by Font and Text\n\trvg::Text text(ctx, \"Text to display\", font, {400, 100});\n}\n```\n\nAfter having all these resources created we naturally want to render them.\nSince rvg tries to stay as modular and univerally usable as possible,\nthe interface all resources use for rendering is a raw vulkan command buffer.\nBinding state (like transform/paint/scissor) will result in a simple\ndescriptor set bind while rendering shapes will result always in an indirect\ndraw.\nAssuming the resources from above, this could look like this:\n\n```cpp\nrender(vk::CommandBuffer cb) {\n\t// Binds default (full) scissor, identity transform and other required\n\t// state\n\tctx.bindDefaults(cb);\n\n\t// We can bind state and draw what we want now.\n\t// Bound state stays the same until replaced\n\t// First, we bind our transform\n\ttransform.bind(cb);\n\n\t// Now, let's draw!\n\t// Starting with the rect shape: we specified that we might want\n\t// to fill it but don't need the stroke data. So now we can record\n\t// its fill commands but were not allowed to stroke it\n\tpaint1.bind(cb);\n\trect.fill(cb);\n\n\tcircle.fill(cb);\n\n\tpaint2.bind(cb);\n\tcircleShape.stroke(cb);\n\n\t// we can also fill/stroke shapes multiple times\n\tscissor.bind(cb);\n\trect.fill(cb);\n\n\t// explicitly reset the limiting scissor bound above:\n\tctx.defaultScissor().bind(cb);\n\n\tgradient.bind(cb);\n\ttext.draw(cb);\n}\n```\n\nIt's now probably pretty easy to imagine how you could use rvg to further\nbuild your own (roughly) object-oriented interfaces and divide the work\ninto small components.\n\n## Screenshots\n\nScreenshot of [example/example.cpp](example/example.cpp):\n\n![\u003cCurrently not loading example picture :(\u003e](example/example.png)\n\n## Building\n\nThe library uses meson as build system. It uses a few of my other\nlibraries as dependencies to stay modular but those will be automatically\nbuilt using meson. The only hard dependencies are vulkan as well as glslang\nfor building the spirv shaders.\nYou need a solid C++17 compiler (currently not tested with msvc),\ngcc \u003e= 7 is tested. For gcc 7 you currently have to turn off werror\nin meson (`meson configure -Dwerror=false` in build dir).\nFor the glfw example you need the glfw3 library (obviously with vulkan\nsupport).\n\nAfter building\n\n```\nmeson build -Dexample-glfw=true\ncd build\nninja\n```\n\nyou should be able to run the example in the build dir via `./example/example_glfw`.\nThere is also an example using my experimental ny window abstraction instead of glfw,\nenable it via `-Dexample-ny=true` (requires several low level xcb/wayland libraries).\n\n# Notes\n\nPlease read the linked introduction (requirements) before reporting build issues.\nContributions welcome, always want to hear ideas and suggestions.\n\nThis library is the successor of/inspired my attempt to write a\n[nanoVG vulkan backend](https://github.com/nyorain/vvg), which worked\nbut didn't really make use of vulkans advantages. That inspired\nme to look into which kind of abstraction would make sense for vulkan.\n","funding_links":[],"categories":["Graphics"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnyorain%2Frvg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnyorain%2Frvg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnyorain%2Frvg/lists"}