Skip to content

dipdowel/graph1

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Graph1

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.


project-screenshot.png



✨ Features

  • 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.

πŸ—ΊοΈ Roadmap

Please refer to the ROADMAP.md for plans on future features and improvements.


πŸ“„ What Graph1 Is

  • A software renderer for 2D graphics.
  • A toolkit for manipulating pixels, shapes, and effects.
  • A real-time capable drawing engine for dynamic visuals.

⛔️ What Graph1 is/does Not

  • 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.

πŸ–‹οΈ Drawing Contexts

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.


🌈 Colors and Pixels

  • Graph1 uses RGBA model for color representation.
  • The resulting framebuffer can be converted to other color models before being sent to the graphics output.

πŸš€ Multithreaded Rendering

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-threaded
  • n > 1 β†’ use n threads to divide workload

Some of the functions that support multithreading:

  • draw::tools::fill::buffer
  • draw::rectangle::filled
  • fx::scanline::window
  • utils::color::adapters::rgba_to_0rgb

🌐 Geometry and Drawing

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


πŸ“… Fonts and Text

Graph1 ships with pixel fonts embedded using the CBF (Compact Bitmap Font) format.

Embedded fonts:

  • c_c_red_alert_inet0
  • c_c_red_alert_inet1 (LAN)

These fonts are parsed at runtime and rendered directly into the framebuffer.

CBF format:

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) .


βš’οΈ Utilities

  • utils::math::rng β€” deterministic and random generators
  • utils::math::geometry::region β€” bounding regions for layouts
  • utils::color::adapters β€” fast color format conversions
  • utils::color::palettes β€” predefined color palettes
  • utils::pixel_copy::image_data β€” copy and transform raw buffers

⚠️ Safety and Performance Notes

  • All rendering happens in system memory β€” no GPU (unless you enable experimental GPU support via the gpu feature 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.

✨ Examples and links

Experimental GPU support.

  • There is a highly experimental GPU support in Graph1, which is enabled by the gpu feature flag.
  • The GPU is utilized by means of OpenCL (which may not be the optimal choice, but hey, an experiment is an experiment!).

Prerequisites

Linux, Intel iGPU

sudo apt-get install intel-opencl-icd ocl-icd-opencl-dev clinfo ocl-icd-libopencl1 opencl-headers

Linux, AMD iGPU

  1. 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 

πŸŽ“ License

This project uses multiple licenses:

SPDX Notice

The project’s overall license expression is:

SPDX-License-Identifier: MIT AND LicenseRef-FONT-MATRIKS-UAXACTUN

Important Notes

  • 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.

🚨 TODOs

  • Add documentation on how to load custom fonts

NB: Below is an older version of the README.md file.

It contains some useful bits which need to be cleaned up, reorganized, and incorporated into the new version (above).





Graph1

Application code is code that uses Graph1 library.

What Graph1 is and what it does

  • 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.

What Graph1 is not and what it does not do

  • 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.

Working with color

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.

Multithreaded operations

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 color
  • draw::rectangle::filled() - draws a filled rectangle
  • fx::scanline::window() - applies a scanline effect to a window
  • utils::color::adapters::rgba_to_0rgb::rgba_to_0rgb() - converts an RGBA buffer to 0RGB
  • To be continued...

num_threads == 0

Graph1 will not perform the multithreaded operation at all (in most cases this is not what you want).

num_threads == 1

Graph1 will use only the main thread to perform the operation

num_threads > 1

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.

Fonts

Default embedded fonts

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 font format

"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.

The header

Header consists of a bunch of u16 values:

  • [0x0] - magic number CBF0 for "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 body

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 in char_order
  • font_pixel_data - 1-bit image data of the font (0 for black, 1 for white)

CBF parsing

Graph1 parses an

Creating and/or using your own pixel fonts

  • TODO: Come up with how to create and add custom fonts
  • TODO: Explain how to add custom fonts, etc.

About

Some experiments with graphics using Rust

Resources

License

Stars

Watchers

Forks

Packages

No packages published