Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1152660
  • 博文数量: 222
  • 博客积分: 5262
  • 博客等级: 大校
  • 技术积分: 3028
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-22 19:10
文章分类

全部博文(222)

文章存档

2012年(2)

2011年(192)

2010年(28)

分类: 嵌入式

2010-12-29 14:53:56

Linux | FreeBSD | OpenBSD | NetBSD | BSDI | AIX | Solaris/SunOS | Tru64 | HP-UX | IRIX | Minux | SCO Unix | Mac OS X

声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
framebuffer绘图时候的颜色问题,LCD为tft 16bpp的,rgb565的。
Subject: framebuffer绘图时候的颜色问题,LCD为tft 16bpp的,rgb565的。
      我用framebuffer写了一个简单的绘图程序,但是现在颜色有问题,不知道是不是我draw_point函数里面的颜色那块写错了。我的LCD屏幕 是 tft 16bpp的rgb 为565, 处理器为3sc2410,LCD控制器为3sc2410集成的。请问draw_point是不是有问题。颜色怎么样才能搞定?谢谢!!!

#include
#include
#include
#include
#include
#include

static int fp = 0;
static uint bits_per_pixel;
static uint line_length;
static char * fbp;
static long screensize=0;
static int xres = 0;
static int yres = 0;
void draw_point(int x,int y,int color)
{
int location = x * (bits_per_pixel / 8) + y * line_length;
*(fbp + location) = (color >> (0+3)) &0x1f; /* 蓝色的色深 */ /*直接赋值来改变屏幕上某点的颜色*/
*(fbp + location + 1) = (color >> (8+2)) & 0x3f; /* 绿色的色深*/
*(fbp + location + 2) = (color >> (16+3)) & 0x1f; /* 红色的色深*/
*(fbp + location + 3) = (color >> 24) & 0xff; /* 是否透明 */
}

int get_pixel(int x, int y)
{
int location = x * (bits_per_pixel / 8) + y * line_length;
return ((*(fbp + location))&0xff ) || ( (*(fbp + location + 1))&0xff00 ) || ( ( *(fbp + location + 2))&0xff0000) || (( *(fbp + location + 3))&0xff000000);

}


void draw_hLine(int x0, int y0, int x1,int color)
{
for(x0; x0 <= x1; x0++ )
{
draw_point(x0,y0,color);
}

}
void draw_vLine(int x0, int y0, int y1, int color)
{
for(y0; y0 <= y1; y0++ )
{
draw_point(x0,y0,color);
}

}

