SkillAgentSearch skills...

Fbg

Lightweight C 2D graphics API agnostic library with parallelism support

Install / Use

/learn @grz0zrg/Fbg

README

FBGraphics : Lightweight C 2D graphics API agnostic library with parallelism support

FBGraphics (FBG) is a simple C 24, 32 bpp (internal format) graphics library with parallelism and custom rendering backend support (graphics API agnostic).

The library is only two .c files on most use cases, the renderer agnostic library fbgraphics.c and one of the rendering backend found in custom_backend directory.

The library come with five backend (see custom_backend folder) :

  • a Linux framebuffer rendering backend (with 16 bpp support through 24/32 bpp conversion)
  • OpenGL backend which use the GLFW library
  • OpenGL ES 2.0 backend for fbdev or Raspberry PI
  • fast dispmanx backend (Video Core IV; Raspberry PI)
  • GBA backend (slow due to 24/32 bpp -> 16 bpp support, mostly done as a proof of concept for portability on low memory hardware)

Features :

  • Easy to write / use custom rendering backend support flexible enough to target low memory hardware!
  • Cross-platform with the GLFW backend (some examples may need to be adapted to the target OS)
  • Linux framebuffer (fbdev) rendering backend support
    • Double buffering (with optional page flipping mechanism)
    • 16, 24 (BGR/RGB), 32 bpp support
  • GBA rendering backend
  • OpenGL rendering backend through GLFW
  • OpenGL ES 2.0 rendering backend for Raspberry PI or through fbdev (tested on Nano PI Fire 3 board)
  • dispmanx rendering backend (Video Core IV; Raspberry PI)
  • Optional : Full parallelism, execute graphics code on multiple CPU cores with a single function
  • Image loading (provided by LodePNG, NanoJPEG, and stb_image)
  • Bitmap fonts for drawing texts
  • Bare-metal graphics primitive (pixels, rectangles, lines, polygon)
  • Easy to do fading, clipping and screen-clearing related effects (motion blur etc.)
  • Drawing calls can be used to render into a specified target buffer such as fbg_image etc.
  • Framerate tracking & display for all cores
  • Lightweight enough to be hackable; adapt to all kinds of needs (and still support parallelism easily)

The library is generic, most functions (including parallel ones) only manipulate buffers and you can build a custom rendering backend pretty easily with few functions call, see the custom_backend folder.

Doxygen documentation : https://grz0zrg.github.io/fbg/

Table of Contents

About

FBGraphics was built to produce fullscreen pixels effects easily (think of Processing-like creative coding etc.) with non-accelerated framebuffer by leveraging multi-core processors, it is a bit like a software GPU but much less complex and featured, the initial target platform was a Raspberry PI 3B / NanoPI.

FBGraphics was extended to support any numbers of custom rendering backend; all graphics calls manipulate internal buffers and a simple interface allow to draw the result the way you want to.

FBGraphics can support low memory hardware such as GBA. It should be noted that all internal buffers are manipulated in 24/32 bpp so it has to convert to 16bpp on GBA.

An OpenGL rendering backend which use the GLFW library was created to demonstrate the custom backend feature, it allow to draw the non-accelerated FB Graphics buffer into an OpenGL context through a texture and thus allow to interwine 3D or 2D graphics produced with standard OpenGL calls with CPU-only graphics produced by FBGraphics draw calls.

An OpenGL ES 2.0 backend is also available with similar features, it target platforms with support for OpenGL ES 2.0 through fbdev (tested on Nano PI Fire 3 SBC) or Raspberry PI dispmanx and similar platforms, it wouldn't be hard to extend this for more OpenGL ES 2.0 platforms...

There is also a dispmanx backend targeting Raspberry PI, it have better performances than the OpenGL ES 2 backend on this platform and is recommended if you don't need 3D stuff.

FBGraphics was built so that it is possible to create any number of rendering context using different backend running at the same time while exploiting multi-core processors... the content of any rendering context can be transfered into other context through images when calling fbg_drawInto

FBGraphics framebuffer settings support 16, 24 (BGR/RGB), 32 bpp, 16 bpp mode is handled by converting from 24 bpp to 16 bpp upon drawing, page flipping mechanism is disabled in 16 bpp mode, 24 bpp is the fastest mode.

FBGraphics is lightweight and does not intend to be a fully featured graphics library, it provide a limited set of graphics primitive and a small set of useful functions to start doing computer graphics anywhere right away with or without multi-core support.

If you want to use the parallelism features with advanced graphics primitives, take a look at great libraries such as libgd, Adafruit GFX library or even ImageMagick which should be easy to integrate.

FBGraphics is fast but should be used with caution, display bounds checking is not implemented on most primitives, this allow raw performances at the cost of crashs if not careful.

