Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building library for 1 bpp Display #22

Open
MichaelYankin opened this issue May 22, 2024 · 1 comment
Open

Building library for 1 bpp Display #22

MichaelYankin opened this issue May 22, 2024 · 1 comment

Comments

@MichaelYankin
Copy link

Hello!

I'm trying to use this library for my project with a monochrome oled. I know that your library only supports 8 bpp framebuffer devices, but maybe you have any tips to me, how can I use your library for my project? Thank you.

Best regards,
Michael

@grz0zrg
Copy link
Owner

grz0zrg commented May 25, 2024

Hello,

the library only support some bpp for most drawing functions but you can work around this limitation with a custom backend, it does the job but will be likely slow and overkill, i don't know your device and never did anything on monochrome devices but you may look at the Game Boy Advance backend for a simple backend example with an initially non-supported device : https://github.com/grz0zrg/fbg/tree/master/custom_backend/gba

It does 24 or 32 bpp internally but convert to the GBA display format on draw so that all library functions can be used without changes.

The way to adapt it to a 1 bpp device would be to allocate a 1 bpp buffer then rewrite the draw function, something like this (untested and assuming you can copy the buffer to the device) :

// fbg_test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "fbg_test.h" // define your test_context struct with the buffer in this file

void fbg_testDraw(struct _fbg *fbg);

struct _fbg *fbg_testSetup() {
    struct _fbg_test_context *test_context = (struct _fbg_test_context *)calloc(1, sizeof(struct _fbg_test_context));
    if (!test_context) {
        return NULL;
    }

    // your display width / height
    int width = 240;
    int height = 160;

    // 1 bpp buffer (which may be sent to the hardware)
    test_context->buffer = calloc(1, width * height * sizeof(char));

    struct _fbg *fbg = fbg_customSetup(width, height, 3, 0, 0, (void *)test_context, fbg_testDraw, NULL, NULL, NULL);
    if (!fbg) {
        return NULL;
    }

    fbg->back_buffer = calloc(1, fbg->size * sizeof(char));
    if (!fbg->back_buffer) {
        return NULL;
    }
    
    return fbg;
}

void fbg_testDraw(struct _fbg *fbg) {
    struct _fbg_test_context *test_context = fbg->user_context;

    int x, y;
    for (x = 0; x < fbg->width; ++x) {
        for (y = 0; y < fbg->height; ++y) {
            int index = x + y * fbg->width;

            int red = fbg->back_buffer[index * fbg->components];
            test_context->buffer[index] = red;
        }
    }

    // copy test_context->buffer to the device
}

and to test the backend compile this with fbgraphics.c and fbg_test.c :

#include "fbg_test.h"

int main() {
	struct _fbg *fbg = fbg_testSetup();

	// draw on internal buffer
	fbg_line(fbg, 0, 0, fbg->width, fbg->height, 255, 0, 0);

	while (1) {
		// convert + copy to hw
		fbg_draw(fbg);
	}

	return 0;
}

maybe you can also just use the hardware memory directly if available
you may also have to write a free function depending on what you want (see fbg_customSetup parameters)

If you don't want to convert from high bpp to low bpp you may have to rewrite the drawing functions or use the simpler ones that support this.

If the question is for a 1 bpp Linux framebuffer then there should be minor changes to the setup function in https://github.com/grz0zrg/fbg/tree/master/custom_backend/fbdev to make it open the framebuffer with this format and a conversion step in fbg_fbdevDraw

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants