OpenGL1.0 線段

OpenGL1.0線段

DionysosLai2014-06-16

         本篇作爲我學習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值

         主要運算:加法+取整---->取整是浮點運算

         代碼如下:

void lineDDA(int x0, int y0, int x1, int y1)
{
	/* x0 <= x1, 0 < m < 1*/
	int x;
	float m, dx, dy, y;
	dx = x1 - x0;
	dy = y1 - y0;
	m = dy / dx;
	y = y0;
	
	for(x = 0; x <= x1, ++x)
	{
		int iy = (int)(y + 0.5);
		SetPixel(x, iy);		///< 畫點
		y = y + m;
	}
}

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,至此我們可以得到下面的遞推關係:

        

        

         那麼,最終結果就是如下所示:

        

         主要運算:加法-->沒有浮點運算

         代碼如下:

void lineMidPoint(int x0, int y0, int x1, int y1)
{
	/* x0 <= x1, 0 < m < 1*/
	int a, b, d1, d2, d, x, y;
	a = y0 - y1;
	b = x1 - x0;
	d = a + a + b;
	d1 = a + a;
	d2 = (a+b) + (a+b);
	x = x0;
	y = y0;
	SetPixel(x,y);				///< 畫點
	while(x < x1)
	{
		if(d<0)
		{
			++y;
			d += d2;
		}
		else
		d += d1;
		x++;
		SetPixel(x,y);				///< 畫點
	}
}

              Ok,這就是我今天所學的。快一點了,該睡覺。明天生活更美好。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章