免费注册 查看新帖 |

Chinaunix

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

Android原生(Native)C开发之二:framebuffer篇 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-02 11:21 |只看该作者 |倒序浏览

虽然现在能通过交叉环境编译程序,并push到Android上执行,但那只是console台程序,是不是有些单调呢?下面就要看如何通过Linux的
framebuffer
技术在Android上画图形,关于Linux的framebuffer技术,这里就不再详细讲解了,请大家google一下。

操作framebuffer的主要步骤如下:
1、打开一个可用的FrameBuffer设备;
2、通过mmap调用把显卡的物理内存空间映射到用户空间;
3、更改内存空间里的像素数据并显示;
4、退出时关闭framebuffer设备。

下面的这个例子简单地用framebuffer画了一个渐变的进度条,代码 framebuf.c 如下:
#include
#include
#include
#include
#include
inline static unsigned short int make16color(unsigned char r,
unsigned char g, unsigned char b)
{
    return
(
(((r >> 3)
& 31) (((g >> 2)
& 63)  |
  ((b >> 3)
&
31)      
);
}
int main() {
    int fbfd =
0;
    struct
fb_var_screeninfo vinfo;
    struct
fb_fix_screeninfo finfo;
    long int
screensize = 0;
char *fbp = 0;
    int x = 0, y
= 0;
    int
guage_height = 20, step = 10;
    long int
location = 0;
    // Open
the file for reading and writing
    fbfd =
open("/dev/graphics/fb0", O_RDWR);
    if (!fbfd)
{
      
printf("Error: cannot open framebuffer device.\n");
      
exit(1);
    }
    printf("The
framebuffer device was opened successfully.\n");
    // Get
fixed screen information
    if
(ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
      
printf("Error reading fixed information.\n");
      
exit(2);
    }
    // Get
variable screen information
    if
(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
      
printf("Error reading variable information.\n");
      
exit(3);
    }
printf("sizeof(unsigned short) = %d\n",
sizeof(unsigned short));
   
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres,
vinfo.bits_per_pixel );
printf("xoffset:%d, yoffset:%d, line_length:
%d\n", vinfo.xoffset, vinfo.yoffset, finfo.line_length );
    // Figure
out the size of the screen in bytes
    screensize =
vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;;
    // Map
the device to memory
    fbp = (char
*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
                     
fbfd, 0);
    if
((int)fbp == -1) {
      
printf("Error: failed to map framebuffer device to
memory.\n");
      
exit(4);
    }
    printf("The
framebuffer device was mapped to memory successfully.\n");
//set to black color first
memset(fbp, 0, screensize);
    //draw
rectangle
    y =
(vinfo.yres - guage_height) / 2 -
2;      
// Where we are going to put the pixel
    for (x =
step - 2; x      
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                     
(y+vinfo.yoffset) * finfo.line_length;
      
*((unsigned short int*)(fbp + location)) = 255;
    }
    y =
(vinfo.yres + guage_height) / 2 +
2;      
// Where we are going to put the pixel
    for (x =
step - 2; x      
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                     
(y+vinfo.yoffset) * finfo.line_length;
      
*((unsigned short int*)(fbp + location)) = 255;
    }
    x = step
- 2;
    for (y =
(vinfo.yres - guage_height) / 2 - 2; y      
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                     
(y+vinfo.yoffset) * finfo.line_length;
      
*((unsigned short int*)(fbp + location)) = 255;
    }
    x =
vinfo.xres - step + 2;
    for (y =
(vinfo.yres - guage_height) / 2 - 2; y      
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                     
(y+vinfo.yoffset) * finfo.line_length;
      
*((unsigned short int*)(fbp + location)) = 255;
    }
    // Figure
out where in memory to put the pixel
    for ( x =
step; x      
for ( y = (vinfo.yres - guage_height) / 2; y           
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                     
(y+vinfo.yoffset) * finfo.line_length;
           
if ( vinfo.bits_per_pixel == 32 ) {
               
*(fbp + location) =
100;      
// Some blue
               
*(fbp + location + 1) =
15+(x-100)/2;   
// A little green
               
*(fbp + location + 2) =
200-(y-100)/5;   
// A lot of red
               
*(fbp + location + 3) =
0;     
// No transparency
           
} else { //assume 16bpp
               
unsigned char b = 255 * x / (vinfo.xres - step);
               
unsigned char g =
255;   
// (x - 100)/6 A little green
               
unsigned char r =
255;    // A lot
of red
               
unsigned short int t = make16color(r, g, b);
               
*((unsigned short int*)(fbp + location)) = t;
           
}
      
}
  //printf("x = %d, temp = %d\n",
x, temp);
      
//sleep to see it
      
usleep(200);
    }
    //clean
framebuffer
    munmap(fbp,
screensize);
   
close(fbfd);
    return
0;
}
注意,在Android环境,framebuffer设备不是象linux一样的 /dev/fb0,而是 [color="#ff0000"]/dev/graphics/fb0 [color="#000000"],
fbfd = open("/dev/graphics/fb0", O_RDWR);
打开framebuffer设备,
    fbp =
(char *)mmap(0, screensize, PROT_READ | PROT_WRITE,
MAP_SHARED,
                     
fbfd, 0);

将设备map到一块内存,然后就可以操作这块内存空间来显示你想画的图形了。
最后别忘了关闭设备:
   
munmap(fbp, screensize);
   
close(fbfd);

效果图如下:

               
               
               

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP