请问:一笔苍穹 NEO SDK 有关画水平直线优化算法:char hline(int x1, int y, int
<P>有关画水平直线优化算法:<BR>1、普通的算法采用char far *video_buffer = (char far *)0xa000;<BR> 普通方式往显存打点时采用BYTE(字节)方式打点<BR>2、优化方式采用 int far *video_buffer = (int far *)0xa000;<BR> 优化方式往显存打点时采用WORD(字)方式打点<BR><BR><STRONG><FONT color=#0000ff>对于320*200*16色方式下程序代码如下:<BR></FONT><FONT color=#0033ff>无需考虑跨页</FONT></STRONG><BR>void Hline_1(int x1,int y,int x2,int color)<BR>{<BR> unsigned int first_word,middle_word,last_word,line_offset,index;<BR> unsigned int far *video_buffer_w = (unsigned int far *)video_buffer;//字变量</P><P> if ((x1&0x0001))<BR> first_word = (color<<8);//第一点为奇数,不整除,只填写后一点<BR> else<BR> first_word = ((color<<8)|color);//第一点为偶数,整除,两点都填写<BR> if ((x2&0x0001))<BR> last_word = (color<<8)|color);//最后一点为奇数,不整除,两点都填写<BR> else<BR> last_word = color;//最后一点为偶数,整除,只填写前一点<BR> //处理直线最前面和最后面那两个无法整除的字节<BR> line_offset = ((y<<7)+(y<<5));<BR> middle_word = ((color<<8)|color);<BR> //以下以字为单位copy数据到显存<BR> video_buffer_w[line_offset-(x1>>1)] = first_word;//画线首<BR> for (i = (x1>>1)+1;i<(x2>>1);i++)//以字为单位循环画线中部<BR> video_buffer_w[line_offset+i] = middle_word;<BR> video_buffer_w[line_offset-(x2>>1)] = last_word;//画线尾<BR>}<BR><BR><FONT color=#f70909><STRONG>但是对于800*600*256色深下,由于以(字)方式往显存写像素点时,<BR></STRONG></FONT><STRONG><FONT color=#ee3d11>需要考虑跨页,跨页时该如何处理?以下是你的NEO SDK3.1的程序片段,<BR></FONT><FONT color=#ff00ff>希望你能帮我看看我加的注释是否正确:</FONT></STRONG><BR><FONT color=#000000>page = (char)((addr = ((long)y + g_sl_offset) * g_screen_h + x1) >> 15);<BR>//计算直线的起始页号<BR>if (page == ((addr + length) >> 15)) //如果当前直线在同一页内<BR>{<BR> int far *d_tmp = (int far *)(g_videoptr + (unsigned)((addr << 1) & 0xffff));<BR>//以字为单位的直线在显示的起始地址<BR></FONT><FONT color=#000000> set_vbe_page(page);<BR> for (k = g_rect_left; k < len; ++k)<BR> {<BR> switch(g_draw_mode)<BR> {<BR> case COPY_PUT : d_tmp[k] = color; break;//以字方式打点<BR> case XOR_PUT : d_tmp[k] = d_tmp[k] ^ color; break;<BR> case NOT_PUT : d_tmp[k] = ~d_tmp[k]; break;<BR> case OR_PUT : d_tmp[k] = d_tmp[k] | color; break;<BR> case AND_PUT : d_tmp[k] = d_tmp[k] & color; break;<BR> }<BR> }<BR> }<BR> else//如果当前直线跨页<BR> {<BR> for (k = g_rect_left; k < length; ++k)<BR> dot(k + xx, y, color);<BR> if (odd) dot(xx + length, y, color8); /*补齐*/<BR> }<BR> </FONT><FONT color=#ff3300><STRONG>当跨页时,怎么只是简单的用字节(BYTE)方式打点,并没有见到跨页点的处理呢?</STRONG></FONT></P> 呵呵,当时偷了个懒,发生跨页后就从跨页处开始直接调用dot()直到结束[em04]<BR>其实可以单独处理了跨页后再使用int *进行优化画线。<BR>其实还可以用datamove画线,更加优化。也要处理跨页 是否需要考虑如下几种情况:<BR> 1、当不跨页时<BR> a.水平线第一点为奇数(或者偶数)<BR> b.水平线最后一点为奇数(或者偶数)<BR> 2、当跨页时<BR> a.第一页水平线第一点奇数(或者偶数)<BR> b.第一页水平线最后一点为奇数(或者偶数)<BR> c.第二页水平线第一点为奇数(或者偶数)<BR> d.第二页水平线最后一点为奇数(或者偶数)<BR><BR><STRONG><FONT color=#ff0000>当第一点为奇数,只填写后一点<BR>当第一点为偶数,两点都填写<BR>当最后一点为奇数,两点都填写<BR>当最后一点为奇数,只填写前一点</FONT></STRONG> 太有味了<BR>
页:
[1]
