Android原生(Native)C(JNI/NDK)开发之二:framebuffer篇
为方便以后学习和工作,现转载一批文章,方便以后使用。
来源:http://blog.sina.com.cn/s/blog_4a0a39c30100auh9.html 作者:风子
如对Android原生(Natvie)C开发还任何疑问,请参阅《Android原生(Native)C开发之一:环境搭建篇》:http://blog.sina.com.cn/s/blog_4a0a39c30100auh9.html(或者http://android-sz.iteye.com/blog/828246)
虽然现在能通过交叉环境编译程序,并push到Android上执行,但那只是console台程序,是不是有些单调呢?下面就要看如何通过Linux的 framebuffer 技术在Android上画图形,关于Linux的framebuffer技术,这里就不再详细讲解了,请大家google一下。
操作framebuffer的主要步骤如下:
1、打开一个可用的FrameBuffer设备;
2、通过mmap调用把显卡的物理内存空间映射到用户空间;
3、更改内存空间里的像素数据并显示;
4、退出时关闭framebuffer设备。
下面的这个例子简单地用framebuffer画了一个渐变的进度条,代码 framebuf.c 如下:
C代码
- #include<unistd.h>
- #include<stdio.h>
- #include<fcntl.h>
- #include<linux/fb.h>
- #include<sys/mman.h>
- inlinestaticunsignedshortintmake16color(unsignedcharr,unsignedcharg,unsignedcharb)
- {
- return(
- (((r>>3)&31)<<11)|
- (((g>>2)&63)<<5)|
- ((b>>3)&31));
- }
- intmain(){
- intfbfd=0;
- structfb_var_screeninfovinfo;
- structfb_fix_screeninfofinfo;
- longintscreensize=0;
- char*fbp=0;
- intx=0,y=0;
- intguage_height=20,step=10;
- longintlocation=0;
- //Openthefileforreadingandwriting
- fbfd=open("/dev/graphics/fb0",O_RDWR);
- if(!fbfd){
- printf("Error:cannotopenframebufferdevice.\n");
- exit(1);
- }
- printf("Theframebufferdevicewasopenedsuccessfully.\n");
- //Getfixedscreeninformation
- if(ioctl(fbfd,FBIOGET_FSCREENINFO,&finfo)){
- printf("Errorreadingfixedinformation.\n");
- exit(2);
- }
- //Getvariablescreeninformation
- if(ioctl(fbfd,FBIOGET_VSCREENINFO,&vinfo)){
- printf("Errorreadingvariableinformation.\n");
- exit(3);
- }
- printf("sizeof(unsignedshort)=%d\n",sizeof(unsignedshort));
- 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);
- //Figureoutthesizeofthescreeninbytes
- screensize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;;
- //Mapthedevicetomemory
- fbp=(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,
- fbfd,0);
- if((int)fbp==-1){
- printf("Error:failedtomapframebufferdevicetomemory.\n");
- exit(4);
- }
- printf("Theframebufferdevicewasmappedtomemorysuccessfully.\n");
- //settoblackcolorfirst
- memset(fbp,0,screensize);
- //drawrectangle
- y=(vinfo.yres-guage_height)/2-2;//Wherewearegoingtoputthepixel
- for(x=step-2;x<vinfo.xres-step+2;x++){
- location=(x+vinfo.xoffset)*(vinfo.bits_per_pixel/8)+
- (y+vinfo.yoffset)*finfo.line_length;
- *((unsignedshortint*)(fbp+location))=255;
- }
- y=(vinfo.yres+guage_height)/2+2;//Wherewearegoingtoputthepixel
- for(x=step-2;x<vinfo.xres-step+2;x++){
- location=(x+vinfo.xoffset)*(vinfo.bits_per_pixel/8)+
- (y+vinfo.yoffset)*finfo.line_length;
- *((unsignedshortint*)(fbp+location))=255;
- }
- x=step-2;
- for(y=(vinfo.yres-guage_height)/2-2;y<(vinfo.yres+guage_height)/2+2;y++){
- location=(x+vinfo.xoffset)*(vinfo.bits_per_pixel/8)+
- (y+vinfo.yoffset)*finfo.line_length;
- *((unsignedshortint*)(fbp+location))=255;
- }
- x=vinfo.xres-step+2;
- for(y=(vinfo.yres-guage_height)/2-2;y<(vinfo.yres+guage_height)/2+2;y++){
- location=(x+vinfo.xoffset)*(vinfo.bits_per_pixel/8)+
- (y+vinfo.yoffset)*finfo.line_length;
- *((unsignedshortint*)(fbp+location))=255;
- }
- //Figureoutwhereinmemorytoputthepixel
- for(x=step;x<vinfo.xres-step;x++){
- for(y=(vinfo.yres-guage_height)/2;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;//Someblue
- *(fbp+location+1)=15+(x-100)/2;//Alittlegreen
- *(fbp+location+2)=200-(y-100)/5;//Alotofred
- *(fbp+location+3)=0;//Notransparency
- }else{//assume16bpp
- unsignedcharb=255*x/(vinfo.xres-step);
- unsignedcharg=255;//(x-100)/6Alittlegreen
- unsignedcharr=255;//Alotofred
- unsignedshortintt=make16color(r,g,b);
- *((unsignedshortint*)(fbp+location))=t;
- }
- }
- //printf("x=%d,temp=%d\n",x,temp);
- //sleeptoseeit
- usleep(200);
- }
- //cleanframebuffer
- munmap(fbp,screensize);
- close(fbfd);
- return0;
- }
注意,在Android环境,framebuffer设备不是象linux一样的 /dev/fb0,而是/dev/graphics/fb0,
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);
效果图如下:
更多相关文章
- Android简单自定义圆形和水平ProgressBar
- Android(安卓)设备+APP+号码信息
- Android设备硬件序列号(SN、串号)分析
- Android设备开机日志分析
- 转-Android原生(Native)C(JNI/NDK)开发之二:framebuffer篇
- Android内核和驱动程序
- Android外设存储设备的访问及测试
- Android: Android(安卓)Bluetooth
- Android简单自定义圆形和水平ProgressBar