青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

  C++博客 :: 首頁 :: 聯系 ::  :: 管理
  163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

常用鏈接

留言簿(48)

我參與的團隊

搜索

  •  

積分與排名

  • 積分 - 402530
  • 排名 - 59

最新評論

閱讀排行榜

評論排行榜

這次我將教你如何使用顯示列表,顯示列表將加快程序的速度,而且可以減少代碼的長度。
   當你在制作游戲里的小行星場景時,每一層上至少需要兩個行星,你可以用OpenGL中的多邊形來構造每一個行星。聰明點的做法是做一個循環,每個循環畫出行星的一個面,最終你用幾十條語句畫出了一個行星。每次把行星畫到屏幕上都是很困難的。當你面臨更復雜的物體時你就會明白了。
那么,解決的辦法是什么呢?用現實列表,你只需要一次性建立物體,你可以貼圖,用顏色,想怎么弄就怎么弄。給現實列表一個名字,比如給小行星的顯示列表命 名為“asteroid”。現在,任何時候我想在屏幕上畫出行星,我只需要調用glCallList(asteroid)。之前做好的小行星就會立刻顯示 在屏幕上了。因為小行星已經在顯示列表里建造好了,OpenGL不會再計算如何構造它。它已經在內存中建造好了。這將大大降低CPU的使用,讓你的程序跑 的更快。
   那么,開始學習咯。我稱這個DEMO為Q-Bert顯示列表。最終這個DEMO將在屏幕上畫出15個立方體。每個立方體都由一個盒子和一個頂構成,頂部是一個單獨的顯示列表,盒子沒有頂。
   這一課是建立在第六課的基礎上的,我將重寫大部分的代碼,這樣容易看懂。下面的這些代碼在所有的課程中差不多都用到了。

  #include <windows.h>                    // Header File For Windows
  #include <stdio.h>                     // Header File For Standard Input/Output
  #include <gl\gl.h>                     // Header File For The OpenGL32 Library
  #include <gl\glu.h>                    // Header File For The GLu32 Library
  #include <gl\glaux.h>              ?    ?// Header File For The GLaux Library

  HDC hDC=NULL;                       // Private GDI Device Context
  HGLRC hRC=NULL;                      // Permanent Rendering Context
  HWND hWnd=NULL;                      // Holds Our Window Handle
  HINSTANCE hInstance;                    // Holds The Instance Of The Application

  bool keys[256];                       // Array Used For The Keyboard Routine
  bool active=TRUE;                     // Window Active Flag Set To TRUE By Default
  bool fullscreen=TRUE;                   // Fullscreen Flag Set To Fullscreen Mode By Default

   下面設置變量。首先是存儲紋理的變量,然后兩個新的變量用于顯示列表。這些變量是指向內存中顯示列表的指針。命名為box和top。
   然后用兩個變量xloop,yloop表示屏幕上立方體的位置,兩個變量xrot,yrot表示立方體的旋轉。

  GLuint texture[1];                     // Storage For One Texture
  GLuint box;                        // Storage For The Display List
  GLuint top;                        // Storage For The Second Display List
  GLuint xloop;                       // Loop For X Axis
  GLuint yloop;                       // Loop For Y Axis

  GLfloat xrot;                       // Rotates Cube On The X Axis
  GLfloat yrot;                       // Rotates Cube On The Y Axis

   接下來建立兩個顏色數組。

  static GLfloat boxcol[5][3]=                // Array For Box Colors
  {
      // Bright: Red, Orange, Yellow, Green, Blue
      {1.0f,0.0f,0.0f},{1.0f,0.5f,0.0f},{1.0f,1.0f,0.0f},{0.0f,1.0f,0.0f},{0.0f,1.0f,1.0f}
   };

   static GLfloat topcol[5][3]=
               // Array For Top Colors
  {
      // Dark: Red, Orange, Yellow, Green, Blue
      {.5f,0.0f,0.0f},{0.5f,0.25f,0.0f},{0.5f,0.5f,0.0f},{0.0f,0.5f,0.0f},{0.0f,0.5f,0.5f}
   };

   LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  // Declaration For WndProc

   現在正式開始建立顯示列表。你可能注意到了,所有創造盒子的代碼都在第一個顯示列表里,所有創造頂部的代碼都在另一個列表里。我會努力解釋這些細節。

  GLvoid BuildLists()                    // Build Box Display List
  {

   開始的時候我們告訴OpenGL我們要建立兩個顯示列表。glGenLists(2)建立了兩個顯示列表的空間,并返回第一個顯示列表的指針。“box”指向第一個顯示列表,任何時候調用“box”第一個顯示列表就會顯示出來。

      box=glGenLists(2);                 // Building Two Lists

   現在開始構造第一個顯示列表。我們已經申請了兩個顯示列表的空間了,并且有box指針指向第一個顯示列表。所以現在我們應該告訴OpenGL要建立什么類型的顯示列表。
我們用glNewList()命令來做這個事情。你一定注意到了box是第一個參數,這表示OpenGL將把列表存儲到box所指向的內存空間。第二個參 數GL_COMPILE告訴OpenGL我們想預先在內存中構造這個列表,這樣每次畫的時候就不必重新計算怎么構造物體了。
GL_COMPILE類似于編程。在你寫程序的時候,把它裝載到編譯器里,你每次運行程序都需要重新編譯。而如果他已經編譯成了.exe文件,那么每次你 只需要點擊那個.exe文件就可以運行它了,不需要編譯。當OpenGL編譯過顯示列表后,就不需要再每次顯示的時候重新編譯它了。這就是為什么用顯示列 表可以加快速度。

      glNewList(box,GL_COMPILE);            // New Compiled box Display List

   下面這部分的代碼畫出一個沒有頂部的盒子,它不會出現在屏幕上,只會存儲在顯示列表里。
   你可以在glNewList()和glEngList()中間加上任何你想加上的代碼??梢栽O置顏色,貼圖等等。唯一不能加進去的代碼就是會改變顯示列表的代碼。顯示列表一旦建立,你就不能改變它。
比如你想加上glColor3ub(rand()%255,rand()%255,rand()%255),使得每一次畫物體時都會有不同的顏色。但因為 顯示列表只會建立一次,所以每次畫物體的時候顏色都不會改變。物體將會保持第一次建立顯示列表時的顏色。 如果你想改變顯示列表的顏色,你只有在調用顯示列表之前改變顏色。后面將詳細解釋這一點。

          glBegin(GL_QUADS);            // Start Drawing Quads

               // Bottom Face

              glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Top Right Of The Texture and Quad
              glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Top Left Of The Texture and Quad
              glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);  // Bottom Left Of The Texture and Quad
              glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);  // Bottom Right Of The Texture and Quad

               // Front Face

              glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);  // Bottom Left Of The Texture and Quad
              glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);  // Bottom Right Of The Texture and Quad
              glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);   // Top Right Of The Texture and Quad
              glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);   // Top Left Of The Texture and Quad

               // Back Face

              glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Bottom Right Of The Texture and Quad
              glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);  // Top Right Of The Texture and Quad
              glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);  // Top Left Of The Texture and Quad
              glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Bottom Left Of The Texture and Quad

               // Right face

              glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Bottom Right Of The Texture and Quad
              glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);  // Top Right Of The Texture and Quad
              glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);   // Top Left Of The Texture and Quad
              glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);  // Bottom Left Of The Texture and Quad

               // Left Face

              glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Bottom Left Of The Texture and Quad
              glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);  // Bottom Right Of The Texture and Quad
              glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);   // Top Right Of The Texture and Quad
              glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);  // Top Left Of The Texture and Quad

          glEnd();                 // Done Drawing Quads

   用glEngList()命令,我們告訴OpenGL我們已經完成了一個顯示列表。在glNewList()和glEngList()之間的任何東西就是顯示列表的一部分。

      glEndList();                   // Done Building The box List

   現在我們來建立第二個顯示列表。在上一個顯示列表的指針上加1,就得到了第二個顯示列表的指針。第二個顯示列表的指針命名為“top”。

      top=box+1;                    // top List Value Is box List Value +1

   現在我們知道了第二個顯示列表的指針,我們可以建立它了。

      glNewList(top,GL_COMPILE);            // New Compiled top Display List

   下面的代碼畫出盒子的頂部。

          glBegin(GL_QUADS);            // Start Drawing Quad

               // Top Face

              glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);  // Top Left Of The Texture and Quad
              glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);  // Bottom Left Of The Texture and Quad
              glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);  // Bottom Right Of The Texture and Quad
              glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);  // Top Right Of The Texture and Quad

          glEnd();                 // Done Drawing Quad

   然后告訴OpenGL第二個顯示列表建立完畢。

      glEndList();                   // Done Building The top Display List
  }

   貼圖紋理的代碼和之前教程里的代碼是一樣的。我們需要一個可以貼在立方體上的紋理。我決定使用mipmapping處理讓紋理看上去光滑,因為我討厭看見像素點。紋理的文件名是“cube.bmp”,存放在data目錄下。

  if (TextureImage[0]=LoadBMP("Data/Cube.bmp"))      // Load The Bitmap

   改變窗口大小的代碼和第六課是一樣的。
   初始化的代碼只有一點改變,加入了一行BuildList()。請注意代碼的順序,先讀入紋理,然后建立顯示列表,這樣當我們建立顯示列表的時候就可以將紋理貼到立方體上了。

  int InitGL(GLvoid)                    // All Setup For OpenGL Goes Here
  {
       if (!LoadGLTextures())
              // Jump To Texture Loading Routine
      {
           return FALSE;
               // If Texture Didn’t Load Return FALSE
      }
       BuildLists();
                   // Jump To The Code That Creates Our Display Lists
      glEnable(GL_TEXTURE_2D);             // Enable Texture Mapping
      glShadeModel(GL_SMOOTH);             // Enable Smooth Shading
      glClearColor(0.0f, 0.0f, 0.0f, 0.5f);       // Black Background
      glClearDepth(1.0f);                // Depth Buffer Setup
      glEnable(GL_DEPTH_TEST);             // Enables Depth Testing
      glDepthFunc(GL_LEQUAL);              // The Type Of Depth Testing To Do

   接下來的三行使燈光有效。Light0一般來說是在顯卡中預先定義過的,如果Light0不工作,把下面那行注釋掉好了。
   最后一行的GL_COLOR_MATERIAL使我們可以用顏色來貼紋理。如果沒有這行代碼,紋理將始終保持原來的顏色,glColor3f(r,g,b)就沒有用了??傊@行代碼是很有用的。

      glEnable(GL_LIGHT0);               // Quick And Dirty Lighting (Assumes Light0 Is Set Up)
      glEnable(GL_LIGHTING);              // Enable Lighting
      glEnable(GL_COLOR_MATERIAL);           // Enable Material Coloring

   最后,設置投影校正,返回TURE。

      glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// Nice Perspective Correction
      return TRUE;                   // Initialization Went OK

   現在來看繪畫?拇搿6允掖永炊際嗆芡反蟮?,脫]衧in,沒有cos,但仍然看起來很奇怪(相信讀者不會覺得頭大)。首先,按慣例,清除屏幕和深度緩沖。
   然后捆綁紋理到立方體上(我知道捆綁這個詞不太專業,但是……)。可以將這行放在顯示列表里,但放在外邊,就可以在任何時候修改它。

  int DrawGLScene(GLvoid)                  // Here’s Where We Do All The Drawing
  {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Clear The Screen And The Depth Buffer
      glBindTexture(GL_TEXTURE_2D, texture[0]);       // Select The Texture

   現在到了真正有趣的地方了。用一個循環,循環變量用于改變Y軸位置,在Y軸上畫5個立方體,所以用從1到5的循環。

      for (yloop=1;yloop<6;yloop++)           // Loop Through The Y Plane
      {

   另外用一個循環,循環變量用于改變X軸位置。每行上的立方體數目取決于行數,所以循環方式如下。

          for (xloop=0;xloop< yloop;xloop++)    // Loop Through The X Plane
          {
               glLoadIdentity();
         // Reset The View

   下邊的代碼是移動和旋轉當前坐標系到需要畫出立方體的位置。(原文有很羅嗦的一大段,相信大家的數學功底都不錯,就不翻譯了)

              glLoadIdentity();         // Reset The View
               // Position The Cubes On The Screen

              glTranslatef(1.4f+(float(xloop)*2.8f)-(float(yloop)*1.4f),((6.0f-float(yloop))*2.4f)-7.0f,-20.0f);

               glRotatef(45.0f-(2.0f*yloop)+xrot,1.0f,0.0f,0.0f);
  // Tilt The Cubes Up And Down
              glRotatef(45.0f+yrot,0.0f,1.0f,0.0f);  // Spin Cubes Left And Right

   然后在正式畫盒子之前設置顏色。每個盒子用不同的顏色。

              glColor3fv(boxcol[yloop-1]);   // Select A Box Color

   好了,顏色設置好了?,F在需要做的就是畫出盒子。不用寫出畫多邊形的代碼,只需要用glCallList(box)命令調用顯示列表。盒子將會用glColor3fv()所設置的顏色畫出來。

              glCallList(box);         // Draw The Box

   然后用另外的顏色畫頂部。搞定。

              glColor3fv(topcol[yloop-1]);   // Select The Top Color

              glCallList(top);         // Draw The Top
          }
       }
       return TRUE;
                   // Jump Back
  }

   下面的代碼是鍵盤控制的一些東西。

              SwapBuffers(hDC);       // Swap Buffers (Double Buffering)
              if (keys[VK_LEFT])       // Left Arrow Being Pressed?
               {
  ??                 yrot-=0.2f;
      // If So Spin Cubes Left
              }
              if (keys[VK_RIGHT])      // Right Arrow Being Pressed?
              {
                   yrot+=0.2f;
      // If So Spin Cubes Right
              }
               if (keys[VK_UP])
        // Up Arrow Being Pressed?
              {
                   xrot-=0.2f;
      // If So Tilt Cubes Up
               }
              if (keys[VK_DOWN])       // Down Arrow Being Pressed?
              {
                    xrot+=0.2f;
      // If So Tilt Cubes Down
               }

   與以前的指南一樣,我們要確認窗口頂部標題的正確。

              if (keys[VK_F1])       // Is F1 Being Pressed?
              {
                    keys[VK_F1]=FALSE;
   // If So Make Key FALSE
                  KillGLWindow();    // Kill Our Current Window
                  fullscreen=!fullscreen;// Toggle Fullscreen / Windowed Mode
                   // Recreate Our OpenGL Window
                  if (!CreateGLWindow("NeHe’s Display List Tutorial",
                          640,480,16,fullscreen))

                  {
                        return 0;
   // Quit If Window Was Not Created
                    }
               }
           }
       }
   }

