SmlOS三-图形处理相关功能实现
显存操作
在前面显卡相关功能进行了介绍。主要原理是找到显存地址,然后写入对应的颜色数值。
显存地址在早期处理的时候,已经存在相应的内存地址里面并保存在BOOTINFO结构体vram成员变量里,可以直接使用。
在调试的时候可以把显存全部填充成一种颜色,大概会是这样:
文字显示
文字呢,其实就是一个个小矩形里画出字体的样子。
这里文字显示采用文字矩阵为8*16的格式,并有专用文件转换成相应的中间件文件与内核文件相连接调用。
字体矩阵中包含的只是相应的点集。
指出了在8*16的矩形区域中文字需要显示的点。系统会由此判断并进行绘图。
而显示只是需要向显存写入相应点,便可以在屏幕进行显示。
这里显示了几个数字:
这里提供单个字符串绘制函数:
extern char Font[4096];
/*输出字符串*/
void PutFont_Asc(unsigned char *vram, int nXSize, int x, int y, char c,unsigned char *s)
{
for (; *s != 0x00; s++)
{
PutFont8(vram, nXSize, x, y, c, Font + *s * 16);
x += 8;
}
return;
}
调色板设置
这里的显示模式是8位色模式,调色板功能可以自定义指定颜色值的对应关系。
而在使用调色板功能之前,首先要保存EFLAGS寄存器的内容,EFLAGS寄存器主要用于提供程序状态,并进行相应控制,在设定结束后恢复该寄存器内容。
而单个颜色号的设定,有汇编指令out进行,因为C语言并没有相应指令,所以是用汇编实现,并由C语言进行调用。
_io_cli: ; void io_cli(void); ; 关闭所有可屏蔽中断
CLI
RET
_io_out8: ; void io_out8(int port, int data); ; 将8位的data输出到port端口
MOV EDX,[ESP+4] ; port
MOV AL,[ESP+8] ; data
OUT DX,AL
RET
/* 设置调色板函数 */
void set_palette(int start, int end, unsigned char *rgb)
{
int i, eflags;
eflags = io_load_eflags(); /* 保存eflags的值 */
io_cli(); /* 关闭所有可屏蔽中断 */
io_out8(0x03c8, start);
for (i = start; i <= end; i++)
{
io_out8(0x03c9, rgb[0] / 4);
io_out8(0x03c9, rgb[1] / 4);
io_out8(0x03c9, rgb[2] / 4);
rgb += 3;
}
io_store_eflags(eflags); /* 恢复eflags的值 */
return;
}
在这里由CPU向外部设备发送指定命令设定调色板功能。
而在这里设定了16号颜色,分别如下:
序号 | 颜色 |
---|---|
0 | 黑 |
1 | 亮红 |
2 | 亮绿 |
3 | 亮黄 |
4 | 亮蓝 |
5 | 亮紫 |
6 | 浅亮蓝 |
7 | 白 |
8 | 亮灰 |
9 | 暗红 |
10 | 暗绿 |
11 | 暗黄 |
12 | 暗青 |
13 | 暗紫 |
14 | 浅暗蓝 |
15 | 暗灰 |
设置调色板之后就能显示各种不同的颜色了。
鼠标及窗口显示
图形显示功能还包括鼠标的图像的初始化,鼠标图像的初始化设置与矩形的绘制类似.
准备一个鼠标图像的二维数组,采用16*16的大小,这就是鼠标的形状了。
static char cursor[16][16] =
{
"**..............",
"*O*.............",
"*OO*............",
"*OOO*...........",
"*OOOO*..........",
"*OOOOO*.........",
"*OOOOOO*........",
"*OOOOOOO*.......",
"*OOOOOOOO*......",
"*OOOOOOOOO*.....",
"*OOOO******.....",
"*OOO*...........",
"*OO*............",
"*O*.............",
"**..............",
"................"
};
并根据对应点绘制出相应的鼠标的图像,支持透明色设定功能,图层管理的相关函数可以直接调用。
而窗口默认图形的绘制,和一般图形的绘制类似。主要分成四步:第一绘制出窗体矩形,第二绘制出工作区矩形,第三绘制出窗口标题,最后绘制出关闭按钮。
前两步调用矩形的绘制函数,第三步调用字符串的显示函数。
关闭按钮的绘制与鼠标的绘制类似。
// 这个数组定义的是窗口右上角那个叉叉图形
static char closebtn[13][20] =
{
"QQQQQQQQQQQQQQQQQQQQ",
"QQQQQQQQQQQQQQQQQQQQ",
"QQQQQQQQQQQQQQQQQQQQ",
"QQQQQQ@@QQQQ@@QQQQQQ",
"QQQQQQQ@@QQ@@QQQQQQQ",
"QQQQQQQQ@@@@QQQQQQQQ",
"QQQQQQQQQ@@QQQQQQQQQ",
"QQQQQQQQ@@@@QQQQQQQQ",
"QQQQQQQ@@QQ@@QQQQQQQ",
"QQQQQQ@@QQQQ@@QQQQQQ",
"QQQQQQQQQQQQQQQQQQQQ",
"QQQQQQQQQQQQQQQQQQQQ",
"QQQQQQQQQQQQQQQQQQQQ"
};
是一个13*20的红色叉叉。
对于图层绘制字符串功能,以上只是单纯的在对应显示数组里面进行绘制操作。
但是在加入图层管理结构之后,这些操作并没有直接的写入到显存里,操作的管理由图层管理相关函数决定。
每一个窗口,就相当与photoshop里的各种图层相互重叠,有图层管理函数计算出来最终的显示的样子,写到显存中。
显示的样子大概是:
发表回复
要发表评论,您必须先登录。