SmlOS三-图形处理相关功能实现

  • 内容
  • 评论
  • 相关

显存操作

在前面显卡相关功能进行了介绍。主要原理是找到显存地址,然后写入对应的颜色数值。

显存地址在早期处理的时候,已经存在相应的内存地址里面并保存在BOOTINFO结构体vram成员变量里,可以直接使用。

在调试的时候可以把显存全部填充成一种颜色,大概会是这样:

image


文字显示

文字呢,其实就是一个个小矩形里画出字体的样子。

这里文字显示采用文字矩阵为8*16的格式,并有专用文件转换成相应的中间件文件与内核文件相连接调用。

字体矩阵中包含的只是相应的点集。

指出了在8*16的矩形区域中文字需要显示的点。系统会由此判断并进行绘图。

而显示只是需要向显存写入相应点,便可以在屏幕进行显示。

这里显示了几个数字:

image

这里提供单个字符串绘制函数:

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里的各种图层相互重叠,有图层管理函数计算出来最终的显示的样子,写到显存中。

显示的样子大概是:

image