编程论坛's Archiver

ba_wang_mao 发表于 2007-10-30 14:50

请问:一笔苍穹 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&amp;0x0001))<BR>        first_word = (color&lt;&lt;8);//第一点为奇数,不整除,只填写后一点<BR>    else<BR>        first_word = ((color&lt;&lt;8)|color);//第一点为偶数,整除,两点都填写<BR>    if ((x2&amp;0x0001))<BR>        last_word = (color&lt;&lt;8)|color);//最后一点为奇数,不整除,两点都填写<BR>    else<BR>        last_word = color;//最后一点为偶数,整除,只填写前一点<BR>    //处理直线最前面和最后面那两个无法整除的字节<BR>    line_offset = ((y&lt;&lt;7)+(y&lt;&lt;5));<BR>    middle_word = ((color&lt;&lt;8)|color);<BR>    //以下以字为单位copy数据到显存<BR>    video_buffer_w[line_offset-(x1&gt;&gt;1)] = first_word;//画线首<BR>    for (i = (x1&gt;&gt;1)+1;i&lt;(x2&gt;&gt;1);i++)//以字为单位循环画线中部<BR>        video_buffer_w[line_offset+i] = middle_word;<BR>    video_buffer_w[line_offset-(x2&gt;&gt;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) &gt;&gt; 15);<BR>//计算直线的起始页号<BR>if (page == ((addr + length) &gt;&gt; 15)) //如果当前直线在同一页内<BR>{<BR> int far *d_tmp = (int far *)(g_videoptr + (unsigned)((addr &lt;&lt; 1) &amp; 0xffff));<BR>//以字为单位的直线在显示的起始地址<BR></FONT><FONT color=#000000>  set_vbe_page(page);<BR>  for (k = g_rect_left; k &lt; 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] &amp; color; break;<BR>        }<BR>   }<BR> }<BR> else//如果当前直线跨页<BR> {<BR>      for (k = g_rect_left; k &lt; 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>

一笔苍穹 发表于 2007-10-30 15:18

呵呵,当时偷了个懒,发生跨页后就从跨页处开始直接调用dot()直到结束[em04]<BR>其实可以单独处理了跨页后再使用int *进行优化画线。<BR>其实还可以用datamove画线,更加优化。也要处理跨页

ba_wang_mao 发表于 2007-10-30 16:00

是否需要考虑如下几种情况:<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>

eakcon 发表于 2007-11-14 10:06

太有味了<BR>

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.