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

Win32 OpenGL編程(14) 顯示列表

系統 2055 0

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

討論新聞組及文件

前段時間因為剛換工作,很多東西都沒有步入正軌,因為工作原因,學習了很多其他的東西,比如irrlicht等,現在慢慢緩下來了,還是好好的將OpenGL學習完。呵呵,其實這個系列主要還是自己學習為主,但是選擇了一條比較累的寫博方式,其實一邊學習一般完成NEHE教程的Win32代碼就可以了,但是選擇了跟隨《 OpenGL Programming Guide 》的方式,這樣會比NEHE學的更詳細一些,但是因為自己需要額外打很多字,所以也累了很多。閑話少說,繼續學習。

顯示列表

顯示列表可以提高性能,事實上就像把一對的函數存入OpenGL的緩存中,然后能很快的調用一樣,事實上,比普通的函數調用的優點僅在于速度更快,但是卻無法更改。甚至包括參數都無法更改。。。。。。。相當于用犧牲靈活性來換取一定的性能。。。。。當然,在對圖形程序的性能追求中,犧牲的又何止是靈活性啊。。。。。。可讀性,可維護性,擴展性。。。。。都壯烈犧牲過

效率對比

下面具體來看看例子,為了更加具體的表現顯示列表對性能的優化,一兩個球的繪制是沒有辦法的,我決定繪制在屏幕上繪制100個球,源代碼利用原來文章中的2009-11-9/LightSimple,這樣還可以加大動態光照的運算,進一步加大運算量。利用普通函數完成這樣的工作,用已有的知識已經沒有問題了,代碼如下:

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

代碼的含義不解釋應該也很清楚,先移到屏幕左上角,每繪制一個球移動一個球的距離,繪制下一個,每10個球繪制后換一行,并且移動到開頭,繼續繪制。

然后放開fps的限制,加入一段計算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
    
    
;
}
  

為了這里特別寫的,假如有什么問題請指出來,含義也很簡單,每1500毫秒(一秒半)算一下fps,為什么用1500毫秒,是感覺要是定在1000,好像誤差會大點,事實上,這里用的時間越久,誤差越小,但是計算的間隔長了,不能及時的反應變化。

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

效果及大概的運行效率如下圖所示:

image

基本上在150~200幀左右。(因為抓屏的瞬間會導致瞬間的fps下降)

我們再看看顯示列表的版本:

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

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

然后再調用:

glCallList(giTorus+1);

基本上就好了,與一般的OpenGL特性不同的是,顯示列表使用上非常簡單,但是知道什么時候應該使用,卻需要一定的知識和經驗,在《 OpenGL Programming Guide 》中,甚至有專門的一節《顯示列表的設計哲學》來闡述這個。

我們看看效果:

image

基本上在370~450之間(同樣因為抓屏的瞬間會導致瞬間的fps下降)

從fps上來看,效率成倍的增加。這就是顯示列表的作用,僅僅這么一個小程序都無法掩蓋其強大。。。。。。

使用

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

OpenGL Reference Manual 》:

GLuint glGenLists( GLsizei range);
Parameters

range

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

glGenLists返回一個由range指定長度的顯示列表起始標記,相當于普通操作的分配內存,返回的第一個內存的指針,glGenLists返回的也是第一個顯示列表的標志,但是是以整數值來表示的。

然后,再就是glNewList和glEndList函數對,指示了一個顯示列表的開始及結束,具體指示的顯示列表由glNewList的第一個參數決定,就像定義一個函數的“{”和“}” 一樣。

再然后,就是glCallList用于調用顯示列表,就像調用函數一樣,用參數指定調用的是哪個顯示列表。

    
      giTorus 
    
    
= 
    
      glGenLists
    
    
(2);


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

    
    
      glEndList
    
    
();
  

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

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

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

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

完整程序中一個程序實現了上述兩種方式,利用gbIsUseDisplayList全局變量控制,需要注意,自然,還有lightsimple中包含變換光照位置的代碼。

參考資料

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自己還做了一個面向對象的框架,作為演示程序來說,這樣的框架非常合適。也有 中文版 ,各取所需吧。

完整源代碼獲取說明

由于篇幅限制,本文一般僅貼出代碼的主要關心的部分,代碼帶工程(或者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編程(14) 顯示列表


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美一级欧美一级高清 | 午夜影视在线观看免费完整高清大全 | 性色av一区二区三区四区 | 国产在线精彩视频 | 9久9久女女免费精品视频在线观看 | 五月婷婷六月爱 | 婷婷在线网站 | 欧美极品在线观看 | 日本高免费观看在线播放 | 国产精品视频观看 | 91免费在线视频 | 国产精品密蕾丝视频下载 | 欧美精品在线观看 | 国内精品免费一区二区观看 | 欧美日韩国产精品一区二区 | 午夜激情小视频 | 性欧美高清极品猛交 | 日日爽 | 欧美丰满丝袜videossex | 日本高清一区二区三区不卡免费 | 成人午夜免费看 | 欧美性猛交一区二区三区精品 | 精品久久久久久免费影院 | 亚洲成片在线观看12345ba | 日韩亚洲欧美一区 | 免费播放春色aⅴ视频 | 亚洲国产日本 | 国产国产精品人在线观看 | 国模无水印一区二区三区 | 91看片网 | 国产成人午夜性a一级毛片 久久久久亚洲 | 国产精品久久久久免费视频 | 久久国产免费福利永久 | 激情五月色综合色婷婷 | 五月在线观看 | 亚洲精品成A人在线观看拍拍拍 | 亚洲欧洲视频 | 日穴视频在线观看 | 色悠悠久久久久 | 91高清国产视频 | 欧美日韩一区二区不卡 |