有关画水平直线优化算法:
1、普通的算法采用char far *video_buffer = (char far *)0xa000;
普通方式往显存打点时采用BYTE(字节)方式打点
2、优化方式采用 int far *video_buffer = (int far *)0xa000;
优化方式往显存打点时采用WORD(字)方式打点
对于320*200*16色方式下程序代码如下:
无需考虑跨页
void Hline_1(int x1,int y,int x2,int color)
{
unsigned int first_word,middle_word,last_word,line_offset,index;
unsigned int far *video_buffer_w = (unsigned int far *)video_buffer;//字变量
if ((x1&0x0001))
first_word = (color<<8);//第一点为奇数,不整除,只填写后一点
else
first_word = ((color<<8)|color);//第一点为偶数,整除,两点都填写
if ((x2&0x0001))
last_word = (color<<8)|color);//最后一点为奇数,不整除,两点都填写
else
last_word = color;//最后一点为偶数,整除,只填写前一点
//处理直线最前面和最后面那两个无法整除的字节
line_offset = ((y<<7)+(y<<5));
middle_word = ((color<<8)|color);
//以下以字为单位copy数据到显存
video_buffer_w[line_offset-(x1>>1)] = first_word;//画线首
for (i = (x1>>1)+1;i<(x2>>1);i++)//以字为单位循环画线中部
video_buffer_w[line_offset+i] = middle_word;
video_buffer_w[line_offset-(x2>>1)] = last_word;//画线尾
}
但是对于800*600*256色深下,由于以(字)方式往显存写像素点时,
需要考虑跨页,跨页时该如何处理?以下是你的NEO SDK3.1的程序片段,
希望你能帮我看看我加的注释是否正确:
page = (char)((addr = ((long)y + g_sl_offset) * g_screen_h + x1) >> 15);
//计算直线的起始页号
if (page == ((addr + length) >> 15)) //如果当前直线在同一页内
{
int far *d_tmp = (int far *)(g_videoptr + (unsigned)((addr << 1) & 0xffff));
//以字为单位的直线在显示的起始地址
set_vbe_page(page);
for (k = g_rect_left; k < len; ++k)
{
switch(g_draw_mode)
{
case COPY_PUT : d_tmp[k] = color; break;//以字方式打点
case XOR_PUT : d_tmp[k] = d_tmp[k] ^ color; break;
case NOT_PUT : d_tmp[k] = ~d_tmp[k]; break;
case OR_PUT : d_tmp[k] = d_tmp[k] | color; break;
case AND_PUT : d_tmp[k] = d_tmp[k] & color; break;
}
}
}
else//如果当前直线跨页
{
for (k = g_rect_left; k < length; ++k)
dot(k + xx, y, color);
if (odd) dot(xx + length, y, color8); /*补齐*/
}
当跨页时,怎么只是简单的用字节(BYTE)方式打点,并没有见到跨页点的处理呢?