Applying C - Framebuffer Graphics
Written by Harry Fairhead   
Monday, 10 June 2019
Article Index
Applying C - Framebuffer Graphics
Color
The Main Program

We also need a function to get a block of pixels and a function to restore them:

void saveBlock(uint32_t x, uint32_t y, uint32_t L,
                                    uint32_t block[]) {
  for (int i = 0; i < L; i++) {
    for (int j = 0; j < L; j++) {
      block[i+j*L] = getRawPixel(x + i, y + j);
    }
  }
}
void restoreBlock(uint32_t x, uint32_t y, uint32_t L, 
uint32_t block[]) { for (int i = 0; i < L; i++) { for (int j = 0; j < L; j++) { setRawPixel(x + i, y + j, block[i+j*L]); } } }

The pixel data is stored in a one-dimensional array simulating a two-dimensional array to avoid the problems of passing a variable size two-dimensional array.

Now we can start on the main program. First we need the includes and some data structures:

#define _POSIX_C_SOURCE  199309L
#include <stdio.h>
#include <stdlib.h>
#include <linux/fb.h>
#include <fcntl.h> 
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <inttypes.h>
#include <time.h>
#define BLOCKSIZE 10
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
uint8_t *fbp;
uint32_t block[BLOCKSIZE*BLOCKSIZE];
struct color {
    uint32_t r;
    uint32_t g;
    uint32_t b;
    uint32_t a;
};

The fbp variable is a global pointer to the start of the framebuffer. First we need to set up the framebuffer:

int main(int argc, char** argv) {
    int fd = open("/dev/fb0", O_RDWR);
    ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
    ioctl(fd, FBIOGET_FSCREENINFO, &finfo);
    vinfo.grayscale = 0;
    vinfo.bits_per_pixel = 32;
    ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo);
    ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);   
    fbp = mmap(0, vinfo.yres * finfo.line_length, 
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

With the framebuffer set up we can write a bounce program ignoring the details of how the graphics are being created:

struct color c = {0xFF, 0x00, 0x00, 0xFF};
int x = 600;
int y = 400;
int vx = -1;
int vy = -1;
struct timespec pause;
pause.tv_sec = 0;
pause.tv_nsec = 20 * 1000*1000;
saveBlock(x, y, BLOCKSIZE,block);
for (;;) {
    restoreBlock(x, y, BLOCKSIZE, block);
    x = x + vx;
    y = y + vy;
    if (x <= 0) {
       x = 0; vx = -vx;
    }
    if (y <= 0) {
       y = 0; vy = -vy;
    }
    if ((x + BLOCKSIZE) >= vinfo.xres) {
       x = vinfo.xres - BLOCKSIZE - 1;
       vx = -vx;
    }
    if ((y + BLOCKSIZE) >= vinfo.yres) {
       y = vinfo.yres - BLOCKSIZE - 1;
       vy = -vy;
    }
    saveBlock(x, y, BLOCKSIZE, block);
    setBlock(x, y, BLOCKSIZE, c);
    nanosleep(&pause, NULL);
    } 
    return (EXIT_SUCCESS);
}

The if statements check to see if the ball is about to go off the screen and if it is then it is bounced by reversing the appropriate velocity and settings its position to be on the edge of the screen. The speed of the bounce can be determined by the time delay used in nanosleep. The ball will bounce around the screen, overwriting, but not destroying, anything else on the screen. There are various system "glitches" that can spoil the effect. In particular, the activation of any screensaver will result in the ball leaving a trail behind.

If you are familiar with other graphics environments, you might be wondering how to synchronize your graphics update to the screen refresh. You can try looking up the ioctl FBIO_WAITFORVSYNC call, which waits for a vertical sync to occur. The problem is that many graphics cards do not implement it.

Also included in the chapter:

  • Framebuffer Text PSF 1
  • Framebuffer Text PSF 2
  • Windowing Systems - X11
  • Device, Screen and Window
  • Graphics Functions
  • An Example
  • Color
  • Events
  • GTK - a GUI Framework
  • A First Window
  • Glade
  • Graphics Beyond GTK

Summary

  • Selecting a graphics system for Linux is difficult because there is so much choice and many different levels of operation.

  • The framebuffer gives you direct access to the graphics buffer.

  • You can use it to write directly to the screen and it doesn't take account of windows or any other part of the GUI.

  • It is possible to use font files to write text to the framebuffer.

  • The standard window system is X11 and it has a client-server architecture with the program that does the drawing as the client, and the program that does the rendering on a device as the server.

  • X11 can be used via the Xlib library.

  • X11 can also handle user input and for this you have to implement an event handling loop.

  • The GTK Framework is a complete GUI system with windows, buttons and events.

  • The structure of almost any GUI framework makes your program asynchronous and this can be confusing at first.

  • You can use GTK via function calls, but it is much easier to use the Glade drag-and-drop editor.

 

Now available as a paperback or ebook from Amazon.

Applying C For The IoT With Linux

  1. C,IoT, POSIX & LINUX
  2. Kernel Mode, User Mode & Syscall
  3. Execution, Permissions & Systemd
  4. Signals & Exceptions
  5. Integer Arithmetic
  6. Fixed Point
  7. Floating Point
  8. File Descriptors
  9. The Pseudo-File System
    Extract: The Pseudo File System 
  10. Graphics
    Extract: framebuffer 
  11. Sockets
  12. Threading
    Extract  Condition Variables
    Extract  Deadline Scheduling ***NEW
  13. Cores Atomics & Memory Management
  14. Interupts & Polling
  15. Assembler

Also see the companion book: Fundamental C

<ASIN:1871962609>

<ASIN:1871962463>

<ASIN:1871962617>

<ASIN:1871962455>

Related Articles

Remote C/C++ Development With NetBeans

Raspberry Pi And The IoT In C

Getting Started With C/C++ On The Micro:bit

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on, Twitter, Facebook or Linkedin.

Banner


SQLite Improves Nulls Support
10/10/2019

The latest release of SQLite is available with support for Nulls in Order By clauses and the ability to use Filter on aggregate functions.



CodeSearchNet Challenge To Improve Semantic Code Search
27/09/2019

As developers we are only too aware of the difficulty of finding relevant code using a natural language query. Now GitHub has released a large dataset of code and natural language comment  with t [ ... ]


More News

graphics

 



 

Comments




or email your comment to: comments@i-programmer.info

 



Last Updated ( Monday, 01 July 2019 )