欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

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

系統 1825 0

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

討論新聞組及文件

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

其實這是個滯后的話題了,事實上應該在光照一節就應該詳述的,但是因為光照的內容本來就多,所以當時并沒有再牽涉此內容。

在我們填充三維物體時,與平面繪制不同,因為牽涉到了前面物體遮擋后面物體的問題,假如沒有一個很好的內置機制,我們就只能通過程序記住每個物體的Z軸(其實也不一定是Z軸,看當時的觀察方向),然后按順序將遠的物體先繪制,然后再繪制離我們近的,通過這種方式,可以讓離我們近的物體繪制在后面,覆蓋掉遠的物體。

當然,假如覺得不麻煩的話,這樣做倒也不是不行,但是假如這些事情是由硬件實現的話,效率可是會上一個層次的,所以OpenGL也提供了此方法,被稱作深度測試。(Depth Test)使用方法那是相當簡單,僅僅需要通過glEnable啟用就可以了,我們現在看看使用前后的區別。

我們通過以下函數繪制一大一小兩個球

    
      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繪制的是小的藍球,繪制的時候都采用默認坐標,即繪制在屏幕的中央,并且Z軸也不動,那么,從理論上來講,大球會包含小球,小球就被大球遮掩了,我們顯示要的應該也是這種效果。

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

代碼如下:

    
      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

我們會觀察到很明顯的繪制順序導致的問題,左邊的圖因為先繪制大球再繪制小球,小的籃球竟然覆蓋掉了應該在其外部的紅球。實際使用中,我們可以都自己判斷,然后用右邊的正確繪制方式,隨著圖形的增多,會增加一定的計算量,OpenGL提供的深度測試就是為我們提供了更簡便高效的方式,事實上,由于OpenGL使用的方式因為可以在測試后,直接繪制出最終圖形而忽略繪制被覆蓋掉的圖形,效率上比覆蓋繪制會更高一些(需要硬件支持)。

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

glEnable(GL_DEPTH_TEST);

以啟用深度測試,效果大不一樣:

image

天下至簡之事莫過于此:)

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

扇子驅不散大霧 -- 阿拉伯諺語

像云像霧 又像風 -- 某電視劇名

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

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

首先看沒有霧效果時,我用OpenGL繪制的3個紅球,紅球的Z軸是依次向內。

主要代碼如下:

    
      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);
}


    
      //這里進行所有的繪圖工作

    
    
      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軸的變化,因為使用的是正投影方式。現在我們啟用霧效果來試一下。

添加進如下語句:

    
      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
    
  
    因為霧的顏色為白色,第3個紅球基本上已經全白了。。。。大家可以調整上述代碼中的參數以獲取不同的效果。
  
    比如說,偏藍色的霧:
  
    
      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

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

主要函數其實也就一個glFog*,但是參數那是相當的多啊,留待大家自己嘗試了。

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.

本系列其他文章見OpenGL專題 《 Win32 OpenGL系列專題

參考資料

1. 《 OpenGL Reference Manual 》,OpenGL參考手冊

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

3. 《Nehe OpenGL Tutorials》,Nehe著,在 http://nehe.gamedev.net/ 上可以找到教程及相關的代碼下載,(有PDF版本教程下載)Nehe自己還做了一個面向對象的框架,作為演示程序來說,這樣的框架非常合適。也有 中文版 ,各取所需吧。

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

完整源代碼獲取說明

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

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

Mercurial使用方法見《 分布式的,新一代版本控制系統Mercurial的介紹及簡要入門

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

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

原創文章作者保留版權 轉載請注明原作者 并給出鏈接

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

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成人颜色视频 | 国产精品久久久久无码人妻精品 | 日韩欧美在线看 | 日韩av电影在线播放 | 一级欧美日韩 | 精品一区二区三区在线观看 | 免费中文字幕 | 无码日韩精品一区二区免费 | 777777777亚洲妇女 | 91精品啪在线观看国产91九色 | av在线播放国产 | 一区二区国产在线观看 | 色图综合 | 国产精品a久久久久 | 久久国产婷婷国产香蕉 | 成人国产精品免费 | 欧美日韩一区二区在线视频播放 | 成人毛片在线播放 | 99热在线播放 | 一级大片免费看 | 日韩网红少妇无码视频香港 | 国产精品a久久久久 | 成人国产精品免费观看视频 | 久久av一区| 在线三级网址 | 丁香久久 | 久久草在线精品视频99 | 欧美一级二级三级 | 奇米影视首页 | 日韩欧美专区 | 欧美在线精品一区二区在线观看 | 天天色图片 | 一 级做人爱全视频在线看 久久综合九色综合网站 | 2021国产精品成人免费视频 | 毛片在线免费观看完整版 | 国产在线精品一区 | 久9久9精品视频在线观看 | 欧美特黄 | 欧美欲乱妇135| 国产成人啪精品视频免费网站软件 | 毛片2 |