void draw_line(int x1,int y1,int x2,int y2,int color)
{
int dx,dy,e;
dx=x2-x1;
dy=y2-y1;

if(dx>=0)
{
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 1/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
draw_point(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else // 2/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
draw_point(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)

if(dx>=dy) // 8/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
draw_point(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else // 7/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
draw_point(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
else //dx<0
{
dx=-dx; //dx=abs(dx)
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 4/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
draw_point(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 3/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
draw_point(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)

if(dx>=dy) // 5/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
draw_point(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 6/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
draw_point(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
}

void draw_rectangle(int x1,int y1,int x2,int y2,int color)
{
draw_line(x1,y1,x2,y1,color);
draw_line(x2,y1,x2,y2,color);
draw_line(x1,y2,x2,y2,color);
draw_line(x1,y1,x1,y2,color);
}

/**************************************************************
在LCD屏幕上用颜色填充一个矩形
**************************************************************/
void fill_rectangle(int x1,int y1,int x2,int y2,int color)
{
int i;

for(i=y1;i<=y2;i++)
draw_line(x1,i,x2,i,color);
}


int fb_init()
{
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else on
ly length is significant */
struct fb_bitfield blue;
fp = open ("/dev/fb/0",O_RDWR);
if (fp < 0){
printf("%s ",strerror(errno));
printf("Error : Can not open framebuffer device ");
exit(1);
}
if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
printf("Error reading fixed information ");
exit(2);
}
if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
printf("Error reading variable information ");
exit(3);
}
bits_per_pixel = vinfo.bits_per_pixel;
line_length = finfo.line_length;
xres = vinfo.xres;
yres = vinfo.yres;
screensize = xres * yres * bits_per_pixel / 8;
red = vinfo.red;
green = vinfo.green;
blue = vinfo.blue;
printf("the visual type is %d ",finfo.visual); //if 2 that is FB_VISUAL_TRUECOLOR

printf("red.length is %d,offset is %d; green.length is %d,offset is %d; blue.length is %d, offset is %d",red.length,red.offset,green.length,green.offset,blue.length,blue.offset);

// printf("red.length is %d,offset is %d",red.length,red.offset);
/*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来,得到一个指向这块空间的指针*/
fbp =(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
if ((int) fbp == -1)
{
printf ("Error: failed to map framebuffer device to memory. ");
exit (4);
}

return 0;
}
void fb_close()
{
munmap(fbp,screensize); /*解除映射*/
close(fp); /*关闭文件*/
}
/*
int main () {
int x = 0 ; int y = 0;
fb_init();

for(; x <= xres; ++x)
{
for(y = 0; y <= x; ++y)
{
draw_point(x,y,0x0000ff);
}
}
draw_line(0,250,200,315,0x567896);

fill_rectangle(100,100,230,300,0x567896);
fb_close();
return 0;
}
*/
Subject: Re: framebuffer绘图时候的颜色问题,LCD为tft 16bpp的,rgb565的。
      fb 内存中当为5-6-5颜色模式(16bit)时每一点对应各颜色分量总和为1个16位整数(占2个字节)


/*
color 为1个32位整数 little[R:G:B:A]=8:8:8:8 big[A:B:G:R]=8:8:8:8
想用逐个byte分析的话注意 color 在不同 endian 下的构成
以下 unsigned short 为16位整数(32bit机器), 64bit机器可能有所区别
*/
void draw_point(int x,int y,int color) /* RGB16 [R:G:B=5:6:5] */
{
if(x < 0 || x >= xres || y < 0 || y >= yres) return;
unsigned short *addr = ((unsigned short*)fbp) + y * xres + x;
*addr = (((color & 0xff) >> 3) << 11) | /* 红色 */
((((color >> 8) & 0xff) >> 2) << 5) | /* 绿色 */
(((color >> 16) & 0xff) >> 3); /* 蓝色 */
/* A 分量你自己解决 */
}

/* 以下这段取自为 SkyEye 写的 LCD 仿真 */
int get_pixel(int x, int y) /* RGB16 [R:G:B=5:6:5] */
{
if(x < 0 || x >= xres || y < 0 || y >= yres) return 0;
unsigned int c = (unsigned int)*(((unsigned short*)fbp) + y * xres + x);
return ((((c & 0xf800) >> 8) | 0x0007) | /* 红色 */
((((c & 0x07e0) >> 3) | 0x0003) << 8) | /* 绿色 */
((((c & 0x001f) << 3) | 0x0007) << 16) | /* 蓝色 */
0xff000000);
}



另外,你的fbp映射有问题,应该是
#include
....
fbp =(char *)mmap(0, finfo.smem_len + (finfo.smem_start & (~PAGE_MASK)),
PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
而且真正起址为 fbp + (finfo.smem_start & (~PAGE_MASK))
Subject: Re: framebuffer绘图时候的颜色问题,LCD为tft 16bpp的,rgb565的。
      太感谢这位anthonylee大仙了。还有你摘录的那段skyeye里面的代码。现在我的颜色也搞定了。非常非常的感谢啊。感谢所有的大仙,还有skyeye等等。
Copyright © 2007~2009 UNIX Resources Network, All Rights Reserved. About URN | Privacy & Legal | Help | Contact us
阅读(2521) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~