一、基本概念
framebuffer: 帧缓存、帧缓存(显示设备)
Linux内核为显示提供的一套应用程序接口。(驱动内核支持)
分辨率:
像素点
显示屏:800 * 600(横向有800个像素点,纵向有600个像素点)
显卡(显存(保存像素点的值))
RGB
888(8个bitR,8个bit G,8个bit B)
PC ,4412(RGB888)
RGB565(S3C2440)
为了提高代码的书写效率(将RGB扩充到4字节)
二、解决显存空间不能直接被用户访问
根据显存的大小的多少,来申请空间
1、打开显示设备(/dev/fb0)
2、获取显示设备相关参数(分辨率、位深度......)
3、建立内存映射
4、写入RGB颜色值
5、解除映射
6、关闭显示设备
三、framebuffer常问话术
framebuff(是什么,具体原理、怎么做、)
是什么:Linux内核为显示提供的一套应用程序接口。(驱动内核支持)
具体原理:通过内存映射技术向显存空间写入RGB值
1、打开显示设备(/dev/fb0)
2、获取显示设备相关参数(分辨率、位深度......)
3、建立内存映射
4、写入RGB颜色值
5、解除映射
6、关闭显示设备
四、常见画图操作
1、画一个点
void draw_point(int x,int y,unsigned int col)
{
if(x >= vinf.xres || y>= vinf.yres)
{
return;
}
if(vinf.bits_per_pixel == RGB888_FMT)
{
unsigned int *p = pmem;
*(p + y * vinf.xres_virtual + x) = col;
}
else if(vinf.bits_per_pixel == RGB565_FMT)
{
unsigned short *p = pmem;
*(p + y * vinf.xres_virtual + x) = col;
}
}
2、画一条竖线,横线,斜线
void draw_line(int x0,int y0,int x1,int y1,unsigned int col)
{
if(x0 >= vinf.xres|| y0 >= vinf.yres|| x1 >= vinf.xres || y1 >= vinf.yres)
{
return;
}
if(vinf.bits_per_pixel == RGB888_FMT)
{
int xmax = x0 > x1 ? x0 : x1;
int xmin = x0 < x1 ? x0 : x1;
if(x0 == x1)
{
int ymax = y0 > y1 ? y0 : y1;
int ymin = y0 < y1 ? y0 : y1;
for(int y = ymin;y < ymax;++y)
{
draw_point(x0,y,col);
}
}
else if(y0 == y1)
{
for(int x = xmin;x < xmax;++x)
{
draw_point(x,y0,col);
}
}
else
{
for(int x = xmin;x < xmax;++x)
{
int y = (y1 - y0)/(x1 - x0) * (x - x0) + y0;
draw_point(x,y,col);
}
}
}
}
3、画一个圆
void draw_circle(int x,int y,int r,unsigned int col)
{
int xc = 0;
int yc = r;
int p = 3 - 2 * r;
while(xc <= yc)
{
draw_point(x + xc ,y+yc,col);
draw_point(x - xc ,y+yc,col);
draw_point(x + xc ,y-yc,col);
draw_point(x - xc ,y-yc,col);
draw_point(x + yc ,y+xc,col);
draw_point(x - yc ,y-xc,col);
draw_point(x + yc ,y-xc,col);
draw_point(x - yc ,y-xc,col);
xc++;
if(p < 0)
{
p += 4 *xc + 6;
}
else
{
yc--;
p += 4 *(xc - yc) + 10;
}
}
}
4、画一个矩形
void draw_rectangle(int x,int y,int x0,int y0,unsigned int col)
{
if(x >= vinf.xres || y>= vinf.yres)
{
return;
}
for(int i = x;i <= x0;++i)
{
draw_point(i,y,col);
}
for(int i = x;i <= x0;++i)
{
draw_point(i,y0,col);
}
for(int i = y;i <= y0;++i)
{
draw_point(x,i,col);
}
for(int i = y;i < y0;++i)
{
draw_point(x0,i,col);
}
}
5、清屏
void clear_watch(unsigned int col)
{
int i = 0;
int j = 0;
for(i = 0;i < vinf.xres;++i)
{
for(j = 0;j < vinf.yres;++j)
{
draw_point(i,j,col);
}
}
}