Graph1 is a zero-dependency Rust library for pixel-level 2D graphics, drawing, animation, and procedural effects. Designed for real-time applications, it provides primitives, geometry, drawing tools, effects, and font rendering utilities. It is suitable for games, demos, educational tools, or any project that requires software rendering with high control and precision.
- Zero dependencies β no external crates used.
- (Unless you opt in for experimental GPU support).
- Cross-platform β works on any platform with Rust support.
- Multithreading β parallel rendering for large framebuffers.
- Compositing β alpha blending with integer and float support.
- Geometric Primitives β lines, polygons, circles, bΓ©zier curves, etc.
- Context-based API β all the settings for drawing are available in one place.
- Pixel Fonts β supports bitmap fonts for rendering text
- Procedural Effects β scanlines, glitch effects, white noise, gradients, etc.
- Flexible Clipping β built-in clipping strategies for line drawing.
- Color Utilities β palettes, conversion between 0RGB, RGBA, ABGR, etc.
Please refer to the ROADMAP.md for plans on future features and improvements.
- A software renderer for 2D graphics.
- A toolkit for manipulating pixels, shapes, and effects.
- A real-time capable drawing engine for dynamic visuals.
- Does not perform file I/O (reading/writing images, fonts, etc.).
- Does not maintain state beyond its own context (@see GraphContext).
- Does not depend on any OS, graphics API, or runtime.
Graph1 uses context objects to separate responsibilities:
GraphContextβ main entry point: framebuffer, window, settings.WindowContextβ defines screen size, center, color, quadrants.LineContextβ manages anti-aliasing, thickness and rasterization of lines.BezierContextβ control over how bΓ©zier curves are rendered.- ,
AlphaContextβ alpha blending settings
Each context can be programmatically configured at any point in runtime. Default values are provided for ease of use.
- Graph1 uses RGBA model for color representation.
- The resulting framebuffer can be converted to other color models before being sent to the graphics output.
Many Graph1 operations (e.g., buffer fill, scanline effect, rectangle drawing) can be executed in parallel. The GraphContext.num_threads controls how many threads are used:
0β don't use any threads (i.e. do nothing)1β single-threadedn > 1β usenthreads to divide workload
Some of the functions that support multithreading:
draw::tools::fill::bufferdraw::rectangle::filledfx::scanline::windowutils::color::adapters::rgba_to_0rgb
Supported primitives and shapes:
- Lines (with clipping, anti-aliasing)
- Polygons (including stars and convex shapes)
- Circles and ellipses
- BΓ©zier curves (with control rendering)
- Filled rectangles
Closed shapes can be flood-filled with a color
Graph1 ships with pixel fonts embedded using the CBF (Compact Bitmap Font) format.
c_c_red_alert_inet0c_c_red_alert_inet1 (LAN)
These fonts are parsed at runtime and rendered directly into the framebuffer.
A binary format optimized for small size and fast parsing. It contains:
- Metadata: font name, author, kerning, size
- Character layout, widths, and pixel bitmap (1-bit)
Note: Custom fonts can be made using the [CBF generator](https://github.com/dipdowel/compact-bitmap-font) .
utils::math::rngβ deterministic and random generatorsutils::math::geometry::regionβ bounding regions for layoutsutils::color::adaptersβ fast color format conversionsutils::color::palettesβ predefined color palettesutils::pixel_copy::image_dataβ copy and transform raw buffers
- All rendering happens in system memory β no GPU (unless you enable experimental GPU support via the
gpufeature flag). - Unsafe operations are avoided unless performance requires it.
- Custom numeric traits are used (
Numeric) to support generic math. - Tests are included to verify precision and corner cases.
- https://github.com/dipdowel/graph1_wasm_demo
- A collection of demos implemented with Graph1
- Guides and tutorials
- See it in action on https://graph1.codument.com
- https://github.com/dipdowel/graph1_app_template
- A bare-minimum app template to kick off your Graph1 project.
- https://github.com/dipdowel/graph1_minifb_demo
- Run demos from `graph1_wasm_demo` locally using `minifb`
- https://github.com/dipdowel/compact-bitmap-font
- Compact bitmap font generator. Such fonts can be rendered by Graph1.
- There is a highly experimental GPU support in Graph1, which is enabled by the
gpufeature flag. - The GPU is utilized by means of OpenCL (which may not be the optimal choice, but hey, an experiment is an experiment!).
sudo apt-get install intel-opencl-icd ocl-icd-opencl-dev clinfo ocl-icd-libopencl1 opencl-headers- Find and install the latest AMD drivers for your system
sudo amdgpu-install
# or
sudo amdgpu-install --opencl=legacy,rocr
# then
sudo apt-get install ocl-icd-opencl-dev clinfo ocl-icd-libopencl1 opencl-headers This project uses multiple licenses:
- Source code: Licensed under the MIT License.
- Font family "Matriks Uaxactun": Licensed separately under custom terms in FONT-MATRIKS-UAXACTUN.
The projectβs overall license expression is:
SPDX-License-Identifier: MIT AND LicenseRef-FONT-MATRIKS-UAXACTUN
- The font family may only be used when the Graph1 library is included as a dependency in a Rust project and must remain embedded in the library.
- Any project that embeds or redistributes the font family through Graph1 must also include the FONT-MATRIKS-UAXACTUN license file.
- Add documentation on how to load custom fonts
It contains some useful bits which need to be cleaned up, reorganized, and incorporated into the new version (above).
Application code is code that uses Graph1 library.
- Graph1 is a zero-dependency library for producing and manipulating graphical primitives, e.g. lines, curves, simple geometric shapes. It also can render texts using pixel fonts.
- Graph1 can be used for creating static images, animations, 2D computer game graphics (non-GPU), etc.
- Graph1 does not read or write files, but it can accept data from files read by your application code.
- Keeping any static state is outside the scope of Graph1. This should be done in the application code.
At the moment of writing, Graph1 uses 0RGB encoding for a pixel, which means that the upper 8-bits are ignored,
the next 8 bits are for the R channel, then 8 bits for the G channel, and the last 8 bits for the B channel. This helps
to avoid any extra conversion while working with library minifb.
Eventually, we may move to ARGB model, but that's not the case now.
Some operations in Graph1 can be performed in parallel. For example, filling a buffer with a color, copying one buffer to another, etc.
The buffer gets split into chunks, and each chunk is processed by a separate thread. In lower-level functions,
the number of threads must be passed explicitly. In higher-level functions, the number of threads to spawn read taken from GraphContext.num_threads.
Here's a list of functions that support multithreading:
draw::tools::fill::buffer()- fills a buffer with a colordraw::rectangle::filled()- draws a filled rectanglefx::scanline::window()- applies a scanline effect to a windowutils::color::adapters::rgba_to_0rgb::rgba_to_0rgb()- converts an RGBA buffer to 0RGB- To be continued...
Graph1 will not perform the multithreaded operation at all (in most cases this is not what you want).
Graph1 will use only the main thread to perform the operation
Graph1 will spawn num_threads threads to perform the operation. The relevant buffer(s) will be split into num_threads chunks,
and each chunk will be processed by a separate thread. Main thread will wait for all the spawned threads to finish their work.
By default, the following pixel fonts are available in Graph1 framework:
The default fonts are stored in the Graph1 sourcecode and are encoded in CBF format (see below).
They are embedded directly into a compiled application using include_bytes!().
It is also possible to load and use your custom pixel fonts (see section "Using custom pixel fonts").
"CBF" stands for "Compact Bitmap Font". It is a simple non-compressed binary format for storing pixel fonts as raw binary data. An CBF-file contains a header with metadata and some data sizes, and a body with some textual information and the bits representing the font itself.
- [0x0] - magic number
CBF0for "Compact Bitmap F0nt" - [0x1] - version of CBF format
- [0x2] - size of
font_name, size of the name of the font - [0x3] - size of
author_signature, size of the author's name - [0x4] - size of
char_order - [0x5] - size of
char_width - [0x6] - font image width
- [0x7] - font image height
- [0x8] - spacing props: lower byte -- kerning, higher byte -- leading.
- [0x9] - UTF8 default char: lower 2 bytes.
- [0xa] - UTF8 default char: higher 2 bytes.
- [0xb] - version of the font
- [0xc] - date: year
- [0xd] - date: lower byte -- day, higher byte -- month.
The font body consists of a few fields of variable length. All the lengths are listed in the header.
Font body fields:
font_name- A string with the name of the font.author_signature- A string with the name of the author of the font.char_order- order of characters in the font.char_widths- how many pixels wide each char is. The order of values matches the order of chars inchar_orderfont_pixel_data- 1-bit image data of the font (0 for black, 1 for white)
Graph1 parses an
TODO:Come up with how to create and add custom fontsTODO:Explain how to add custom fonts, etc.
