歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> OpenGL超級寶典學習筆記——生成輪廓

OpenGL超級寶典學習筆記——生成輪廓

日期:2017/3/1 9:32:12   编辑:Linux編程

有時我們不需要物體的許多細節,而只需要其外圍的輪廓來描繪物體大概的形狀比如物體的陰影。

如果我們簡單的使用線框模式繪制一個立方體如下:

下面介紹OpenGL生成輪廓的兩種方式。

多邊形偏移

多邊形偏移是一個挺有用的技巧,有時會用來解決z-fighting。z-fighting在開啟深度測試時,如果兩個重疊物體的深度值非常接近,那麼就有可能會產生z-fighting(因為在繪制物體時采用插值的方式,而插值會有一定的誤差)。

如下圖

遇到這種情況,我們就可以使用多變形偏移,對一個多邊形的z值進行偏移。

多邊形偏移有三種方法,分別對應於不同的光柵化模式:GL_LINE, GL_FILL和GL_POINT.通過 glEnable傳參數GL_POLYGON_OFFSET_LINE、GL_POLYGN_OFFSET_FILL和GL_POLYGON_OFFSET_POINT來啟用。

通過glPolygonOffset(GLfloat factor, GLfloat units);如果啟用了多邊形偏移,那麼在進行深度測試之前,每個片段的深度值都會加上一個計算出來的偏移值。計算公式如下:

offset = m * factor + r * units;

其中m是多邊形的最大深度斜率(在光柵化過程中計算的),r是能夠保證產生可解析區別的窗口坐標深度值的最小值。r因OpenGL的實現而異。通過設置factor和units來調整偏移值,來達到你想要的效果。

下面是使用多邊形偏移的代碼:

//保存之前的矩陣和屬性

glPushMatrix();
glPushAttrib(GL_ALL_ATTRIB_BITS);

//往裡移動並旋轉
glTranslatef(0.0f, 0.0f, -5.0f);
glRotatef(angle, 1.0f, 1.0f, 0.0f);

//畫線框立方體,制造輪廓
glColor3f(1.0f, 0.0f, 0.0f);
//設置線的寬度為3
glLineWidth(3.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glutSolidCube(1);

//畫實心立方體
glColor3f(0.0f, 0.0f, 0.0f);
//設置多邊形偏移,往屏幕外靠近觀察點進行偏移
glPolygonOffset(-1.5, -1.0f);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glutSolidCube(1);

glPopAttrib();
glPopMatrix();

得到的效果:

使用模板緩沖區

模板緩沖區類似於深度緩沖區,圖元在繪制到顏色緩沖區前,需要先經過模板測試。首先我們可以通過繪制一個實心的立方體來創建一個模板(把模板緩沖區對應的值設置為1)。然後再繪制線框立方體,設置模板測試函數為不等於1的才通過測試,這樣就能得到一個立方體的輪廓(去除掉了中間的線,因為中間的線不能通過模板測試)。

代碼如下:

glPushMatrix();
glPushAttrib(GL_ALL_ATTRIB_BITS);

//清除模板緩沖區
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);

//一開始設置為總是通過模板測試,建立模板

glStencilFunc(GL_ALWAYS, 1, 0xFFFF);

//模板測試失敗時與模板測試通過但深度測試失敗時,模板的值保持不修改.
//通過模板測試與深度測試時,使用上面glStencilFunc指定的 ref(1)替換掉

glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glEnable( GL_STENCIL_TEST );


glTranslatef(0.0f, 0.0f, -5.0f);
glRotatef(angle, 1.0f, 1.0f, 0.0f);

//繪制實體的立方體
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glColor3f(0.0f, 0.0f, 0.0f);
glutSolidCube(1);

//設置只有模板緩沖區值不為1的,地方才通過模板測試
glStencilFunc(GL_NOTEQUAL, 1, 0xFFFF);

//繪制線框立方體
glLineWidth(3.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(1.0f, 0.0f, 0.0f);
glutSolidCube(1);

glPopAttrib();
glPopMatrix();

效果:

OpenGL超級寶典 第4版 中文版PDF+英文版+源代碼 見 http://www.linuxidc.com/Linux/2013-10/91413.htm

OpenGL編程指南(原書第7版)中文掃描版PDF 下載 http://www.linuxidc.com/Linux/2012-08/67925.htm

OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htm

Ubuntu 13.04 安裝 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htm

OpenGL三維球體數據生成與繪制【附源碼】 http://www.linuxidc.com/Linux/2013-04/83235.htm

Ubuntu下OpenGL編程基礎解析 http://www.linuxidc.com/Linux/2013-03/81675.htm

如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm

更多《OpenGL超級寶典學習筆記》相關知識 見 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581

Copyright © Linux教程網 All Rights Reserved