免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1486 | 回复: 0
打印 上一主题 下一主题

基于FrameBuffer的简易图形库开发 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-01 08:56 |只看该作者 |倒序浏览
QT不是基于FrameBuffer的吗,现在被Nokia收购了,可惜对于很简单的应用,QT太宠大了,既然知道FrameBuffer的工作原理,自己写一个也行啊,找了找资料,写了以下的代码,当然功能极其简单,实现的基本原理是将FrameBuffer的物理内容映射到进程空间内,然后直接对这段内存进行写操作,这样就会直接将数据显示在屏幕上。
//zsygui.h
#ifndef __ZSYGUI_H__
#define __ZSYGUI_H__
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ERR(fmt,args...) printf("Error:" fmt,##args)
/*frame buffer device structure*/
struct fb_dev{
int fd; /*file descriptor*/
struct fb_fix_screeninfo fixinfo;
struct fb_var_screeninfo varinfo;
char *addr; /*map address*/
int fb_size; /*frame buffer size*/
char *buffer; /*buffer,equals to framebufer's size*/
};
struct fb_dev* zsygui_open(const char *device,int mode);
extern int zsygui_flush_buffer(struct fb_dev *pdev);
extern int zsygui_fill_color(struct fb_dev*pdev,int color);
extern int zsygui_draw_line(struct fb_dev *pdev,int whichline,int startpos,int endpos,int color);
extern int zsygui_close(struct fb_dev *pdev);
#endif //__ZSYGUI_H__

//zsygui.c
#include "zsygui.h"
struct fb_dev* zsygui_open(const char *device,int mode){
struct fb_dev *dev=(struct fb_dev*)malloc(sizeof(struct fb_dev));
if(!dev){
  return NULL;
}
if(!device){
  free(dev);
  return NULL;
}
if((dev->fd=open(device,mode))fd,FBIOGET_FSCREENINFO,&dev->fixinfo)==-1){
  printf("ioctl failed.\n");
  free(dev);
  return NULL;
}
if(ioctl(dev->fd,FBIOGET_VSCREENINFO,&dev->varinfo)==-1){
  printf("ioctl failed.\n");
  free(dev);
  return NULL;
}
//frame buffer size
dev->fb_size=(dev->varinfo.yres) * (dev->fixinfo.line_length);
//map physical address to process virtual address
dev->addr=mmap(NULL,dev->fb_size,PROT_READ|PROT_WRITE,MAP_SHARED,dev->fd,0);
if(!dev->addr){
  printf("mmap failed.\n");
  free(dev);
  return NULL;
}
//allocate the same size buffer
dev->buffer=(char*)malloc(dev->fb_size);
if(!dev->buffer){
  printf("malloc failed.\n");
  free(dev);
  return NULL;
}
memset(dev->buffer,0,dev->fb_size);
return dev;
}
int zsygui_fill_color(struct fb_dev*pdev,int color){
if(!pdev){
  return -1;
}
memset(pdev->buffer,color,pdev->fb_size);
zsygui_flush_buffer(pdev);
return 0;
}
int zsygui_close(struct fb_dev*pdev){
free(pdev->buffer);
free(pdev);  
}
int zsygui_flush_buffer(struct fb_dev *pdev){
char *src,*dst;
int size=0;
int lines=0;
int offset=0;
if(!pdev){
  return -1;
}
src=pdev->buffer;
dst=pdev->addr;
size=pdev->varinfo.xres;
printf("bits_per_pixel=%d\n",pdev->varinfo.bits_per_pixel);
//这里实现一行一行的写,相当于逐行扫描
//一个像素对应几个位,由bits_per_pixel获取,除以8,得到字节数
//每次地址要偏移xres个单元
lines=pdev->varinfo.yres*((pdev->varinfo.bits_per_pixel)/8);
offset=pdev->varinfo.xres;
while(lines-->=0){
  memcpy(dst,src,size);
  src+=offset;
  dst+=offset;
}
return 0;
}
int zsygui_draw_hline(struct fb_dev*pdev,int whichline,int startpos,int endpos,int color){
int i;
char *buf;
if(!pdev){
  return -1;
}
if(startpospdev->varinfo.xres)
  startpos=0;
if(endpospdev->varinfo.xres)
  endpos=pdev->varinfo.xres;
if(whichlinepdev->varinfo.yres)
  whichline=0;
buf=pdev->buffer+whichline*pdev->varinfo.xres;
for(i=startpos;i
//测试程序
#include "zsygui.h"
int main(int argc,char **argv){
struct fb_dev *dev;
dev=zsygui_open("/dev/fb0",O_RDWR);
printf("%p\n",dev);
zsygui_fill_color(dev,0x0);
zsygui_draw_hline(dev,300,0,500,0xb0);
zsygui_draw_hline(dev,301,0,500,0xb0);
zsygui_close(dev);
return 0;
}
差不多,编译后,尽量在字符模式下编译,运行,实现了预期效果,后来我把它交叉编译后,放到ARM板上,运行也算良好。

下一次的工作就是要将jpeg格式的图片,显示出来,涉及到jpeg解码问题,当然,自己写是不太可能的,不过,我找到了一个libjpeg的解码库,这个还不错,可以直接使用,等成功了,再发上来!

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/56374/showart_2107851.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP