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

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

常用鏈接

留言簿(48)

我參與的團隊

搜索

  •  

積分與排名

  • 積分 - 402520
  • 排名 - 59

最新評論

閱讀排行榜

評論排行榜

 這一課我會教您如何使用三種不同的紋理濾波方式。教您如何使用鍵盤來移動場景中的對象,還會教您在OpenGL場 景中應用簡單的光照。這一課包含了很多內容,如果您對前面的課程有疑問的話,先回頭復習一下。進入后面的代碼之前,很好的理解基礎知識十分重要。我們還是 在第一課的代碼上加以修改。跟以前不一樣的是,只要有任何大的改動,我都會寫出整段代碼。程序開始,我們先加上幾個新的變量。

  #include <windows.h>                    // Windows的頭文件
  #include <stdio.h>                     // 標準輸入/輸出庫的頭文件 (新增)
  #include <gl\\gl.h>                     // OpenGL32庫的頭文件
  #include <gl\\glu.h>                    // GLu32庫的頭文件
  #include <gl\\glaux.h>                   // GLaux庫的頭文件

  HGLRC hRC=NULL;                      // 永久著色描述表
  HDC hDC=NULL;                       // 私有GDI設備描述表
  HWND hWnd=NULL;                      // 保存我們的窗口句柄
  HINSTANCE hInstance;                    // 保存程序的實例

  bool keys[256];                      // 用于鍵盤例程的數組
  bool active=TRUE;                     // 窗口的活動標志,缺省為TRUE
  bool fullscreen=TRUE;                   // 全屏標志缺省設定成全屏模式

   下面幾行是新的。我們增加三個布爾變量。light變量跟蹤光照是否打開。變量lpfp用來存儲‘L’和‘F’鍵是否按下的狀態。后面我會解釋這些變量的重要性。現在,先放在一邊吧。

  BOOL light;                   ?    ?// 光源的開/關
  BOOL lp;                          // L鍵按下了么?
  BOOL fp;                          // F鍵按下了么?

   現在設置5個變量來控制繞x軸和y軸旋轉角度的步長,以及繞x軸和y軸的旋轉速度。另外還創建了一個z變量來控制進入屏幕深處的距離。

  GLfloat xrot;                       // X 旋轉
  GLfloat yrot;                       // Y 旋轉
  GLfloat xspeed;                      // X 旋轉速度
  GLfloat yspeed;                      // Y 旋轉速度

  GLfloat z=-5.0f;                      // 深入屏幕的距離

接著設置用來創建光源的數組。我們將使用兩種不同的光。第一種稱為環境光。環境光來自于四面八方。所有場景中的對象都處于環境光的照射中。第二種類型的光 源叫做漫射光。漫射光由特定的光源產生,并在您的場景中的對象表面上產生反射。處于漫射光直接照射下的任何對象表面都變得很亮,而幾乎未被照射到的區域就 顯得要暗一些。這樣在我們所創建的木板箱的棱邊上就會產生的很不錯的陰影效果。
   創建光源的過程和顏色的創建完全一致。前三個參數分別是RGB三色分量,最后一個是alpha通道參數。
   因此,下面的代碼我們得到的是半亮(0.5f)的白色環境光。如果沒有環境光,未被漫射光照到的地方會變得十分黑暗。

  GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };    // 環境光參數 (新增)

   下一行代碼我們生成最亮的漫射光。所有的參數值都取成最大值1.0f。它將照在我們木板箱的前面,看起來挺好。

  GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };    // 漫射光參數 (新增)

最后我們保存光源的位置。前三個參數和glTranslate中的一樣。依次分別是XYZ軸上的位移。由于我們想要光線直接照射在木箱的正面,所以XY軸 上的位移都是0.0f。第三個值是Z軸上的位移。為了保證光線總在木箱的前面,所以我們將光源的位置朝著觀察者(就是您哪。)挪出屏幕。我們通常將屏幕也 就是顯示器的屏幕玻璃所處的位置稱作Z軸的0.0f點。所以Z軸上的位移最后定為2.0f。假如您能夠看見光源的話,它就浮在您顯示器的前方。當然,如果 木箱不在顯示器的屏幕玻璃后面的話,您也無法看見箱子。最后一個參數取為1.0f。這將告訴OpenGL這里指定的坐標就是光源的位置,以后的教程中我會多加解釋。

  GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f };    // 光源位置 ( 新增 )

  filter變 量跟蹤顯示時所采用的紋理類型。第一種紋理(texture 0)使用gl_nearest(不光滑)濾波方式構建。第二種紋理(texture 1)使用gl_linear(線性濾波)方式,離屏幕越近的圖像看起來就越光滑。第三種紋理 (texture 2)使用mipmapped濾波方式,這將創建一個外觀十分優秀的紋理。根據我們的使用類型,filter變量的值分別等于0,1或2。下面我們從第一種紋理開始。
   GLuint texture[3]為三種不同紋理分配儲存空間。它們分別位于在texture[0]、texture[1]、texture[2]中。

  GLuint filter;                       // 濾波類型
  GLuint texture[3];                     // 3種紋理的儲存空間
  LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);   // WndProc定義

   現在載入一個位圖,并用它創建三種不同的紋理。這一課使用glaux輔助庫來載入位圖,因此在編譯時您應該確認是否包含了glaux庫。我知道Delphi和VC++都包含了glaux庫,但別的語言不能保證都有。(譯者glaux是OpenGL輔助庫,根據OpenGL的跨平臺特性,所有平臺上的代碼都應通用。但輔助庫不是正式的OpenGL標準庫,沒有出現在所有的平臺上。但正好在Win32平臺上可用。呵呵,BCB當然也沒問題了。)這里我只對新增的代碼做注解。如果您對某行代碼有疑問的話,請查看教程六。那一課很詳細的解釋了載入、創建紋理的內容。
   在上一段代碼后面及ReSizeGLScene()之前的位置,我們增加了下面的代碼。這和第六課中載入位圖的代碼幾乎相同。

  AUX_RGBImageRec *LoadBMP(char *Filename)          // 載入位圖
  {
       FILE *File=NULL;
                  // 文件句柄
      if (!Filename)                   // 確認文件名已初始化
      {
           return NULL;
                // 沒有返回 NULL
      }
       File=fopen(Filename,"r");
             // 檢查文件是否存在
      if (File)                     // 存在么?
      {
           fclose(File); 
              // 關閉文件句柄
          return auxDIBImageLoad(Filename);     // 載入位圖并返回一個指針
      }
      return NULL;                    // 載入失敗返回 NULL
  }

   這段代碼調用前面的代碼載入位圖,并將其轉換成3個紋理。Status變量跟蹤紋理是否已載入并被創建了。

  int LoadGLTextures()                    // 載入位圖并轉換成紋理
  {
       int Status=FALSE;
                  // Status 指示器
      AUX_RGBImageRec *TextureImage[1];         // 創建紋理的存儲空間
      memset(TextureImage,0,sizeof(void *)*1);      // 將指針設為 NULL

現在載入位圖并轉換成紋理。TextureImage[0]=LoadBMP("Data/Crate.bmp")調用我們的LoadBMP()函數。 Data目錄下的“Crate.bmp”將被載入。如果一切正常,圖像數據將存放在TextureImage[0]。Status變量被設為TRUE,我 們將開始創建紋理。

      // 載入位圖,檢查有錯,或位圖不存在的話退出。
      if (TextureImage[0]=LoadBMP("Data/Crate.bmp"))
       {
           Status=TRUE;
                // Status 設為 TRUE

   現在我們已經將圖像數據載入TextureImage[0]。我們將用它來創建3個紋理。下面的行告訴OpenGL我們要創建三個紋理,它們將存放在texture[0]、texture[1]、texture[2] 中。

          glGenTextures(3, &texture[0]);       // 創建紋理

第六課中我們使用了線性濾波的紋理貼圖。這需要機器有相當高的處理能力,但它們看起來很不錯。這一課中,我們接著要創建的第一種紋理使用 GL_NEAREST方式。從原理上講,這種方式沒有真正進行濾波。它只占用很小的處理能力,看起來也很差。唯一的好處是這樣我們的工程在很快和很慢的機 器上都可以正常運行。
您會注意到我們在MIN和MAG時都采用了GL_NEAREST,你可以混合使用GL_NEAREST和GL_LINEAR。紋理看起來效果會好些,但我 們更關心速度,所以全采用低質量貼圖。MIN_FILTER在圖像繪制時小于貼圖的原始尺寸時采用。MAG_FILTER在圖像繪制時大于貼圖的原始尺寸 時采用。

          // 創建 Nearest 濾波貼圖
          glBindTexture(GL_TEXTURE_2D, texture[0]);
           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
// (新增)
          glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);// (新增)
          glTexImage2D(GL_TEXTURE_2D, 0, 3,
               TextureImage[0]->sizeX, TextureImage[0]->sizeY,
               0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

   下個紋理與第六課的相同,線性濾波。唯一的不同是這次放在了texture[1]中。因為這是第二個紋理。如果放在texture[0]中的話,他將覆蓋前面創建的GL_NEAREST紋理。

          // 創建線性濾波紋理
          glBindTexture(GL_TEXTURE_2D, texture[1]);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
           glTexImage2D(GL_TEXTURE_2D, 0, 3,
               TextureImage[0]->sizeX, TextureImage[0]->sizeY,
               0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

下面是創建紋理的新方法:Mip-mapping(紋理細化)。您可能會注意到當圖像在屏幕上變得很小的時候,很多細節將會丟失。剛才還很不錯的圖案變得 很難看。當您告訴OpenGL創建一個mipmapped的紋理后,OpenGL將嘗試創建不同尺寸的高質量紋理。當您向屏幕繪制一個mipmapped 紋理的時候,OpenGL將選擇它已經創建的外觀最佳的紋理(帶有更多細節)來繪制,而不僅僅是縮放原先的圖像(這將導致細節丟失)。
我曾經說過有辦法可以繞過OpenGL對紋理寬度和高度所加的限制 — 64、128、256,等等。辦法就是 gluBuild2DMipmaps。據我的發現,您可以使用任意的位圖來創建紋理。OpenGL將自動將它縮放到正常的大小。因為是第三個紋理,我們將 它存到texture[2]。這樣本課中的三個紋理全都創建好了。

          // 創建 MipMapped 紋理
          glBindTexture(GL_TEXTURE_2D, texture[2]);
           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
// (新增)

下面一行生成mipmapped紋理。我們使用三種顏色(紅,綠,藍)來生成一個2D紋理。TextureImage[0]->sizeX 是位圖寬度,extureImage[0]->sizeY是位圖高度,GL_RGB意味著我們依次使用RGB色彩。 GL_UNSIGNED_BYTE意味著紋理數據的單位是字節。TextureImage[0]->data指向我們創建紋理所用的位圖。

          gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
               TextureImage[0]->sizeX, TextureImage[0]->sizeY,
               GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
  // ( 新增 )
      }

   現在釋放用來存放位圖數據的內存。我們先查看位圖數據是否存放在TextureImage[0]中,如果有,刪掉。然后釋放位圖結構以確保內存被釋放。

      if (TextureImage[0])                // 紋理是否存在
      {
           if (TextureImage[0]->data)
         // 紋理圖像是否存在
          {
               free(TextureImage[0]->data);
    // 釋放紋理圖像占用的內存
          }
           free(TextureImage[0]);
           // 釋放圖像結構
      }

   最后我們返回status變量。如果一切OK,status變量的值為TRUE。否則為FALSE。

      return Status;                  // 返回 Status 變量
  }

   接著應該載入紋理并初始化OpenGL設置了。InitGL函數的第一行使用上面的代碼載入紋理。創建紋理之后,我們調用glEnable(GL_TEXTURE_2D)啟用2D紋理映射。陰影模式設為平滑陰影(smooth shading)。背景色設為黑色,我們啟用深度測試,然后我們啟用優化透視計算。

  int InitGL(GLvoid)                    // 此處開始對OpenGL進行所有設置
  {
       if (!LoadGLTextures())
              // 跳轉到紋理載入例程
      {
           return FALSE;
               // 如果不能載入紋理返回 FALSE
      }

      glEnable(GL_TEXTURE_2D);             // 啟用紋理映射
      glShadeModel(GL_SMOOTH);             // 啟用陰影平滑
      glClearColor(0.0f, 0.0f, 0.0f, 0.5f);       // 黑色背景
      glClearDepth(1.0f);                // 深度緩存設置
      glEnable(GL_DEPTH_TEST);             // 啟用深度測試
      glDepthFunc(GL_LEQUAL);              // 所作的深度測試類型
      glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// 高度優化的透視投影計算

   現在開始設置光源。下面下面一行設置環境光的發光量,光源light1開始發光。這一課的開始處我們我們將環境光的發光量存放在LightAmbient數組中。現在我們就使用此數組(半亮度環境光)。

      glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);  // 設置環境光

   接下來我們設置漫射光的發光量。它存放在LightDiffuse數組中(全亮度白光)。

      glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);  // 設置漫射光

   然后設置光源的位置。位置存放在 LightPosition 數組中(正好位于木箱前面的中心,X-0.0f,Y-0.0f,Z方向移向觀察者2個單位[位于屏幕外面])。

      glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // 光源位置

   最后,我們啟用一號光源。我們還沒有啟用GL_LIGHTING,所以您看不見任何光線。記住:只對光源進行設置、定位、甚至啟用,光源都不會工作。除非我們啟用GL_LIGHTING。

      glEnable(GL_LIGHT1);               // 啟用一號光源
      return TRUE;                   // 初始化 OK
  }

   下一段代碼繪制貼圖立方體。我只對新增的代碼進行注解。如果您對沒有注解的代碼有疑問,回頭看看第六課。

  int DrawGLScene(GLvoid)                  // 從這里開始進行所有的繪制
  {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 清除屏幕和深度緩存
      glLoadIdentity();                 // 重置當前的模型觀察矩陣

   下三行代碼放置并旋轉貼圖立方體。glTranslatef(0.0f,0.0f,z)將立方體沿著Z軸移動Z單位。glRotatef(xrot,1.0f,0.0f,0.0f)將立方體繞X軸旋轉xrot。glRotatef(yrot,0.0f,1.0f,0.0f)將立方體繞Y軸旋轉yrot

      glTranslatef(0.0f,0.0f,z);            // 移入/移出屏幕 z 個單位

      glRotatef(xrot,1.0f,0.0f,0.0f);          // 繞X軸旋轉
      glRotatef(yrot,0.0f,1.0f,0.0f);          // 繞Y軸旋轉

下一行與我們在第六課中的類似。有所不同的是,這次我們綁定的紋理是texture[filter],而不是上一課中的texture[0]。任何時候, 我們按下F鍵,filter的值就會增加。如果這個數值大于2,變量filter 將被重置為0。程序初始時,變量filter的值也將設為0。使用變量filter我們就可以選擇三種紋理中的任意一種。

      glBindTexture(GL_TEXTURE_2D, texture[filter]);  // 選擇由filter決定的紋理
      glBegin(GL_QUADS);                // 開始繪制四邊形

glNormal3f是這一課的新東西。Normal就是法線的意思,所謂法線是指經過面(多邊形)上的一點且垂直于這個面(多邊形)的直線。使用光源的 時候必須指定一條法線。法線告訴OpenGL這個多邊形的朝向,并指明多邊形的正面和背面。如果沒有指定法線,什么怪事情都可能發生:不該照亮的面被照亮 了,多邊形的背面也被照亮....。對了,法線應該指向多邊形的外側。
看著木箱的前面您會注意到法線與Z軸正向同向。這意味著法線正指向觀察者-您自己。這正是我們所希望的。對于木箱的背面,也正如我們所要的,法線背對著觀 察者。如果立方體沿著X或Y軸轉個180度的話,前側面的法線仍然朝著觀察者,背面的法線也還是背對著觀察者。換句話說,不管是哪個面,只要它朝著觀察者 這個面的法線就指向觀察者。由于光源緊鄰觀察者,任何時候法線對著觀察者時,這個面就會被照亮。并且法線越朝著光源,就顯得越亮一些。如果您把觀察點放到 立方體內部,你就會法線里面一片漆黑。因為法線是向外指的。如果立方體內部沒有光源的話,當然是一片漆黑。

          // 前側面
          glNormal3f( 0.0f, 0.0f, 1.0f);      // 法線指向觀察者
          glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);// Point 1 (Front)
          glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);// Point 2 (Front)
          glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Point 3 (Front)
          glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Point 4 (Front)

          // 后側面
          glNormal3f( 0.0f, 0.0f,-1.0f);      // 法線背向觀察者
          glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);// Point 1 (Back)
          glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Point 2 (Back)
          glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Point 3 (Back)
          glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);// Point 4 (Back)

          // 頂面
          glNormal3f( 0.0f, 1.0f, 0.0f);     // 法線向上
          glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);// Point 1 (Top)
          glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Point 2 (Top)
          glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Point 3 (Top)
          glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);// Point 4 (Top)

          // 底面
          glNormal3f( 0.0f,-1.0f, 0.0f);     // 法線朝下
          glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);// Point 1 (Bottom)
          glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);// Point 2 (Bottom)
          glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Point 3 (Bottom)
          glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Point 4 (Bottom)

          // 右側面
          glNormal3f( 1.0f, 0.0f, 0.0f);    // 法線朝右
          glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);// Point 1 (Right)
          glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Point 2 (Right)
          glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Point 3 (Right)
          glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Point 4 (Right)

          // 左側面
          glNormal3f(-1.0f, 0.0f, 0.0f);    // 法線朝左
          glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);// Point 1 (Left)
          glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Point 2 (Left)
          glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Point 3 (Left)
          glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Point 4 (Left)
      glEnd();     ?            ?// 四邊形繪制結束

   下兩行代碼將xotyrot的旋轉值分別增加xspeedyspeed個單位。xspeedyspeed的值越大,立方體轉得就越快。

      xrot+=xspeed;                // xrot 增加 xspeed 單位
      yrot+=yspeed;                // yrot 增加 yspeed 單位
      return TRUE;
  }

現在轉入WinMain()主函數。我們將在這里增加開關光源、旋轉木箱、切換過濾方式以及將木箱移近移遠的控制代碼。在接近WinMain()函數結束 的地方你會看到SwapBuffers(hDC)這行代碼。然后就在這一行后面添加如下的代碼。代碼將檢查L鍵是否按下過。如果L鍵已按下,但lp的值不是false的話,意味著L鍵還沒有松開,這時什么都不會發生。

                      SwapBuffers(hDC);  // 交換緩存 (雙緩存)
                      if (keys[\’L\’] && !lp)// L 鍵已按下并且松開了?
                      {

   如果lp的值是false的話,意味著L鍵還沒按下,或者已經松開了,接著lp將被設為TRUE。同時檢查這兩個條件的原因是為了防止L鍵被按住后,這段代碼被反復執行,并導致窗體不停閃爍。
  lp設為true之后,計算機就知道L鍵按過了,我們則據此可以切換光源的開/關:布爾變量light控制光源的開關。
                           lp=TRUE;   // lp 設為 TRUE
                           light=!light;// 切換光源的 TRUE/FALSE

   下面幾行來檢查光源是否應該打開,并根據light變量的值。

                           if (!light) // 如果沒有光源
                           {
                                glDisable(GL_LIGHTING);
//禁用光源
                           }
                            else
     // Otherwise
                           {
                                glEnable(GL_LIGHTING);
//啟用光源
                           }
                        }

   下面的代碼查看是否松開了“L”鍵。如果松開,變量lp將設為false。這意味著“L”鍵沒有按下。如果不作此檢查,光源第一次打開之后,就無法再關掉了。計算機會以為“L”鍵一直按著呢。

                      if (!keys[\’L\’])   // L鍵松開了么?
                      {
                            lp=FALSE;
  // 若是,則將lp設為FALSE
                      }

