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

Win32 OpenGL編程(14) 顯示列表

系統(tǒng) 1988 0

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

討論新聞組及文件

Technorati 標(biāo)簽: 顯示列表 , display list , OpenGL

前段時(shí)間因?yàn)閯倱Q工作,很多東西都沒(méi)有步入正軌,因?yàn)楣ぷ髟颍瑢W(xué)習(xí)了很多其他的東西,比如irrlicht等,現(xiàn)在慢慢緩下來(lái)了,還是好好的將OpenGL學(xué)習(xí)完。呵呵,其實(shí)這個(gè)系列主要還是自己學(xué)習(xí)為主,但是選擇了一條比較累的寫(xiě)博方式,其實(shí)一邊學(xué)習(xí)一般完成NEHE教程的Win32代碼就可以了,但是選擇了跟隨《 OpenGL Programming Guide 》的方式,這樣會(huì)比NEHE學(xué)的更詳細(xì)一些,但是因?yàn)樽约盒枰~外打很多字,所以也累了很多。閑話少說(shuō),繼續(xù)學(xué)習(xí)。

顯示列表

顯示列表可以提高性能,事實(shí)上就像把一對(duì)的函數(shù)存入OpenGL的緩存中,然后能很快的調(diào)用一樣,事實(shí)上,比普通的函數(shù)調(diào)用的優(yōu)點(diǎn)僅在于速度更快,但是卻無(wú)法更改。甚至包括參數(shù)都無(wú)法更改。。。。。。。相當(dāng)于用犧牲靈活性來(lái)?yè)Q取一定的性能。。。。。當(dāng)然,在對(duì)圖形程序的性能追求中,犧牲的又何止是靈活性啊。。。。。。可讀性,可維護(hù)性,擴(kuò)展性。。。。。都?jí)蚜覡奚^(guò)

效率對(duì)比

下面具體來(lái)看看例子,為了更加具體的表現(xiàn)顯示列表對(duì)性能的優(yōu)化,一兩個(gè)球的繪制是沒(méi)有辦法的,我決定繪制在屏幕上繪制100個(gè)球,源代碼利用原來(lái)文章中的2009-11-9/LightSimple,這樣還可以加大動(dòng)態(tài)光照的運(yùn)算,進(jìn)一步加大運(yùn)算量。利用普通函數(shù)完成這樣的工作,用已有的知識(shí)已經(jīng)沒(méi)有問(wèn)題了,代碼如下:

    
      void 
    
    
      DrawAll
    
    
()
{
    
    
      glPushMatrix
    
    
();
    
    
      glTranslatef
    
    
(-0.9, 0.9, 0.0);
    
    
      for
    
    
(
    
      int 
    
    
      i 
    
    
= 0; 
    
      i 
    
    
< 10; ++
    
      i
    
    
)
    {
        
    
      for
    
    
(
    
      int 
    
    
      j 
    
    
= 0; 
    
      j 
    
    
< 10; ++
    
      j
    
    
)
        {
            
    
      glutSolidSphere
    
    
(0.1, 30, 16); 
    
      // r = 1 / 20
            
    
    
      glTranslatef
    
    
(0.2, 0.0, 0.0);
        }
        
    
      glTranslatef
    
    
(-2.0, -0.2, 0.0);
    }
    
    
      glPopMatrix
    
    
();
}
  

代碼的含義不解釋?xiě)?yīng)該也很清楚,先移到屏幕左上角,每繪制一個(gè)球移動(dòng)一個(gè)球的距離,繪制下一個(gè),每10個(gè)球繪制后換一行,并且移動(dòng)到開(kāi)頭,繼續(xù)繪制。

然后放開(kāi)fps的限制,加入一段計(jì)算fps的代碼:

    
      // called every frame

    
    
      int 
    
    
      CalculateFPS
    
    
(
    
      DWORD now
    
    
)
{
    
    
      static int 
    
    
      frameCounted 
    
    
= 0;
    
    
      static int 
    
    
      startTime 
    
    
= 
    
      GetTickCount
    
    
();
    
    
      static int 
    
    
      fps 
    
    
= 0;
    ++
    
      frameCounted
    
    
;

    
    
      int 
    
    
      elapsed 
    
    
= 
    
      now 
    
    
- 
    
      startTime
    
    
;

    
    
      if 
    
    
(
    
      elapsed 
    
    
>= 1500 )
    {
        
    
      fps 
    
    
= ( 1000 * 
    
      frameCounted 
    
    
) / 
    
      elapsed
    
    
;
        
    
      startTime 
    
    
= 
    
      now
    
    
;
        
    
      frameCounted 
    
    
= 0;
    }

    
    
      return 
    
    
      fps
    
    
;
}
  

為了這里特別寫(xiě)的,假如有什么問(wèn)題請(qǐng)指出來(lái),含義也很簡(jiǎn)單,每1500毫秒(一秒半)算一下fps,為什么用1500毫秒,是感覺(jué)要是定在1000,好像誤差會(huì)大點(diǎn),事實(shí)上,這里用的時(shí)間越久,誤差越小,但是計(jì)算的間隔長(zhǎng)了,不能及時(shí)的反應(yīng)變化。

對(duì)了,為了更好的展示效率,使用了離屏繪制,(雙緩沖)不明白的看看第一節(jié)。

效果及大概的運(yùn)行效率如下圖所示:

image

基本上在150~200幀左右。(因?yàn)樽テ恋乃查g會(huì)導(dǎo)致瞬間的fps下降)

我們?cè)倏纯达@示列表的版本:

利用一下幾句生成新的顯示列表:

    
      giTorus 
    
    
= 
    
      glGenLists
    
    
(2);


    
      glNewList
    
    
(
    
      giTorus
    
    
, 
    
      GL_COMPILE
    
    
);
    
    
      glutSolidSphere
    
    
(0.1, 30, 16); 
    
      // r = 1 / 20

    
    
      glEndList
    
    
();


    
      glNewList
    
    
(
    
      giTorus
    
    
+1, 
    
      GL_COMPILE
    
    
);

    
      glPushMatrix
    
    
();

    
      glTranslatef
    
    
(-0.9, 0.9, 0.0);

    
      for
    
    
(
    
      int 
    
    
      i 
    
    
= 0; 
    
      i 
    
    
< 10; ++
    
      i
    
    
)
{
    
    
      for
    
    
(
    
      int 
    
    
      j 
    
    
= 0; 
    
      j 
    
    
< 10; ++
    
      j
    
    
)
    {
        
    
      glCallList
    
    
(
    
      giTorus
    
    
);
        
    
      glTranslatef
    
    
(0.2, 0.0, 0.0);
    }
    
    
      glTranslatef
    
    
(-2.0, -0.2, 0.0);
}

    
      glPopMatrix
    
    
();

    
      glEndList
    
    
();
  

然后再調(diào)用:

glCallList(giTorus+1);

基本上就好了,與一般的OpenGL特性不同的是,顯示列表使用上非常簡(jiǎn)單,但是知道什么時(shí)候應(yīng)該使用,卻需要一定的知識(shí)和經(jīng)驗(yàn),在《 OpenGL Programming Guide 》中,甚至有專門(mén)的一節(jié)《顯示列表的設(shè)計(jì)哲學(xué)》來(lái)闡述這個(gè)。

我們看看效果:

image

基本上在370~450之間(同樣因?yàn)樽テ恋乃查g會(huì)導(dǎo)致瞬間的fps下降)

從fps上來(lái)看,效率成倍的增加。這就是顯示列表的作用,僅僅這么一個(gè)小程序都無(wú)法掩蓋其強(qiáng)大。。。。。。

使用

顯示列表牽涉的API并不算太多,而且很好理解:

OpenGL Reference Manual 》:

GLuint glGenLists( GLsizei range);
Parameters

range

Specifies the number of contiguous empty display lists
to be generated.

glGenLists返回一個(gè)由range指定長(zhǎng)度的顯示列表起始標(biāo)記,相當(dāng)于普通操作的分配內(nèi)存,返回的第一個(gè)內(nèi)存的指針,glGenLists返回的也是第一個(gè)顯示列表的標(biāo)志,但是是以整數(shù)值來(lái)表示的。

然后,再就是glNewList和glEndList函數(shù)對(duì),指示了一個(gè)顯示列表的開(kāi)始及結(jié)束,具體指示的顯示列表由glNewList的第一個(gè)參數(shù)決定,就像定義一個(gè)函數(shù)的“{”和“}” 一樣。

