`
yinter
  • 浏览: 243992 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Android原生(Native)C开发之二 framebuffer篇

阅读更多
虽然现在能通过交叉环境编译程序,并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);

效果图如下:

  • 大小: 11.9 KB
分享到:
评论
1 楼 yingjianxuehun 2015-06-25  
在android4.4上fb0总是打不开,已经root,权限也没问题,4.2一下正常,可能是什么原因呢?

相关推荐

    Android 3D游戏开发技术详解与典型案例 书后案例实战源码

    Android Native Development Kit (NDK)允许开发者在Android应用中集成原生代码,提高性能,尤其是对于计算密集型的3D渲染。 3. **3D模型和场景**: 游戏中的3D模型是通过建模软件(如Blender或Maya)创建的,包含...

    android native 显示yuv 420数据

    在Android平台上,显示YUV 420格式的数据通常涉及到Android的原生层(Native Layer)编程,这通常与硬件加速的图形处理有关,比如OpenGL ES。YUV是一种常见的视频和图像编码格式,广泛用于节省存储空间和带宽。420是...

    Android常用设备驱动

    - **NDK编程**:Native Development Kit,允许开发者直接使用C或C++语言开发Android应用或驱动程序,适用于对性能有较高要求的场景。 #### 四、设备驱动调试与优化 1. **调试工具**: - **GDB**:GNU调试器,...

    Android-ScreenShot-Library

    这可能是一个包含C或C++原生代码的目录,用于处理framebuffer的低级操作,这部分代码通常会更接近硬件,效率更高。在Android中,原生代码可以利用NDK(Native Development Kit)编译并链接到Java层,实现跨语言的...

    安卓读取FB

    2. **创建JNI接口**:由于Java层无法直接操作Framebuffer,我们需要编写C/C++代码,并通过JNI(Java Native Interface)与之交互。JNI允许Java代码调用原生C/C++函数,反之亦然。 3. **读取Framebuffer**:在原生...

    Android下基于UVC的UsbCam的源码

    在Android中,尽管原生支持相对较弱,但可以通过JNI(Java Native Interface)调用C/C++库来利用V4L2接口。 3. **FFmpeg**:FFmpeg是一个开源的多媒体处理工具集,包含了编解码器、转换工具以及各种处理音频和视频...

    Android平台下能够截动态屏幕的底层库实现

    在Android平台上,截取动态屏幕是...开发者需要具备扎实的C/C++基础,对Android系统有深入理解,并且熟悉NDK开发流程。通过这样的底层库,开发者可以创建出能够捕捉动态屏幕的应用,为测试、调试或者特殊需求提供便利。

    Android 屏幕颜色的变换源码.rar

    在Android系统中,屏幕颜色的变换涉及到多个层次的技术...这个压缩包中的源代码可能涵盖了这些层面的实现,深入研究可以帮助我们更好地理解Android系统的色彩管理机制,对于开发高性能、色彩准确的应用程序非常有帮助。

    android opengles2.0 jni

    JNI(Java Native Interface)则允许Java代码调用C/C++原生代码,为高性能计算和图形处理提供可能。在Android应用开发中,结合OpenGL ES 2.0和JNI,开发者可以实现更复杂、性能更强的图形特效,例如“水波纹效果”。...

    PowerVR.Supported+Extensions.OpenGL+ES.EGL.pdf

    - **EGL_ANDROID_image_native_buffer**:允许EGL将原生缓冲区(如Android的ANativeWindowBuffer)用作图像。 - **EGL_ANDROID_native_fence_sync**:提供了与Android硬件同步框架集成的同步机制。 - **EGL_...

Global site tag (gtag.js) - Google Analytics