然后對“F”鍵作相似的檢查。如果有按下“F”?⑶搖癋”鍵沒有處于按著的狀態或者它就從沒有按下過,將變量fp設為true。這意味著這個鍵正被按著 呢。接著將filter變量加一。如果filter變量大于2(因為這里我們的使用的數組是texture[3],大于2的紋理不存在),我們重置 filter變量為0。

                      if (keys[\’F\’] && !fp)// F鍵按下了么?
                      {
                            fp=TRUE;
   // fp 設為 TRUE
                          filter+=1;  // filter的值加一
                          if (filter>2)// 大于2了么?
                          {
                                filter=0;
 // 若是重置為0
                          }
                       }
                       if (!keys[\’F\’])
   // F鍵放開了么?
                      {
                            fp=FALSE;
  // 若是fp設為FALSE
                      }

   這四行檢查是否按下了PageUp鍵。若是的話,減少z變量的值。這樣DrawGLScene函數中包含的glTranslatef(0.0f,0.0f,z)調用將使木箱離觀察者更遠一點。

                      if (keys[VK_PRIOR]) // PageUp按下了?
                      {
                            z-=0.02f;
 // 若按下,將木箱移向屏幕內部。
                      }

   接著四行檢查PageDown鍵是否按下,若是的話,增加z變量的值。這樣DrawGLScene函數中包含的glTranslatef(0.0f,0.0f,z)調用將使木箱向著觀察者移近一點。

                      if (keys[VK_NEXT])  // PageDown按下了么?
                      {
                            z+=0.02f;
  //若按下的話,將木箱移向觀察者。
                      }

   現在檢查方向鍵。按下左右方向鍵xspeed相應減少或增加。按下上下方向鍵yspeed相應減少或增加。記住在以后的教程中如果xspeedyspeed的值增加的話,立方體就轉的更快。如果一直按著某個方向鍵,立方體會在那個方向上轉的越快。

                      if (keys[VK_UP])    // Up方向鍵按下了么?
                      {
                            xspeed-=0.01f;
// 若是,減少xspeed
                      }
                       if (keys[VK_DOWN])
   // Down方向鍵按下了么?
                      {
                            xspeed+=0.01f;
// 若是,增加xspeed
                      }
                       if (keys[VK_RIGHT]) 
 // Right方向鍵按下了么?
                      {
                            yspeed+=0.01f;
// 若是,增加yspeed
                      }
                       if (keys[VK_LEFT])
   // Left方向鍵按下了么?
                      {
                            yspeed-=0.01f;
// 若是, 減少yspeed
                      }

   像前幾課一樣,我們最后還需要更正窗體的標題。

                      if (keys[VK_F1])        // F1鍵按下了么?
                      {
                            keys[VK_F1]=FALSE;

                          KillGLWindow();    // 銷毀當前的窗口
                          fullscreen=!fullscreen;// 切換 全屏/窗口 模式
                           // 重建 OpenGL 窗口(修改)
                          if (!CreateGLWindow("NeHe\’s Textures, Lighting & Keyboard Tutorial",640,480,16,fullscreen))
                           {
                                return 0;
// 如果窗口未能創建,程序退出
                          }
                       }

                   }
               }
            }

      // 關閉
      KillGLWindow();                  // 銷毀窗口
      return (msg.wParam);                // 退出程序
  }

posted on 2007-12-11 18:10 sdfasdf 閱讀(707) 評論(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>
            夜色激情一区二区| 欧美18av| 欧美高清视频在线观看| 欧美在线短视频| 午夜久久美女| 久久精品二区三区| 久久在线免费观看| 欧美激情免费观看| 一本色道婷婷久久欧美| 一区二区三区日韩精品视频| 亚洲天堂av在线免费| 亚洲欧美国产日韩中文字幕| 欧美一区二区福利在线| 久久精品午夜| 久久一二三区| 国产精品初高中精品久久| 国产精品乱码一区二三区小蝌蚪| 国产模特精品视频久久久久| 国产主播精品在线| 亚洲精品黄色| 欧美一区激情视频在线观看| 裸体丰满少妇做受久久99精品| 欧美激情一区二区三区四区| 亚洲精品乱码久久久久久| 亚洲区国产区| 欧美中文字幕不卡| 欧美精品一区二区视频| 国产精品综合| 一本大道久久a久久精二百| 性色av一区二区怡红| 欧美成年人在线观看| 亚洲香蕉网站| 欧美黄色网络| 国外成人免费视频| 亚洲精品小视频| 欧美一区二区三区久久精品茉莉花 | 国产精品视频免费在线观看| 伊人色综合久久天天五月婷| 亚洲啪啪91| 久久国产黑丝| 欧美国产视频日韩| 亚洲一区www| 欧美精品久久久久久久久老牛影院| 国产亚洲精品久久久久婷婷瑜伽| 亚洲深夜福利视频| 亚洲国产一二三| 久久亚洲春色中文字幕久久久| 国产精品视频内| 一区二区高清视频在线观看| 欧美成人a视频| 久久久在线视频| 国产日韩欧美电影在线观看| 亚洲性xxxx| 亚洲精品一区二区三区婷婷月| 久久久久一区二区三区| 国产日韩一区二区| 先锋a资源在线看亚洲| 亚洲精品乱码久久久久久蜜桃91| 久久久久久久91| 影音先锋中文字幕一区| 免费成人在线观看视频| 久久频这里精品99香蕉| 亚洲第一网站| 亚洲第一成人在线| 欧美成年视频| 亚洲激情av在线| 欧美岛国在线观看| 嫩草国产精品入口| 亚洲人久久久| 亚洲看片免费| 国产精品捆绑调教| 久久av资源网站| 久久免费的精品国产v∧| 在线精品视频一区二区| 欧美激情第10页| 欧美人与性禽动交情品| 中国日韩欧美久久久久久久久| 亚洲精品五月天| 国产精品国产精品国产专区不蜜| 亚洲色图在线视频| 亚洲欧美日韩天堂| 狠狠久久综合婷婷不卡| 牛牛国产精品| 欧美日韩1080p| 欧美一区二区三区四区在线观看地址| 亚洲综合视频网| 亚洲第一黄网| 一本大道av伊人久久综合| 国产精品色婷婷久久58| 久久久欧美精品| 欧美精品一卡二卡| 亚洲一区在线直播| 久久精品视频在线免费观看| 亚洲日本激情| 亚洲欧美欧美一区二区三区| 国内揄拍国内精品少妇国语| 亚洲国产人成综合网站| 国产精品久久久久一区二区三区共| 久久久精品国产免费观看同学| 久久综合给合久久狠狠色| 亚洲精品免费在线播放| 亚洲一区二区三区乱码aⅴ| 好吊妞**欧美| aa级大片欧美| 亚洲黄色成人久久久| 亚洲在线一区二区三区| 亚洲国产一区视频| 香蕉久久久久久久av网站| 亚洲乱码国产乱码精品精天堂| 亚洲欧美日韩精品久久亚洲区| 最新国产成人av网站网址麻豆| 亚洲午夜av电影| 亚洲欧洲精品一区二区三区| 亚洲午夜精品一区二区| 亚洲精品在线三区| 欧美主播一区二区三区美女 久久精品人| 亚洲精品乱码久久久久久日本蜜臀| 欧美一区二区在线免费观看| 亚洲午夜女主播在线直播| 免费亚洲婷婷| 蜜臀av一级做a爰片久久| 国产精品资源在线观看| 一本久道久久综合狠狠爱| 亚洲欧洲一区二区在线播放| 欧美中文字幕| 久久久久国产一区二区| 国产精品日韩高清| 中文一区在线| 亚洲综合二区| 欧美性开放视频| 亚洲最新在线| 一区二区三区蜜桃网| 欧美jizz19hd性欧美| 欧美高清在线一区| 亚洲国产精品精华液2区45| 久久看片网站| 欧美成人国产一区二区| 在线国产欧美| 免费毛片一区二区三区久久久| 久久综合色一综合色88| 黄色亚洲精品| 亚洲欧美激情视频| 国产精品成人播放| 一区二区三区视频免费在线观看| 亚洲线精品一区二区三区八戒| 欧美日韩精品伦理作品在线免费观看 | 欧美大色视频| 最新国产精品拍自在线播放| 亚洲精品一级| 欧美日韩午夜剧场| 这里只有精品丝袜| 久久精品在线播放| 亚洲二区在线观看| 久久国产精品黑丝| 国产无遮挡一区二区三区毛片日本| 亚洲国产99| 一区二区三区日韩欧美精品| 欧美视频中文字幕在线| 亚洲网站在线看| 老**午夜毛片一区二区三区| 亚洲欧洲精品一区二区三区| 欧美视频三区在线播放| 亚洲欧美日韩一区二区三区在线观看 | 一本久久青青| 久久久免费精品| 亚洲青涩在线| 国产精品啊啊啊| 欧美在线观看一二区| 亚洲国产精品久久| 亚洲欧美日韩精品在线| 国产综合久久久久影院| 免费成人av在线| 亚洲欧美日韩国产精品| 另类图片国产| 亚洲宅男天堂在线观看无病毒| 黄色av成人| 欧美亚洲第一页| 免费欧美日韩| 欧美亚洲免费在线| 亚洲国产片色| 另类天堂av| 久久国产精品久久国产精品 | 国产欧美日韩在线观看| 欧美mv日韩mv国产网站| 亚洲综合欧美日韩| 亚洲精品久久久久久久久久久久 | 亚洲激情在线| 久久久久天天天天| 亚洲一区二区三区免费观看| 好吊一区二区三区| 国产精品免费福利| 欧美激情一区二区三区全黄 | 亚洲精品综合| 欧美ab在线视频| 香蕉国产精品偷在线观看不卡| 亚洲激情小视频| 在线不卡中文字幕播放| 国产日韩欧美成人| 欧美三级视频| 欧美日韩18|