framebuffer graphic example

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <stdint.h>
#include <errno.h>
typedef struct __box
{
        int x;
        int y;
        int dx;
        int dy;
        uint32_t c;
} Box;
int frame_buffer_handle;
long lastms;
struct fb_var_screeninfo varinfo;
struct fb_fix_screeninfo fixinfo;
void draw_pixel(uint32_t *video_buffer, int y, int x, uint32_t c);
void fill_screen(uint32_t *video_buffer, uint32_t c);
void draw_rect(uint32_t *video_buffer, int dy, int dx, int w, int h, uint32_t c);
int msleep(long);
long msnow();
long msnow()
{
        struct timespec _t;
        clock_gettime(CLOCK_REALTIME, &_t);
        return _t.tv_sec * 1000 + _t.tv_nsec / 1000000;
}
int msleep(long msec)
{
        struct timespec ts;
        int res;

        if (msec < 0)
        {
                errno = EINVAL;
                return -1;
        }

        ts.tv_sec = msec / 1000;
        ts.tv_nsec = (msec % 1000) * 1000000;

        do
        {
                res = nanosleep(&ts, &ts);
        } while (res && errno == EINTR);

        return res;
}

void draw_rect(uint32_t *video_buffer, int dy, int dx, int w, int h, uint32_t c)
{
        for (int y = dy; y < dy + h; y++)
                for (int x = dx; x < dx + w; x++)
                        draw_pixel(video_buffer, y, x, c);
}

void fill_screen(uint32_t *video_buffer, uint32_t c)
{
        for (int y = 0; y < varinfo.yres; y++)
                for (int x = 0; x < varinfo.xres; x++)
                        draw_pixel(video_buffer, y, x, c);
}
void draw_pixel(uint32_t *video_buffer, int y, int x, uint32_t c)
{
        uint32_t offset = varinfo.yoffset == 0 ? varinfo.yres : 0;
        uint32_t *addr = video_buffer + ((y + offset) * (fixinfo.line_length >> 2)) + x;
        *addr = c;
}
void refresh_screen(int delay)
{
        uint32_t offset = varinfo.yoffset == 0 ? varinfo.yres : 0;
        varinfo.yoffset = offset;
        int ret = ioctl(frame_buffer_handle, FBIOPAN_DISPLAY, &varinfo);
        if (delay == 1)
        {
                long now = msnow();
                if (now - lastms < 40)
                {
                        msleep(40 - (now - lastms));
                }
                lastms = msnow();
        }
}
int main()
{
        lastms = msnow();
        int tty_fd = open("/dev/tty0", O_RDWR);
        ioctl(tty_fd, KDSETMODE, KD_GRAPHICS);
        srand(time(NULL));
        frame_buffer_handle = open("/dev/fb0", O_RDWR);
        ioctl(frame_buffer_handle, FBIOGET_FSCREENINFO, &fixinfo);
        printf("id: %s\n", fixinfo.id);
        printf("smem_start: %ld\n", fixinfo.smem_start);
        printf("smem_len: %d\n", fixinfo.smem_len);
        printf("line_lenth: %d\n", fixinfo.line_length);

        ioctl(frame_buffer_handle, FBIOGET_VSCREENINFO, &varinfo);
        printf("resx:%d,resy:%d\n", varinfo.xres, varinfo.yres);
        printf("x_virtual:%d,y_virtual:%d\n", varinfo.xres_virtual, varinfo.yres_virtual);
        printf("x_offset:%d,y_offset:%d\n", varinfo.xoffset, varinfo.yoffset);
        printf("bits_per_pixel:%d\n", varinfo.bits_per_pixel);

        size_t len = fixinfo.line_length * varinfo.yres;
        uint32_t *video_buffer = mmap(NULL, len * 2, PROT_READ | PROT_WRITE, MAP_SHARED, frame_buffer_handle, 0);

        fill_screen(video_buffer, 0xff0000ff);

        int box_count = 500;
        Box box[box_count];
        for (int i = 0; i < box_count; i++)
        {
                box[i].x = rand() % 380 * 2;
                box[i].dx = rand() % 380 * 2;
                box[i].y = rand() % 280 * 2;
                box[i].dy = rand() % 280 * 2;
                box[i].c = ((rand() % 256) << 24) + ((rand() % 256) << 16) + ((rand() % 256) << 8) + rand() % 256;
        }
        int msstart = msnow();
        printf("start at:%ld\n", msstart);
        for (int r = 0; r < 500; r++)
        {
                for (int i = 0; i < box_count; i++)
                {
                        if (box[i].x == box[i].dx && box[i].y == box[i].dy)
                        {
                                box[i].dy = rand() % 280 * 2;
                                box[i].dx = rand() % 380 * 2;
                        }
                        else
                        {
                                if (box[i].x != box[i].dx)
                                {
                                        box[i].x += box[i].x > box[i].dx ? -2 : 2;
                                }
                                if (box[i].y != box[i].dy)
                                {
                                        box[i].y += box[i].y > box[i].dy ? -2 : 2;
                                }
                        }
                }
                fill_screen(video_buffer, 0xff0000ff);
                for (int i = 0; i < box_count; i++)
                {
                        draw_rect(video_buffer, box[i].y, box[i].x, 32, 32, box[i].c);
                }
                refresh_screen(1);
        }
        int msstop = msnow();
        printf("stop at:%ld\n", msstop);
        printf("fps:%d\n", (500 * 1000) / (msstop - msstart));
        ioctl(tty_fd, KDSETMODE, KD_TEXT);
        printf("\n");
        return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值