posted on 2007-12-13 11:10 sdfasdf 閱讀(577) 評論(0)  編輯 收藏 引用 所屬分類: OPENGL
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区制服诱惑| 欧美在线一级视频| 欧美久久视频| 久久亚洲精品一区二区| 小处雏高清一区二区三区| 9久草视频在线视频精品| 亚洲日本电影| 久久综合色综合88| 久久亚洲国产精品一区二区| 一本色道久久88亚洲综合88| 亚洲国产日韩精品| 日韩亚洲视频| 欧美一级日韩一级| 久久综合九色欧美综合狠狠| 欧美aⅴ99久久黑人专区| 欧美日韩一区视频| 国产乱理伦片在线观看夜一区| 国产一区二区三区网站 | 理论片一区二区在线| 蜜桃av一区二区三区| 一本在线高清不卡dvd| 久久久噜噜噜久久中文字幕色伊伊 | 久久国产高清| 欧美大胆成人| 欧美一区二区免费| 国产精品久久久久久久久久免费看| 欧美国产免费| 狠狠色2019综合网| 99精品国产热久久91蜜凸| 久久在线免费| 性欧美videos另类喷潮| 国产精品免费视频xxxx| 亚洲网站视频福利| 免费久久99精品国产| 欧美在线视屏| 国产欧美日韩在线视频| 亚洲欧美综合v| 欧美激情综合五月色丁香小说| 欧美一区二区三区免费视频| 国产精品高潮呻吟视频| 国产精品国产三级国产专播精品人 | 亚洲欧洲精品一区| 亚洲一级高清| 亚洲观看高清完整版在线观看| 欧美中文字幕视频| 亚洲图片在线| 国产乱码精品一区二区三区忘忧草 | 久久五月激情| 欧美黄色日本| 亚洲电影成人| 99riav1国产精品视频| 欧美一区二区日韩一区二区| 美女脱光内衣内裤视频久久影院| 最新国产拍偷乱拍精品| 在线观看亚洲视频啊啊啊啊| 欧美中文字幕| 母乳一区在线观看| 国产欧美一区二区三区在线看蜜臀| 久久精品国产亚洲aⅴ| 亚洲美女毛片| 欧美一区二区女人| 久久午夜国产精品| 国产精品午夜在线观看| 国内精品亚洲| 亚洲无玛一区| 欧美不卡视频一区发布| 中文av一区二区| 亚洲高清三级视频| 日韩亚洲在线观看| 欧美亚洲三区| 久久手机免费观看| 国产综合色在线视频区| 国产午夜精品福利| 亚洲精品在线免费观看视频| 欧美激情第三页| 中文av一区特黄| 国产色爱av资源综合区| 日韩视频在线你懂得| 99国产精品| 欧美精品自拍| 亚洲视频欧洲视频| 久久精品毛片| 一区二区三区在线观看视频| 欧美在线日韩精品| 久久综合亚洲社区| 99国产欧美久久久精品| 欧美日韩综合一区| 欧美在线免费观看| 亚洲国产精品久久精品怡红院 | 亚洲精品综合| 久久综合激情| 亚洲福利在线观看| 正在播放亚洲一区| 国产欧美一区二区三区沐欲| 久久久久久久999| 精品福利电影| 99精品欧美一区二区三区综合在线| 亚洲免费观看视频| 亚洲欧美国产精品桃花 | 亚洲午夜精品久久| 另类天堂av| 欧美在线观看一二区| 欧美日韩激情网| 久久久激情视频| 亚洲欧美日韩在线播放| 亚洲人久久久| 久久综合色播五月| 欧美影院成人| 国产日韩av一区二区| 亚洲中无吗在线| 久久国产精品久久久久久| 蜜臀久久99精品久久久久久9| 亚洲国产综合在线看不卡| 久久亚洲精品网站| 欧美日本不卡视频| 久久综合久久综合久久综合| 欧美日韩亚洲一区二区三区| 久久免费黄色| 亚洲激精日韩激精欧美精品| 午夜精品一区二区三区四区| 欧美在线观看视频一区二区| 正在播放亚洲一区| 亚洲三级国产| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 亚洲欧美综合v| 亚洲三级电影全部在线观看高清| 亚洲视频在线观看| 亚洲小说春色综合另类电影| 亚洲综合另类| 久久成人人人人精品欧| 狂野欧美性猛交xxxx巴西| 亚洲第一狼人社区| 久久亚洲欧洲| av成人天堂| 另类专区欧美制服同性| 99国产精品国产精品久久| 亚洲网站视频| 欧美久久久久久久久| 国产色婷婷国产综合在线理论片a| 国产亚洲精品bt天堂精选| 91久久久久久久久| 麻豆精品精华液| 亚洲女人av| 国产精品vvv| 一区二区三区精品| 欧美激情中文字幕乱码免费| 欧美伊久线香蕉线新在线| 欧美日韩国产不卡| 亚洲经典自拍| 牛夜精品久久久久久久99黑人| 亚洲无线视频| 欧美调教视频| 亚洲欧美日韩在线播放| 99re热精品| 欧美视频专区一二在线观看| 91久久精品一区二区别| 亚洲第一黄网| 欧美大片在线观看| 亚洲免费不卡| 一级成人国产| 国产精品美女久久久浪潮软件| aa级大片欧美三级| 中日韩高清电影网| 欧美日韩亚洲一区二区三区四区| 99精品国产在热久久下载| 有码中文亚洲精品| 老司机67194精品线观看| 久久久国产91| 在线播放一区| 亚洲精品一线二线三线无人区| 欧美国产三区| 午夜视频一区在线观看| 久久久在线视频| 日韩一区二区免费高清| 一本色道久久综合狠狠躁篇怎么玩 | 老妇喷水一区二区三区| 亚洲国产精品久久久久久女王| 欧美一级电影久久| 久久香蕉国产线看观看网| 亚洲卡通欧美制服中文| 欧美一区二区三区在线看| 亚洲黄色免费网站| 欧美一区二区三区另类| 亚洲图片欧洲图片日韩av| 久久天堂成人| 久久久久久久久一区二区| 欧美日韩综合另类| 亚洲欧洲一区二区三区久久| 黄色精品在线看| 欧美一区二区三区久久精品茉莉花 | 久久亚洲综合色| 亚洲午夜精品一区二区| 可以看av的网站久久看| 久久久91精品| 韩国亚洲精品| 久久综合精品国产一区二区三区| 欧美一区二区日韩一区二区| 国产精品久久国产精麻豆99网站| 亚洲精品国产精品乱码不99| 老**午夜毛片一区二区三区|