Thursday, 3 December 2015

Low-level Graphics on Raspberry Pi (palette)

Again life has happened and the time has slipped. Thanks for the response on the Raspberry Pi forum. To iterate the message from there: I have disabled comments here because I cannot guarantee any kind of decent response time, sorry.

Just a quick, short one now on something I came across trawling through old stuff. Palette animation a.k.a color cycling (Wikipedia) is a technique that might produce interesting effects when applied to a suitably arranged image. In most cases it is likely to be a lot faster than redrawing the actual pixels. Continuing from the fbtest5.c introduced in Part V we can animate the palette like this:
        // draw...
        draw();
        sleep(1);

        int j;
        for(j = 0; j < 16; j++) {
            for(i = 0; i < 16; i++) {
                // rotate the original values based on j changing...
                r[i] = def_r[(i + j + 1) % 16] << 8;
                g[i] = def_g[(i + j + 1) % 16] << 8;
                b[i] = def_b[(i + j + 1) % 16] << 8;
            }
            // Note that we set up the 'pal' structure earlier
            // and it still points to the r, g, b arrays,
            // so we can just reuse 'pal' here
            if (ioctl(fbfd, FBIOPUTCMAP, &pal)) {
                printf("Error setting palette.\n");
            }
            sleep(1);
        }
...which should cycle the color bars in the lower half of the screen.

[Full source available in GitHub]

[Continued in next part Images]

Tuesday, 27 January 2015

Low-level Graphics on Raspberry Pi (part X update III)

Finally managed to find the cause for the (intermittent - reproducible at will only straight after boot) screen blanking issue (mentioned in previous post): the changes in the framebuffer driver seem to require the calls to KDSETMODE to be inside the FBIOPUT_VSCREENINFO calls... Fixed code now in GitHub

Tuesday, 6 January 2015

Low-level Graphics on Raspberry Pi (part X update II)

Finally... in continuation to this post, after some elaboration on the forum I managed to get down to testing this properly - it appears that the changes in the fb driver can be made to work! Replace the 'switch page' by either (ioctl version):
        // switch page
        // ioctl version
        vinfo.yoffset = cur_page * vinfo.yres;
        ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo);
        ioctl(fbfd, FBIO_WAITFORVSYNC, 0);
or (mailbox version):
        // switch page
        // mailbox version
        vx = 0;
        vy = cur_page * vinfo.yres;
        set_fb_voffs(&vx, &vy);
        ioctl(fbfd, FBIO_WAITFORVSYNC, 0);
Curiously the order has to be pan first - wait for vsync after... Obviously if going for the 'ioctl only version' one can scrap all the extra code and there is no need to create the char_dev node etc.

Cleaned up 'pure Linux fb' version of the code available in GitHub. Compile with (as I took out the timing code no need for the rt lib):
gcc -O2 -o fbtestXIV fbtestXIV.c
And run with:
fbset -depth 8
./fbtestXIV
...as it appears the latest Raspbian builds require forcing the framebuffer mode to 8-bit colors before running the examples where 8-bit mode is set. Later the mode can be freely set and the examples run fine... If you want to time the execution use:
time ./fbtestXIV
...which should give just over 10 s if we managed to produce 60 fps for 10 seconds.