再然后,就是glCallList用于調(diào)用顯示列表,就像調(diào)用函數(shù)一樣,用參數(shù)指定調(diào)用的是哪個(gè)顯示列表。

    
      giTorus 
    
    
= 
    
      glGenLists
    
    
(2);


    
      glNewList
    
    
(
    
      giTorus
    
    
, 
    
      GL_COMPILE
    
    
);
    
    
      glutSolidSphere
    
    
(0.1, 30, 16); 
    
      // r = 1 / 20

    
    
      glEndList
    
    
();
  

以上的4句已經(jīng)定義了一個(gè)完整的顯示列表了,分配,定義,都齊了。GL_COMPILE參數(shù)表示僅僅定義,但是不執(zhí)行。(就像真正的函數(shù)第一次定義時(shí)那樣)

    
      glNewList
    
    
(
    
      giTorus
    
    
+1, 
    
      GL_COMPILE
    
    
);

    
      glPushMatrix
    
    
();

    
      glTranslatef
    
    
(-0.9, 0.9, 0.0);

    
      for
    
    
(
    
      int 
    
    
      i 
    
    
= 0; 
    
      i 
    
    
< 10; ++
    
      i
    
    
)
{
    
    
      for
    
    
(
    
      int 
    
    
      j 
    
    
= 0; 
    
      j 
    
    
< 10; ++
    
      j
    
    
)
    {
        
    
      glCallList
    
    
(
    
      giTorus
    
    
);
        
    
      glTranslatef
    
    
(0.2, 0.0, 0.0);
    }
    
    
      glTranslatef
    
    
(-2.0, -0.2, 0.0);
}

    
      glPopMatrix
    
    
();

    
      glEndList
    
    
();
  

在上面這幾句,更加完整的展示了一個(gè)顯示列表的操作,不僅定義了一個(gè)完整的顯示列表,(就是上面那整個(gè)屏幕的球)而且在定義顯示列表的時(shí)候還用“glCallList(giTorus);”調(diào)用了剛才定義的顯示列表。這也展示了顯示列表的可嵌套性。

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

完整程序中一個(gè)程序?qū)崿F(xiàn)了上述兩種方式,利用gbIsUseDisplayList全局變量控制,需要注意,自然,還有l(wèi)ightsimple中包含變換光照位置的代碼。

參考資料

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ō),這樣的框架非常合適。也有 中文版 ,各取所需吧。

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

由于篇幅限制,本文一般僅貼出代碼的主要關(guān)心的部分,代碼帶工程(或者makefile)完整版(如果有的話)都能用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編程(14) 顯示列表


更多文章、技術(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)論
主站蜘蛛池模板: 亚洲免费成人网 | 午夜精品久久久久久久99热 | 337p欧洲日本大胆艺术 | 精品日韩在线观看 | 狠狠综合久久久久综 | 99久久精品视香蕉蕉er热资源 | 亚洲香蕉国产高清在线播放 | 乱人伦中文字幕在线看 | 国产精品98视频全部国产 | 免费中日高清无专码有限公司 | 综合久久久久久中文字幕 | 一级骚片 | 女人精69xxxxx免费无毒 | 国产精品久久久久久麻豆一区 | 国产一区二区精品久久小说 | 中文字幕无线码中文字幕免费 | 波多野结衣久久精品 | 综合欧美一区二区三区 | 国产精品一区二区三区久久 | 亚洲在线h| 国精品一区二区三区 | 夜夜操夜夜 | 精品国产一区二区麻豆 | 久久精品亚洲精品国产欧美 | 久草在线资源 | 99久久国产综合色 | 免费观看一级特黄三大片视频 | 青青影院在线观看 | 91欧美在线 | 在线精品一区二区三区 | 美女被羞羞的网站 | 久草在线视频免费播放 | 成人欧美一级毛片免费观看 | 射综合网| 99激情网| 久久国产免费一区二区三区 | 黄片毛片大全 | 国产精品资源网站在线观看 | 激情欧美一区二区三区中文字幕 | 国产精品视频偷伦精品视频 | 哪里可以看毛片 |