转:时候犯了个霍林郭勒求

 本篇作为我学习Opengl第一篇文档。希望自己能在图形学路上走得远一点,达到能够渲染游戏画质目的,现阶段是Box2D对物理世界模拟很好,但自己无法做到材质渲染很好,致使许多效果差强人意。

         谈到,画线,相信很多游戏引擎都很好的完美支持了,只需要给出起点和终点,就能够很好的帮你实现画线问题。我们今天来分析底层是如何实现的。(ps:知识是网上视频学到,这里只是起到一个学习记录作用,顺便分享出来,没有盗取他人成果意思)。这里先做两点假设:1. 起始点x0 < x1; 2. 线段斜率0~1之间。

1.      直线方程方法

         基本思想:利用直线方程几何方程y=mx+b,确定路径上的像素点位置。

         方法:逐点增加x的值,求出对应y的值,在进行取整运算;

         主要运算:乘法+加法+取整---->这些是浮点运算


2.      DDA(Digital DifferentialAnalyzer,数字差分分析法)方法

         基本思想:y(i+1) = m(x(i+1))+b=mxi+m+b=yi+m;

         方法:就是每次都要获取前面的y值

         主要运算:加法+取整---->取整是浮点运算

         代码如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void lineDDA(int x0, int y0, int x1, int y1)  
  2. {  
  3.     /* x0 <= x1, 0 < m < 1*/  
  4.     int x;  
  5.     float m, dx, dy, y;  
  6.     dx = x1 - x0;  
  7.     dy = y1 - y0;  
  8.     m = dy / dx;  
  9.     y = y0;  
  10.       
  11.     for(x = 0; x <= x1, ++x)  
  12.     {  
  13.         int iy = (int)(y + 0.5);  
  14.         SetPixel(x, iy);        ///< 画点  
  15.         y = y + m;  
  16.     }  
  17. }  

3.      中点运算方法

           目标:消除DDA中的浮点运算。浮点取整运算,不利于硬件实现。

           直线的一般方程:F(x,y) = ax + by + c = 0; 其中 a=y0-y1=-dy;b=x1-x0=dx; c=x0y1-x1y0

         方法:根据所取点间的中点(xi+1,yi+0.5)在直线的位置

         根据中点坐标(xi+1,yi+0.5),构造方程d=F(M)=F(xi+1,yi+0.5)的值,根据d的值,判断M在线段位置:d>=0,中点M在线段上方,取E, d<0, 中点在线段下方,取NE, 如图所示:


          如何判断下一个像素呢

         如果当前像素点(x+1, y+0.5)的d值,参考上面计算:

         1).d>=0, 则取像素点E,那么下一个像素点的d值为:

         d=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c=d+a;----->明显可以看到d的增量为a;

         2).d<0, 则取像素点NE,那么下一个像素点的d值为:

         d=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c=d+a+b,------>明显d的增量为a+b;  

        

         既然d的增量公式知道了,下面就是要知道d的初始值。根据构造方程d0=F(x0+1,y0+0.5)=F(x0,y0)+a+0.5b=a+0.5b; 在这里d0的运算结果有存在个0.5,即除法运算,也就是浮点运算,由于我们并不需要d的值,关系的是d与0的大小关系,因此,两边同时乘以2,消除浮点运算。

         OK,至此我们可以得到下面的递推关系:

        

        

         那么,最终结果就是如下所示:

        

         主要运算:加法-->没有浮点运算

         代码如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void lineMidPoint(int x0, int y0, int x1, int y1)  
  2. {  
  3.     /* x0 <= x1, 0 < m < 1*/  
  4.     int a, b, d1, d2, d, x, y;  
  5.     a = y0 - y1;  
  6.     b = x1 - x0;  
  7.     d = a + a + b;  
  8.     d1 = a + a;  
  9.     d2 = (a+b) + (a+b);  
  10.     x = x0;  
  11.     y = y0;  
  12.     SetPixel(x,y);              ///< 画点  
  13.     while(x < x1)  
  14.     {  
  15.         if(d<0)  
  16.         {  
  17.             ++y;  
  18.             d += d2;  
  19.         }  
  20.         else  
  21.         d += d1;  
  22.         x++;  
  23.         SetPixel(x,y);              ///< 画点  
  24.     }  
  25. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值