亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Win32 OpenGL編程(13) 隱藏表面消除(深度測(cè)試

系統(tǒng) 1748 0

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

討論新聞組及文件

隱藏表面消除(深度測(cè)試)

其實(shí)這是個(gè)滯后的話(huà)題了,事實(shí)上應(yīng)該在光照一節(jié)就應(yīng)該詳述的,但是因?yàn)楣庹盏膬?nèi)容本來(lái)就多,所以當(dāng)時(shí)并沒(méi)有再牽涉此內(nèi)容。

在我們填充三維物體時(shí),與平面繪制不同,因?yàn)闋可娴搅饲懊嫖矬w遮擋后面物體的問(wèn)題,假如沒(méi)有一個(gè)很好的內(nèi)置機(jī)制,我們就只能通過(guò)程序記住每個(gè)物體的Z軸(其實(shí)也不一定是Z軸,看當(dāng)時(shí)的觀(guān)察方向),然后按順序?qū)⑦h(yuǎn)的物體先繪制,然后再繪制離我們近的,通過(guò)這種方式,可以讓離我們近的物體繪制在后面,覆蓋掉遠(yuǎn)的物體。

當(dāng)然,假如覺(jué)得不麻煩的話(huà),這樣做倒也不是不行,但是假如這些事情是由硬件實(shí)現(xiàn)的話(huà),效率可是會(huì)上一個(gè)層次的,所以O(shè)penGL也提供了此方法,被稱(chēng)作深度測(cè)試。(Depth Test)使用方法那是相當(dāng)簡(jiǎn)單,僅僅需要通過(guò)glEnable啟用就可以了,我們現(xiàn)在看看使用前后的區(qū)別。

我們通過(guò)以下函數(shù)繪制一大一小兩個(gè)球

    
      void 
    
    
      DrawBigRedSphere
    
    
()
{
    
    
      GLfloat mat_specular
    
    
[] = { 1.0, 0.0, 0.0, 1.0 };
    
    
      GLfloat mat_shininess
    
    
[] = { 50.0 };
    
    
      GLfloat mat_ambient
    
    
[] = { 1.0, 0.0, 0.0, 1.0 };
    
    
      GLfloat mat_diffuse
    
    
[] = { 1.0, 0.0, 0.0, 1.0 };

    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_SPECULAR
    
    
, 
    
      mat_specular
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_SHININESS
    
    
, 
    
      mat_shininess
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_AMBIENT
    
    
, 
    
      mat_ambient
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_DIFFUSE
    
    
, 
    
      mat_diffuse
    
    
);

    
    
      glutSolidSphere
    
    
(0.5, 32, 32);
}


    
      void 
    
    
      DrawSmallBlueSphere
    
    
()
{
    
    
      GLfloat mat_specular
    
    
[] = { 0.0, 0.0, 1.0, 1.0 };
    
    
      GLfloat mat_shininess
    
    
[] = { 50.0 };
    
    
      GLfloat mat_ambient
    
    
[] = { 0.0, 0.0, 1.0, 1.0 };
    
    
      GLfloat mat_diffuse
    
    
[] = { 0.0, 0.0, 1.0, 1.0 };

    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_SPECULAR
    
    
, 
    
      mat_specular
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_SHININESS
    
    
, 
    
      mat_shininess
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_AMBIENT
    
    
, 
    
      mat_ambient
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_DIFFUSE
    
    
, 
    
      mat_diffuse
    
    
);

    
    
      glutSolidSphere
    
    
(0.3, 32, 32);
}
  

DrawBigRedSphere繪制的是大的紅球,DrawSmallBlueSphere繪制的是小的藍(lán)球,繪制的時(shí)候都采用默認(rèn)坐標(biāo),即繪制在屏幕的中央,并且Z軸也不動(dòng),那么,從理論上來(lái)講,大球會(huì)包含小球,小球就被大球遮掩了,我們顯示要的應(yīng)該也是這種效果。

看一下未開(kāi)啟深度測(cè)試情況下的情況我們先繪制大球,再繪制小球的和用相反順序再繪制的情形:

代碼如下:

    
      void 
    
    
      SceneShow
    
    
(
    
      GLvoid
    
    
)        
{
    
    
      glClear
    
    
(
    
      GL_COLOR_BUFFER_BIT 
    
    
| 
    
      GL_DEPTH_BUFFER_BIT
    
    
);    

    
    
      glPushMatrix
    
    
();
    
    
      glTranslatef
    
    
(-0.5, 0.0, 0.0);
    
    
      DrawBigRedSphere
    
    
();
    
    
      DrawSmallBlueSphere
    
    
();
    
    
      glPopMatrix
    
    
();

    
    
      glPushMatrix
    
    
();
    
    
      glTranslatef
    
    
(0.5, 0.0, 0.0);
    
    
      DrawSmallBlueSphere
    
    
();
    
    
      DrawBigRedSphere
    
    
();
    
    
      glPopMatrix
    
    
();

    
    
      glFlush
    
    
();
}  
  

