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

Win32 OpenGL編程(11) 光照

系統(tǒng) 1611 0

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

討論新聞組及文件

最近跟風(fēng),看了《思維導(dǎo)圖》,用XMind為此節(jié)畫了個(gè)思維導(dǎo)圖,事實(shí)上感覺這種書說起來不一定完全沒有用,但是為了顯示有用似乎說的太過夸張了,基本上,我認(rèn)可一圖勝千言吧。。。。另外,XMind還算比較好用,特別是上傳然后共享的方式比較方便:)基礎(chǔ)版還開源。

上面這種圖用于解釋概念就略顯簡單,但是用于梳理脈絡(luò),復(fù)習(xí)時(shí)回憶概念還算是比較有用的。

上帝說,要有光,就有了光。---- 《舊約?創(chuàng)世紀(jì)》

使用OpenGL時(shí),程序員可以暫時(shí)充當(dāng)一下上帝的角色(其實(shí)犯了妄自稱上帝的戒律),你對(duì)電腦說要有光,于是,顯示的時(shí)候就有了光,呵呵。當(dāng)然,說的時(shí)候需要用電腦的語言。

相對(duì)來說,光照在OpenGL中是屬于那種概念理解比較簡單,但是使用卻比較復(fù)雜的功能之一,因?yàn)楣庹諏儆诒容^容易影響顯示效果的因素,所以光照的用法太多,導(dǎo)致可以使用的定制手段相當(dāng)多,這也就加深了使用的復(fù)雜度,基本上,遵循理解核心概念,需要時(shí)再去查文檔理解每個(gè)函數(shù)的具體參數(shù)使用和意義是種不錯(cuò)的學(xué)習(xí)方式,當(dāng)然,要想精通,恐怕對(duì)各種光照應(yīng)用的情況都得有個(gè)了解才行。上述思維導(dǎo)圖就是核心概念的一個(gè)簡要列表,以下以此圖展開來討論。

為啥需要光

上帝為啥創(chuàng)造光?上帝沒有光看不見東西嗎?。。。。。。。。或者因?yàn)樯系壅J(rèn)為黑暗是不好的,不想呆在黑暗之中。。。。。只有上帝知道

那我們?yōu)樯缎枰饽兀恳驗(yàn)槲覀兊氖澜缬猩系蹌?chuàng)造的光,而OpenGL本質(zhì)上是對(duì)現(xiàn)實(shí)世界的一種建模,既然現(xiàn)實(shí)世界有太陽,有光,那么模擬現(xiàn)實(shí)世界顯示的OpenGL怎么能沒有光呢?(以上純屬無聊的廢話)

以前畫3D圖形的時(shí)候我有意的將物體的每個(gè)面都設(shè)置成不同的顏色(比如以前那個(gè)三角錐),這樣我們才能夠較為清楚的看出來這是個(gè)3D的圖形,為什么會(huì)這樣說呢?那我們先看看事實(shí)上,假如我沒有那樣做,我們看到的是啥。這里以《 Win32 OpenGL編程(6) 踏入3D世界 》一文的glSmoothColorPyramid一例為修改藍(lán)本,(原來的源代碼見/2009-10-21/glSmoothColorPyramid/),將其4面顏色全部設(shè)置為紅色。

即將其源代碼中表示顏色的數(shù)組改為如下形式:

    
      static 
    
    
      GLfloat fPyramidColors
    
    
[] = { 1.0, 0.0, 0.0,
    1.0, 0.0, 0.0,
    1.0, 0.0, 0.0,
    1.0, 0.0, 0.0};
  

我們看看效果。

image

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

事實(shí)上,即便是整個(gè)三角錐正以3D的方式不停的旋轉(zhuǎn),我們看到的效果也類似于一張三角形的紅紙片不停的晃悠而已。3D效果蕩然無存,很顯然,這是有問題的,不能說一個(gè)純色的物體的3D效果會(huì)受到影響吧?這算是我們需要光的最簡單的一層了。一個(gè)三角錐還好說一點(diǎn),我們看看一個(gè)球。此例利用了glut的具體畫實(shí)心體的函數(shù),以后不再全部利用自己的復(fù)雜手工代碼來創(chuàng)造那簡陋的三角錐了,作為一些概念的講解,那樣的三角錐已經(jīng)有點(diǎn)過于簡單了。(當(dāng)然,可以用的時(shí)候還是會(huì)用)因?yàn)槔昧薵lut,畫球就很簡單了(事實(shí)上不用也不難),只需要設(shè)置好紅色,然后用

    
      glutSolidSphere
    
    
(0.5, 30, 16);
  
    就能畫出下面這種半徑為窗口寬度1/4的球。
  

image 有人能看出來上面的那個(gè)是球?我們看到的僅僅是一個(gè)圓而已,數(shù)學(xué)中我們也常常會(huì)將某個(gè)方向的球的圖形抽象成一個(gè)圓,但是現(xiàn)實(shí)中我們還是很容易看出一個(gè)球就是一個(gè)球而不是一個(gè)圓的面,為啥呢?光啊,因?yàn)楣庹盏拇嬖冢粋€(gè)球在我們眼里事實(shí)上不會(huì)是如上面那樣純紅色的就整個(gè)球都是純紅色,會(huì)根據(jù)光照的方向,強(qiáng)度等因素的不同導(dǎo)致各個(gè)部位顯示不同。下面是一個(gè)加上了光照的紅色球體的例子。(上傳U酷后顏色變了-_-!可能是因?yàn)閁酷在上傳后進(jìn)行了2次壓縮編碼導(dǎo)致的顏色混亂,光源移動(dòng)效果基本一致,需要真實(shí)體驗(yàn)的可以下載源代碼編譯后運(yùn)行)

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

主要源代碼如下:

      
        //OpenGL初始化開始
      
      
void SceneInit( int w, int h)
{
GLenum err = glewInit();
if (err != GLEW_OK)
{
MessageBox(NULL, _T( "Error" ), _T( "Glew init failed." ), MB_OK);
exit(-1);
}

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

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glColor3f(0.0, 0.0, 0.0);
}

//這里進(jìn)行所有的繪圖工作
void SceneShow(GLvoid)
{
static GLfloat light_position[] = { 1.0, 0.0, -3.0, 0.0 };
static GLfloat angle = 1.0;

glClear(GL_COLOR_BUFFER_BIT); // 清空顏色緩沖區(qū)

glPushMatrix();
glRotatef(angle, 0.0, 1.0, 0.0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glPopMatrix();
angle += 1.0;

glutSolidSphere(0.5, 30, 16);

glFlush();
}

這里啟用光照的順序就像是上面那個(gè)思維導(dǎo)圖中表示的一樣,一下解釋一下各步驟:

1.定義物體的法線

這一步其實(shí)很重要,但是我們?cè)谶@個(gè)例子中看不到,原因在于glutSolidSphere函數(shù)已經(jīng)完成了這樣的定義,法線的定義有點(diǎn)類似我們以前確定物體表面時(shí)用逆/正時(shí)針的頂點(diǎn)指定順序來確定一個(gè)物體的正背面一樣,法線定義了光線入射時(shí)物體相對(duì)于光源的方向,這算是個(gè)額外的小題目,以后有機(jī)會(huì)再論及,可以參考《OpenGL 編程指南》的第2.5節(jié)。基本上知道法線的概念后,需要調(diào)用的就是glNormal*函數(shù),但是法線的計(jì)算并不總是那么容易。。。。。。比如此例的球體,還好,此例因?yàn)槭鞘褂矛F(xiàn)成的函數(shù),省了此步。

2.創(chuàng)建和選擇光源,并設(shè)置位置

glEnable ( GL_LIGHTING );
glEnable ( GL_LIGHT0 );

兩句表示啟用了第0號(hào)光源,此光源默認(rèn)顏色為白色,位置為(0.0,0.0,1.0, 0.0)。我們利用了其默認(rèn)顏色。

glLight*函數(shù)是專門的光照配置控制函數(shù)。

OpenGL Programming Guide 》:

glLight — set light source parameters
C Specification
void glLightf( GLenum light,
GLenum pname,
GLfloat param);
void glLighti( GLenum light,
GLenum pname,
GLint param);
Parameters

light

Specifies a light.
The number of lights depends on the implementation,
but at least eight lights are supported.
They are identified by symbolic names of the form GL_LIGHT
i,
where i ranges from 0 to the value of GL_MAX_LIGHTS - 1.
pname

Specifies a single-valued light source parameter for light.
GL_SPOT_EXPONENT,
GL_SPOT_CUTOFF,
GL_CONSTANT_ATTENUATION,
GL_LINEAR_ATTENUATION, and
GL_QUADRATIC_ATTENUATION are accepted.
param

Specifies the value that parameter pname of light source light
will be set to.

事實(shí)上,此函數(shù)遠(yuǎn)遠(yuǎn)不如看起來的那么簡單,上面說了,因?yàn)楣庹諏儆诒容^容易影響顯示效果的因素,所以光照的用法很多,上述的pname參數(shù)指定的n個(gè)值就可見一斑。但是本例中使用的方式卻很簡單,僅僅使用此函數(shù)來設(shè)定0號(hào)光源的位置而已。光照的分類其實(shí)包括環(huán)境光,散射光,鏡面光,發(fā)射光(實(shí)際指物體的發(fā)射顏色emissive color)等屬性,這里不詳述了。

    
      glLightfv
    
    
(
    
      GL_LIGHT0
    
    
, 
    
      GL_POSITION
    
    
, 
    
      light_position
    
    
);
  

因?yàn)楣庹漳P偷奈恢弥付ㄊ鞘褂昧四P鸵晥D,所以我們也可以用模型變換的方式來指定光源的位置,就像光源是個(gè)普通的物體一樣,此例中使用了旋轉(zhuǎn)模型視圖的函數(shù)旋轉(zhuǎn)了光源的位置,旋轉(zhuǎn)方式是以Y軸為旋轉(zhuǎn)軸,看到的效果也就是如視頻所示,類似月相變化的動(dòng)畫。

3.創(chuàng)建和選擇光照模型

光照在OpenGL中有兩種模型,一種叫無限遠(yuǎn)觀察者模式,一種叫本地觀察者模式,通過glLightModel*函數(shù)設(shè)置,默認(rèn)為無限遠(yuǎn)觀察者模型,這里沒有修改,即使用了默認(rèn)值,區(qū)別在于是否考慮到觀察者位置對(duì)物體觀察角度不同引起變化,相對(duì)來說本地觀察者模型會(huì)更加逼真一些,但是因?yàn)橛蓄~外的光照計(jì)算,性能也會(huì)受到影響。。。。按照OpenGL管理,默認(rèn)選擇的往往是性能更優(yōu)的,而不是效果更好的。但是,就這么簡單的例子,我看不出區(qū)別。

OpenGL Programming Guide 》:

glLightModel — set the lighting model parameters
C Specification
void glLightModelf( GLenum pname,
GLfloat param);
void glLightModeli( GLenum pname,
GLint param);
Parameters

pname

Specifies a single-valued lighting model parameter.
GL_LIGHT_MODEL_LOCAL_VIEWER,
GL_LIGHT_MODEL_COLOR_CONTROL, and
GL_LIGHT_MODEL_TWO_SIDE are accepted.
param

Specifies the value that param will be set to.

我們可以通過

glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

的調(diào)用切換至本地觀察者模型。

4.定義物體的材料屬性

光是定義了光源而不定義物體怎么反射光,在OpenGL中是不行的,物體的材料屬性決定了其將會(huì)怎么對(duì)光進(jìn)行反應(yīng),與光源屬性對(duì)應(yīng),也有幾種與反射光相關(guān)材料屬性可以設(shè)置。我們通過glMateriall*來設(shè)置材料屬性。

OpenGL Programming Guide 》:

glMaterial — specify material parameters for the lighting model
C Specification