Multi-core support is optional and is only enabled when FBG_PARALLEL C definition is present.

FBGraphics framebuffer backend support a mechanism known as page flipping, it allow fast double buffering by doubling the framebuffer virtual area, it is disabled by default because it is actually slower on some devices. You can enable it with a fbg_fbdevSetup call.

VSync is automatically enabled if supported.

Note : FBGraphics framebuffer backend does not let you setup the framebuffer, it expect the framebuffer to be configured prior launch with a command such as :

fbset -fb /dev/fb0 -g 512 240 512 240 24 -vsync high
setterm -cursor off > /dev/tty0

fbset should be available in your package manager.

Framebuffer Quickstart

The simplest example (no parallelism, without texts and images) :

#include <sys/stat.h>
#include <signal.h>

#include "fbg_fbdev.h"
#include "fbgraphics.h"

int keep_running = 1;

void int_handler(int dummy) {
    keep_running = 0;
}

int main(int argc, char* argv[]) {
    signal(SIGINT, int_handler);

    struct _fbg *fbg = fbg_fbdevSetup("/dev/fb0", 0); // you can also directly use fbg_fbdevInit(); for "/dev/fb0", last argument mean that will not use page flipping mechanism  for double buffering (it is actually slower on some devices!)

    do {
        fbg_clear(fbg, 0); // can also be replaced by fbg_fill(fbg, 0, 0, 0);

        fbg_draw(fbg);

        fbg_rect(fbg, fbg->width / 2 - 32, fbg->height / 2 - 32, 16, 16, 0, 255, 0);

        fbg_pixel(fbg, fbg->width / 2, fbg->height / 2, 255, 0, 0);

        fbg_flip(fbg);

    } while (keep_running);

    fbg_close(fbg);

    return 0;
}

A simple quickstart example with most features (but no parallelism, see below) :

#include <sys/stat.h>
#include <signal.h>

#include "fbg_fbdev.h"
#include "fbgraphics.h"

int keep_running = 1;

void int_handler(int dummy) {
    keep_running = 0;
}

int main(int argc, char* argv[]) {
    signal(SIGINT, int_handler);

    struct _fbg *fbg = fbg_fbdevInit();

    struct _fbg_img *texture = fbg_loadImage(fbg, "texture.png");
    struct _fbg_img *bb_font_img = fbg_loadImage(fbg, "bbmode1_8x8.png");

    struct _fbg_font *bbfont = fbg_createFont(fbg, bb_font_img, 8, 8, 33);

    do {
        fbg_clear(fbg, 0);

        fbg_draw(fbg);

        // you can also use fbg_image(fbg, texture, 0, 0)
        // but you must be sure that your image size fit on the display
        fbg_imageClip(fbg, texture, 0, 0, 0, 0, fbg->width, fbg->height);

        fbg_write(fbg, "Quickstart example\nFPS:", 4, 2);
        fbg_write(fbg, fbg->fps_char, 32 + 8, 2 + 8);

        fbg_rect(fbg, fbg->width / 2 - 32, fbg->height / 2 - 32, 16, 16, 0, 255, 0);

        fbg_pixel(fbg, fbg->width / 2, fbg->height / 2, 255, 0, 0);

        fbg_flip(fbg);

    } while (keep_running);

    fbg_freeImage(texture);
    fbg_freeImage(bb_font_img);
    fbg_freeFont(bbfont);

    fbg_close(fbg);

    return 0;
}

Note : Functions like fbg_clear or fbg_fpixel are fast functions, there is slower equivalent (but more parametrable) such as fbg_background or fbg_pixel, some functions variant also support transparency such as ``fbg_pixelaorfbg_recta`.

Note : You can generate monospace bitmap fonts to be used with fbg_createFont function by using my monoBitmapFontCreator tool available here

Parallelism

Exploiting multiple cores with FBGraphics is really easy, first you have to prepare 3 functions (of which two are optional if you don't have any allocations to do) of the following definition :

// optional function
void *fragmentStart(struct _fbg *fbg) {
    // typically used to allocate your per-thread data
    // see full_example.c for more informations

    return NULL; // return your user data here
}
void fragment(struct _fbg *fbg, struct _fragment_user_data *user_data) {
    // this function will be executed by each threads
    // you are free to call any FBG graphics primitive here
    
    fbg_clear(fbg, 0);
    
    // you are also free to fill each threads back buffer the way you want to
    // fbg->task_id : thread identifier (starting at 

Related Skills

View on GitHub
GitHub Stars525
CategoryCustomer
Updated3mo ago
Forks41

Languages

C

Security Score

97/100

Audited on Dec 19, 2025

No findings