image

我們會(huì)觀(guān)察到很明顯的繪制順序?qū)е碌膯?wèn)題,左邊的圖因?yàn)橄壤L制大球再繪制小球,小的籃球竟然覆蓋掉了應(yīng)該在其外部的紅球。實(shí)際使用中,我們可以都自己判斷,然后用右邊的正確繪制方式,隨著圖形的增多,會(huì)增加一定的計(jì)算量,OpenGL提供的深度測(cè)試就是為我們提供了更簡(jiǎn)便高效的方式,事實(shí)上,由于OpenGL使用的方式因?yàn)榭梢栽跍y(cè)試后,直接繪制出最終圖形而忽略繪制被覆蓋掉的圖形,效率上比覆蓋繪制會(huì)更高一些(需要硬件支持)。

上述代碼,僅僅需要添加一行,

glEnable(GL_DEPTH_TEST);

以啟用深度測(cè)試,效果大不一樣:

image

天下至簡(jiǎn)之事莫過(guò)于此:)

為節(jié)省篇幅僅貼出關(guān)鍵片段,完整源代碼見(jiàn)我博客源代碼的2009-11-12/glDepthTest/ 目錄,獲取方式見(jiàn)文章最后關(guān)于獲取博客完整源代碼的說(shuō)明。

扇子驅(qū)不散大霧 -- 阿拉伯諺語(yǔ)

像云像霧 又像風(fēng) -- 某電視劇名

霧作為一種常見(jiàn)的天氣現(xiàn)象,OpenGL中有所模擬體現(xiàn)也算是正常,但是在OpenGL中霧的作用卻又不止這些,事實(shí)上,霧效果還用于實(shí)現(xiàn)模糊效果,用于關(guān)于模擬模糊,薄霧,煙,污染。

使用步驟非常簡(jiǎn)單,一如OpenGL慣例,首先通過(guò)glEnable開(kāi)啟,然后又有一個(gè)glFog*這個(gè)用于設(shè)置霧效果的函數(shù)可以使用,呵呵,OpenGL學(xué)多了,會(huì)發(fā)現(xiàn)除了概念不一樣,基本上的使用步驟都差不多,開(kāi)始覺(jué)得OpenGL的這種一個(gè)函數(shù)通過(guò)pname參數(shù)去決定函數(shù)作用的方式不太符合好的API的設(shè)計(jì)哲學(xué),(可以參考《 設(shè)計(jì)Qt風(fēng)格的C++API【轉(zhuǎn)】 》)但是想來(lái),API的設(shè)計(jì)還不一定有絕對(duì)意義上的好壞,這樣的設(shè)計(jì)倒是在一定程度上減少了API的數(shù)量,并且查找時(shí)會(huì)稍微方便一點(diǎn),雖然同時(shí)增加了查文檔看參數(shù)作用的負(fù)擔(dān),這些又是題外話(huà)了。

首先看沒(méi)有霧效果時(shí),我用OpenGL繪制的3個(gè)紅球,紅球的Z軸是依次向內(nèi)。

主要代碼如下:

    
      void 
    
    
      DrawRedSphere
    
    
()
{
    
    
      GLfloat mat_specular
    
    
[] = { 1.0, 0.0, 0.0, 1.0 };
    
    
      GLfloat mat_shininess
    
    
[] = { 50.0 };
    
    
      GLfloat mat_ambient
    
    
[] = { 1.0, 0.0, 0.0, 1.0 };
    
    
      GLfloat mat_diffuse
    
    
[] = { 1.0, 0.0, 0.0, 1.0 };

    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_SPECULAR
    
    
, 
    
      mat_specular
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_SHININESS
    
    
, 
    
      mat_shininess
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_AMBIENT
    
    
, 
    
      mat_ambient
    
    
);
    
    
      glMaterialfv
    
    
(
    
      GL_FRONT
    
    
, 
    
      GL_DIFFUSE
    
    
, 
    
      mat_diffuse
    
    
);

    
    
      glutSolidSphere
    
    
(0.25, 32, 32);
}


    
      //這里進(jìn)行所有的繪圖工作

    
    
      void 
    
    
      SceneShow
    
    
