http://blog.csdn.net/neiloid/article/details/6998644

如对Android原生(Natvie)C开发还任何疑问,请参阅《Android原生(Native)C开发之一:环境搭建篇》:http://blog.sina.com.cn/s/blog_4a0a39c30100auh9.html

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

操作framebuffer的主要步骤如下:

1、打开一个可用的FrameBuffer设备;
2、通过mmap调用把显卡的物理内存空间映射到用户空间;
3、更改内存空间里的像素数据并显示;

4、退出时关闭framebuffer设备。

下面的这个例子简单地用framebuffer画了一个渐变的进度条,代码 framebuf.c 如下:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

inline static unsigned short int make16color(unsigned char r, unsigned char g, unsigned char b)
{
return (
(((r >> 3) & 31) << 11) |
(((g >> 2) & 63) << 5) |
((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 < vinfo.xres - 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 < vinfo.xres - 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 < (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 < (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 < 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; // 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,而是/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);

framebuffer (2)_第1张图片

更多相关文章

  1. android NDK 开发环境配置
  2. 使用NetBeans搭建Android开发环境
  3. 第一章 andriod studio 安装与环境搭建
  4. Android——开发环境
  5. Android之adb环境变量配置
  6. android 目录结构,adb环境变量配置

随机推荐

  1. context、getApplicationContext()
  2. Android仿微信SwitchButton
  3. Android音频系统之AudioFlinger(二)
  4. Android动态全屏与退出全屏
  5. Android-代替GLSurfaceView的GLTextureVi
  6. Android(安卓)原代码编后的目录分析
  7. android RecyclerView局部刷新
  8. Github中的Android时间,日期选择器
  9. Android(安卓)cookies正确的更新方式
  10. Android(安卓)知识点总结 (二) view绘制流