void glMaterialfv( GLenum face,
GLenum pname,
const GLfloat * params);
void glMaterialiv( GLenum face,
GLenum pname,
const GLint * params);
Parameters

face

Specifies which face or faces are being updated.
Must be one of
GL_FRONT,
GL_BACK, or
GL_FRONT_AND_BACK.
pname

Specifies the material parameter of the face or faces that is being updated.
Must be one of
GL_AMBIENT,
GL_DIFFUSE,
GL_SPECULAR,
GL_EMISSION,
GL_SHININESS,
GL_AMBIENT_AND_DIFFUSE, or
GL_COLOR_INDEXES.
params

Specifies a pointer to the value or values that pname will be set to.

上例中:

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

這樣8行,定義了4中材料的屬性,并且我們都是使用GL_FRONT定義正面受到光照(即默認(rèn)背面無光照),GL_SPECULAR表示鏡面顏色,GL_SHININESS表示鏡面指數(shù),GL_AMBIENT表示環(huán)境顏色,GL_DIFFUSE表示散射顏色,其中散射顏色和環(huán)境顏色影響物體所反色的散射光和環(huán)境光顏色,(與光源屬性對(duì)應(yīng))有直接光照時(shí),人體主要感知還是以散射顏色為主,無光照時(shí),環(huán)境顏色才會(huì)占重要地位。鏡面顏色決定鏡面反射產(chǎn)生的亮點(diǎn),GL_SHININESS參數(shù)設(shè)置亮點(diǎn)的大小和亮度,發(fā)射光顏色會(huì)讓物體微微發(fā)光(此例未用)。因?yàn)楸容^復(fù)雜,上述文字僅僅大概描述了一個(gè)概念,具體的參數(shù)還是參考《 OpenGL Programming Guide 》 并且實(shí)際的調(diào)整不同數(shù)值體驗(yàn)效果為好。其中,《 OpenGL Programming Guide 》一書中推薦的 Nate Robin的OpenGL教程 的教學(xué)程序程序中有兩個(gè)實(shí)例與光照有關(guān),能夠體驗(yàn)數(shù)值改變時(shí)顯示的效果。假如大家不想自己編程調(diào)試,可以使用教程中的lightposition,lightmateria兩個(gè)例子體驗(yàn)。

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

參考資料

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ū)ο蟮目蚣埽鳛檠菔境绦騺碚f,這樣的框架非常合適。也有 中文版 ,各取所需吧。

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

完整源代碼獲取說明

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

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

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

要是僅僅想瀏覽全部代碼也可以直接到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編程(11) 光照


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

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

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

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

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 天天干人人干 | 久久亚洲美女久久久久 | 欧美性xxxx另类 | 国产欧美日韩中文字幕 | 国产精品自在线拍国产 | 美女在线视频观看影院免费天天看 | 久久国产热这里只有精品 | 国产一级特黄aa毛片 | 青草五月天| 真人一级一级特黄高清毛片 | 99热这里有免费国内精品 | 日日摸天天添天天添破 | 操操操人人 | 久草b | 国产精品色婷婷在线观看 | 久久免费小视频 | 奇米四色视频 | 天天做天天爱夜夜爽女人爽宅 | 国产日产精品久久久久快鸭 | 青草青青在线视频 | 中文字幕天天躁夜夜狠狠综合 | 五月综合激情久久婷婷 | 妖精视频免费在线观看 | 在线成人欧美 | 日韩第3页 | 99在线观看视频免费 | 亚洲高清美女一区二区三区 | 国产成人精品亚洲77美色 | videosex久久麻豆 | 99热99re8国产在线播放 | 香蕉国产在线观看免费 | 天天做天天爱天天一爽一毛片 | 精品九九视频 | 亚洲国产成人精品一区二区三区 | 手机看片欧美日韩 | 香蕉国产在线 | 99在线国产视频 | 国产高清视频在线免费观看 | 欧美交换乱理伦片120秒 | 亚洲综合视频 | 一级欧美毛片成人免费视频 |