(
    
      GLvoid
    
    
)        
{
    
    
      glClear
    
    
(
    
      GL_COLOR_BUFFER_BIT 
    
    
| 
    
      GL_DEPTH_BUFFER_BIT
    
    
);    

    
    
      glPushMatrix
    
    
();
    
    
      glTranslatef
    
    
(-0.75, 0.0, 0.0);
    
    
      DrawRedSphere
    
    
();
    
    
      glPopMatrix
    
    
();

    
    
      glPushMatrix
    
    
();
    
    
      glTranslatef
    
    
(0.0, 0.0, -1.0);
    
    
      DrawRedSphere
    
    
();
    
    
      glPopMatrix
    
    
();

    
    
      glPushMatrix
    
    
();
    
    
      glTranslatef
    
    
(0.75, 0.0, -2.0);
    
    
      DrawRedSphere
    
    
();
    
    
      glPopMatrix
    
    
();

    
    
      glFlush
    
    
();
}  
  

image

從圖形上效果上看不出Z軸的變化,因?yàn)槭褂玫氖钦队胺绞健,F(xiàn)在我們啟用霧效果來(lái)試一下。

添加進(jìn)如下語(yǔ)句:

    
      glEnable
    
    
(
    
      GL_FOG
    
    
);

    
      GLfloat fogColor
    
    
[4] = {1.0, 1.0, 1.0, 1.0};


    
      glFogi 
    
    
(
    
      GL_FOG_MODE
    
    
, 
    
      GL_EXP
    
    
);

    
      glFogfv 
    
    
(
    
      GL_FOG_COLOR
    
    
, 
    
      fogColor
    
    
);

    
      glFogf 
    
    
(
    
      GL_FOG_DENSITY
    
    
, 0.5);
  
    效果如下:
  
    
      image
    
  
    因?yàn)殪F的顏色為白色,第3個(gè)紅球基本上已經(jīng)全白了。。。。大家可以調(diào)整上述代碼中的參數(shù)以獲取不同的效果。
  
    比如說(shuō),偏藍(lán)色的霧:
  
    
      glEnable
    
    
(
    
      GL_FOG
    
    
);

    
      GLfloat fogColor
    
    
[4] = {0.0, 0.0, 0.5, 1.0};


    
      glFogi 
    
    
(
    
      GL_FOG_MODE
    
    
, 
    
      GL_EXP
    
    
);

    
      glFogfv 
    
    
(
    
      GL_FOG_COLOR
    
    
, 
    
      fogColor
    
    
);

    
      glFogf 
    
    
(
    
      GL_FOG_DENSITY
    
    
, 0.5);
  

image

為節(jié)省篇幅僅貼出關(guān)鍵片段,完整源代碼見(jiàn)我博客源代碼的2009-11-12/glFogSample/ 目錄,獲取方式見(jiàn)文章最后關(guān)于獲取博客完整源代碼的說(shuō)明。

主要函數(shù)其實(shí)也就一個(gè)glFog*,但是參數(shù)那是相當(dāng)?shù)亩喟。舸蠹易约簢L試了。

OpenGL Reference Manual 》:

glFog — specify fog parameters
C Specification
void glFogf( GLenum pname,
GLfloat param);
void glFogi( GLenum pname,
GLint param);
Parameters

pname

Specifies a single-valued fog parameter.
GL_FOG_MODE,
GL_FOG_DENSITY,
GL_FOG_START,
GL_FOG_END,
GL_FOG_INDEX, and
GL_FOG_COORD_SRC
are accepted.
param

Specifies the value that pname will be set to.

C Specification
void glFogfv( GLenum pname,
const GLfloat * params);
void glFogiv( GLenum pname,
const GLint * params);
Parameters

pname

Specifies a fog parameter.
GL_FOG_MODE,
GL_FOG_DENSITY,
GL_FOG_START,
GL_FOG_END,
GL_FOG_INDEX,
GL_FOG_COLOR, and
GL_FOG_COORD_SRC
are accepted.
params

Specifies the value or values to be assigned to pname.
GL_FOG_COLOR requires an array of four values.
All other parameters accept an array containing only a single value.

Description

Fog is initially disabled.
While enabled, fog affects rasterized geometry,
bitmaps, and pixel blocks, but not buffer clear operations. To enable
and disable fog, call glEnable and glDisable with argument
GL_FOG.

glFog assigns the value or values in params to the fog parameter
specified by pname.
The following values are accepted for pname:

GL_FOG_MODE

params is a single integer or floating-point value that specifies
the equation to be used to compute the fog blend factor,
f.
Three symbolic constants are accepted:
GL_LINEAR,
GL_EXP,
and GL_EXP2.
The equations corresponding to these symbolic constants are defined below.
The initial fog mode is GL_EXP.
GL_FOG_DENSITY

params is a single integer or floating-point value that specifies
density,
the fog density used in both exponential fog equations.
Only nonnegative densities are accepted.
The initial fog density is 1.
GL_FOG_START

params is a single integer or floating-point value that specifies
start,
the near distance used in the linear fog equation.
The initial near distance is 0.
GL_FOG_END

params is a single integer or floating-point value that specifies
end,
the far distance used in the linear fog equation.
The initial far distance is 1.
GL_FOG_INDEX

params is a single integer or floating-point value that specifies
i
f
,
the fog color index.
The initial fog index is 0.
GL_FOG_COLOR

params contains four integer or floating-point values that specify
C
f
,
the fog color.
Integer values are mapped linearly such that the most positive representable
value maps to 1.0,
and the most negative representable value maps to
-1.0
.
Floating-point values are mapped directly.
After conversion,
all color components are clamped to the range
0
1
.
The initial fog color is (0, 0, 0, 0).
GL_FOG_COORD_SRC

params contains either of the following symbolic constants:
GL_FOG_COORD or GL_FRAGMENT_DEPTH. GL_FOG_COORD
specifies that the current fog coordinate should be used as distance value
in the fog color computation. GL_FRAGMENT_DEPTH specifies that the
current fragment depth should be used as distance value in the fog
computation.

本系列其他文章見(jiàn)OpenGL專(zhuān)題 《 Win32 OpenGL系列專(zhuān)題

參考資料

1. 《 OpenGL Reference Manual 》,OpenGL參考手冊(cè)

2. 《OpenGL 編程指南》(《 OpenGL Programming Guide 》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis 著,徐波譯,機(jī)械工業(yè)出版社

3. 《Nehe OpenGL Tutorials》,Nehe著,在 http://nehe.gamedev.net/ 上可以找到教程及相關(guān)的代碼下載,(有PDF版本教程下載)Nehe自己還做了一個(gè)面向?qū)ο蟮目蚣埽鳛檠菔境绦騺?lái)說(shuō),這樣的框架非常合適。也有 中文版 ,各取所需吧。

4. 《OpenGL入門(mén)學(xué)習(xí)》 ,eastcowboy著,這是我在網(wǎng)上找到的一個(gè)比較好的教程,較為完善,而且非常通俗。這是第一篇的地址: http://bbs.pfan.cn/post-184355.html

完整源代碼獲取說(shuō)明

由于篇幅限制,本文一般僅貼出代碼的主要關(guān)心的部分,代碼帶工程(或者makefile)完整版(如果有的話(huà))都能用Mercurial在Google Code中下載。文章以博文發(fā)表的日期分目錄存放,請(qǐng)直接使用Mercurial克隆下庫(kù):

https://blog-sample-code.jtianling.googlecode.com/hg/

Mercurial使用方法見(jiàn)《 分布式的,新一代版本控制系統(tǒng)Mercurial的介紹及簡(jiǎn)要入門(mén)

要是僅僅想瀏覽全部代碼也可以直接到google code上去看,在下面的地址:

http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code

原創(chuàng)文章作者保留版權(quán) 轉(zhuǎn)載請(qǐng)注明原作者 并給出鏈接

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

Win32 OpenGL編程(13) 隱藏表面消除(深度測(cè)試)及霧效果


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲国产精品成 | 一区二区三区四区日韩 | 午夜国产福利 | 天天做天天爱天天爽天天综合 | 色综合久久天天综合绕观看 | 日韩黄色网页 | 奇米四色在线观看 | 欧美日韩亚洲精品一区 | 日本不卡一区二区三区视频 | 亚洲 激情 | 成年女人18级毛片毛片 | 日日摸夜夜欧美一区二区 | 精品国产免费福利片 | 日韩欧美在线看 | 亚洲综合五月天 | 福利在线免费 | 国产精品自拍视频 | 天天干一干 | 俄罗斯美女逼 | 黑丝毛片 | 久久是精品 | 天天干天天插天天 | 成人欧美视频在线观看播放 | 不卡免费在线视频 | 久草新免费 | 日日碰狠狠添天天爽爽爽 | 免费一级欧美大片在线观看 | 亚洲欧美日韩国产综合专区 | 特黄aa级毛片免费视频播放 | 国产ww久久久久久久久久 | 精品久久综合一区二区 | 亚洲国产精品第一区二区三区 | 国产一二三区在线 | 99j久久精品久久久久久 | 九九爱精品 | 在线播放亚洲精品富二代91 | 日本高清中文字幕一区二区三区a | 国产不卡免费视频 | 欧美爱爱小视频 | 久热这里只精品99re8久 | 福利姬在线播放 |