亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

NeHe的opengl教程delphi版(7)----濾波

2019-11-18 18:32:55
字體:
來源:轉載
供稿:網友
 

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

首先我們還要加進SysUtils單元和Glaux單元。
}

Uses
   SysUtils,
   opengl,
   windows,
   Messages,
   Glaux In '../../GLAUX/Glaux.pas';

   //下面幾行是增加新的變量。

   //我們增加三個布爾變量。
   // light 變量跟蹤光照是否打開。
   //變量lp和fp用來存儲'L' 和'F'鍵是否按下的狀態。
   //后面我會解釋這些變量的重要性?,F在,先放在一邊吧。
   light            : Boolean;          // 光源的開/關
   lp               : Boolean;          // L鍵按下了么?
   fp               : Boolean;          // F鍵按下了么?

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

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

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

   //因此,下面的代碼我們得到的是半亮(0.5f)的白色環境光。
   //如果沒有環境光,未被漫射光照到的地方會變得十分黑暗。
   LightAmbient     : Array[0..3] Of GLfloat = (0.5, 0.5, 0.5, 1.0);  //環境光參數 ( 新增 )
   //下一行代碼我們生成最亮的漫射光。
   //所有的參數值都取成最大值1.0f。
   //它將照在我們木板箱的前面,看起來挺好。
   LightDiffuse     : Array[0..3] Of GLfloat = (1.0, 1.0, 1.0, 1.0);  // 漫射光參數 ( 新增 )
   //最后我們保存光源的位置。
   //前三個參數和glTranslate中的一樣。
   //依次分別是XYZ軸上的位移。
   //由于我們想要光線直接照射在木箱的正面,所以XY軸上的位移都是0.0。
   //第三個值是Z軸上的位移。
   //為了保證光線總在木箱的前面,
   //所以我們將光源的位置朝著觀察者(就是您哪。)挪出屏幕。
   //我們通常將屏幕也就是顯示器的屏幕玻璃所處的位置稱作Z軸的0.0點。
   //所以Z軸上的位移最后定為2.0。
   //假如您能夠看見光源的話,它就浮在您顯示器的前方。
   //當然,如果木箱不在顯示器的屏幕玻璃后面的話,您也無法看見箱子。
   //『譯者注:我很欣賞NeHe的耐心。
   //說真的有時我都打煩了,這么簡單的事他這么廢話干嘛?
   //但如果什么都清楚,您還會翻著這樣的頁面看個沒完么?』
   //最后一個參數取為1.0f。
   //這將告訴OpenGL這里指定的坐標就是光源的位置,以后的教程中我會多加解釋。
   LightPosition    : Array[0..3] Of GLfloat = (0.0, 0.0, 2.0, 1.0);  // 光源位置 ( 新增 )

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

   filter           : GLuint;           // 濾波類型
   texture          : Array[0..2] Of GLuint; // 3種紋理的儲存空間

PRocedure glGenTextures(n: GLsizei; Var textures: GLuint); stdcall; external
   opengl32;

Procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external
   opengl32;

Function gluBuild2DMipmaps(target: GLenum; components, width, height: GLint;
   format, atype: GLenum; data: Pointer): Integer; stdcall; external glu32 name
   'gluBuild2DMipmaps';

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

Function LoadBmp(filename: pchar): PTAUX_RGBImageRec;
Var
   BitmapFile       : Thandle;          // 文件句柄
Begin
   If Filename = '' Then                // 確保文件名已提供。
      result := Nil;                    // 如果沒提供,返回 NULL
   BitmapFile := FileOpen(Filename, fmOpenWrite); //嘗試打開文件
   If BitmapFile > 0 Then               // 文件存在么?
      Begin
         FileClose(BitmapFile);         // 關閉句柄
         result := auxDIBImageLoadA(filename); //載入位圖并返回指針
      End
   Else
      result := Nil;                    // 如果載入失敗,返回NiL。
End;

Function LoadTexture: boolean;          // 載入位圖并轉換成紋理
Var
   Status           : boolean;          // Status 指示器
   TextureImage     : Array[0..1] Of PTAUX_RGBImageRec; // 創建紋理的存儲空間
Begin
   Status := false;
   ZeroMemory(@TextureImage, sizeof(TextureImage)); // 將指針設為 NULL
   TextureImage[0] := LoadBMP('Walls.bmp');
   If TextureImage[0] <> Nil Then
      Begin
         Status := TRUE;                // 將 Status 設為 TRUE
         glGenTextures(1, 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]);  // 使用來自位圖數據生成 的典型紋理
         // 生成紋理
         glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
            TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
            TextureImage[0].data);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  // 線形濾波
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  // 線形濾波

         //下面是創建紋理的新方法。 Mipmapping!
         //『譯者注:這個詞的中文我翻不出來,不過沒關系??赐赀@一段,您就知道意思最重要?!?BR>         //您可能會注意到當圖像在屏幕上變得很小的時候,很多細節將會丟失。
         //剛才還很不錯的圖案變得很難看。當您告訴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 是位圖寬度,
         //TextureImage[0].sizeY 是位圖高度,
         //(====不知為什么,delphi下這個函數沒有height這個參數,
         //但是幫助中卻有,不知delphi再搞什么,郁悶ing......
         //最后我在前面自己寫了一個gluBuild2DMipmaps,
         //來載入glu32.dll中的gluBuild2DMipmaps函數=====)
         //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);      //(新增)  }
      End;
   If assigned(TextureImage[0]) Then    // 紋理是否存在
      If assigned(TextureImage[0].data) Then // 紋理圖像是否存在
         TextureImage[0].data := Nil;   // 釋放紋理圖像占用的內存
   TextureImage[0] := Nil;              // 釋放圖像結構
   result := Status;                    // 返回 Status
End;

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

Procedure glInit();                     // 此處開始對OpenGL進行所有設置
Begin
   If (Not LoadTexture) Then            // 調用紋理載入子例程
      exit;                             // 如果未能載入,退出

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

   //現在開始設置光源。下面下面一行設置環境光的發光量,
   //光源light1開始發光。
   //這一課的開始處我們我們將環境光的發光量存放在LightAmbient數組中。
   //現在我們就使用此數組(半亮度環境光)。
   glLightfv(GL_LIGHT1, GL_AMBIENT, @LightAmbient[0]); // 設置環境光
   //接下來我們設置漫射光的發光量。它存放在LightDiffuse數組中(全亮度白光)。
   glLightfv(GL_LIGHT1, GL_DIFFUSE, @LightDiffuse[0]); // 設置漫射光
   //然后設置光源的位置。
   //位置存放在 LightPosition 數組中
   //(正好位于木箱前面的中心,X-0.0,Y-0.0,Z方向移向觀察者2個單位<位于屏幕外面>)。
   glLightfv(GL_LIGHT1, GL_POSITION, @LightPosition); // 光源位置
   //最后,我們啟用一號光源。我們還沒有啟用GL_LIGHTING,
   //所以您看不見任何光線。
   //記?。褐粚庠催M行設置、定位、甚至啟用,光源都不會工作。
   //除非我們啟用GL_LIGHTING。
   glEnable(GL_LIGHT1);                 // 啟用一號光源

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

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

   //下三行代碼放置并旋轉貼圖立方體。
   //glTranslatef(0.0,0.0,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.0, 0.0, z);           // 移入/移出屏幕 z 個單位
   glRotatef(xrot, 1.0, 0.0, 0.0);      // 繞X軸旋轉
   glRotatef(yrot, 0.0, 1.0, 0.0);      // 繞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.0, 0.0, 1.0);           // 法線指向觀察者
   glTexCoord2f(0.0, 0.0);
   glVertex3f(-1.0, -1.0, 1.0);         // 紋理和四邊形的左下
   glTexCoord2f(1.0, 0.0);
   glVertex3f(1.0, -1.0, 1.0);          // 紋理和四邊形的右下
   glTexCoord2f(1.0, 1.0);
   glVertex3f(1.0, 1.0, 1.0);           // 紋理和四邊形的右上
   glTexCoord2f(0.0, 1.0);
   glVertex3f(-1.0, 1.0, 1.0);          // 紋理和四邊形的左上
   // 后面
   glNormal3f(0.0, 0.0, -1.0);          // 法線背向觀察者
   glTexCoord2f(1.0, 0.0);
   glVertex3f(-1.0, -1.0, -1.0);        // 紋理和四邊形的右下
   glTexCoord2f(1.0, 1.0);
   glVertex3f(-1.0, 1.0, -1.0);         // 紋理和四邊形的右上
   glTexCoord2f(0.0, 1.0);
   glVertex3f(1.0, 1.0, -1.0);          // 紋理和四邊形的左上
   glTexCoord2f(0.0, 0.0);
   glVertex3f(1.0, -1.0, -1.0);         // 紋理和四邊形的左下
   // 頂面
   glNormal3f(0.0, 1.0, 0.0);           // 法線向上
   glTexCoord2f(0.0, 1.0);
   glVertex3f(-1.0, 1.0, -1.0);         // 紋理和四邊形的左上
   glTexCoord2f(0.0, 0.0);
   glVertex3f(-1.0, 1.0, 1.0);          // 紋理和四邊形的左下
   glTexCoord2f(1.0, 0.0);
   glVertex3f(1.0, 1.0, 1.0);           // 紋理和四邊形的右下
   glTexCoord2f(1.0, 1.0);
   glVertex3f(1.0, 1.0, -1.0);          // 紋理和四邊形的右上
   // 底面
   glNormal3f(0.0, -1.0, 0.0);          // 法線朝下
   glTexCoord2f(1.0, 1.0);
   glVertex3f(-1.0, -1.0, -1.0);        // 紋理和四邊形的右上
   glTexCoord2f(0.0, 1.0);
   glVertex3f(1.0, -1.0, -1.0);         // 紋理和四邊形的左上
   glTexCoord2f(0.0, 0.0);
   glVertex3f(1.0, -1.0, 1.0);          // 紋理和四邊形的左下
   glTexCoord2f(1.0, 0.0);
   glVertex3f(-1.0, -1.0, 1.0);         // 紋理和四邊形的右下
   // 右面
   glNormal3f(1.0, 0.0, 0.0);           // 法線朝右
   glTexCoord2f(1.0, 0.0);
   glVertex3f(1.0, -1.0, -1.0);         // 紋理和四邊形的右下
   glTexCoord2f(1.0, 1.0);
   glVertex3f(1.0, 1.0, -1.0);          // 紋理和四邊形的右上
   glTexCoord2f(0.0, 1.0);
   glVertex3f(1.0, 1.0, 1.0);           // 紋理和四邊形的左上
   glTexCoord2f(0.0, 0.0);
   glVertex3f(1.0, -1.0, 1.0);          // 紋理和四邊形的左下
   // 左面
   glNormal3f(-1.0, 0.0, 0.0);          // 法線朝左
   glTexCoord2f(0.0, 0.0);
   glVertex3f(-1.0, -1.0, -1.0);        // 紋理和四邊形的左下
   glTexCoord2f(1.0, 0.0);
   glVertex3f(-1.0, -1.0, 1.0);         // 紋理和四邊形的右下
   glTexCoord2f(1.0, 1.0);
   glVertex3f(-1.0, 1.0, 1.0);          // 紋理和四邊形的右上
   glTexCoord2f(0.0, 1.0);
   glVertex3f(-1.0, 1.0, -1.0);         // 紋理和四邊形的左上
   glEnd();

   xrot := xrot + xspeed;               // xrot 增加 xspeed 單位
   yrot := Yrot + yspeed;               // yrot 增加 yspeed 單位
End;

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

               If (keys[ord('L')] And Not lp) Then
                  Begin
                     //如果lp的值是false的話,
                     //意味著L鍵還沒按下,或者已經松開了,接著lp將被設為TRUE。
                     //同時檢查這兩個條件的原因是為了防止L鍵被按住后,
                     //這段代碼被反復執行,并導致窗體不停閃爍。
                     //lp設為true之后,計算機就知道L鍵按過了,
                     //我們則據此可以切換光源的開/關:布爾變量light控制光源的開關。
                     lp := true;        // lp 設為 TRUE
                     light := Not light; // 切換光源的 TRUE/FALSE
                     If Not light Then  // 如果沒有光源
                        glDisable(GL_LIGHTING) //禁用光源
                     Else               // Otherwis
                        glEnable(GL_LIGHTING); //啟用光源
                  End;
               If Not keys[ord('L')] Then //L鍵松開了么?
                  lp := FALSE;          // 若是,則將lp設為FALSE

               //然后對"F"鍵作相似的檢查。
               //如果有按下"F"鍵并且"F"鍵沒有處于按著的狀態或者它就從沒有按下過,
               //將變量fp設為true。這意味著這個鍵正被按著呢。
               //接著將filter變量加一。如果filter變量大于2
               //(因為這里我們的使用的數組是texture[3],大于2的紋理不存在),
               //我們重置filter變量為0。
               If (keys[ord('F')] And Not fp) Then // F鍵按下了么?
                  Begin
                     fp := TRUE;        // fp 設為 TRUE
                     inc(filter);       // filter的值加一
                     If filter > 2 Then // 大于2了么?
                        filter := 0;    // 若是重置為0
                  End;
               If Not keys[ord('F')] Then //F鍵放開了么?
                  fp := FALSE;          // 若是fp設為FALSE

               //這四行檢查是否按下了PageUp鍵。若是的話,減少z變量的值。這樣DrawGLScene函數中包含的glTranslatef(0.0f,0.0f,z)調用將使木箱離觀察者更遠一點。
               If keys[VK_PRIOR] Then   //PageUp按下了?
                  z := z - 0.02;        // 若按下,將木箱移向屏幕內部。
               //接著四行檢查PageDown鍵是否按下,若是的話,增加z變量的值。這樣DrawGLScene函數中包含的glTranslatef(0.0f,0.0f,z)調用將使木箱向著觀察者移近一點。
               If keys[VK_NEXT] Then    // PageDown按下了么?
                  z := z + 0.02;        //若按下的話,將木箱移向觀察者。

               //現在檢查方向鍵。按下左右方向鍵xspeed相應減少或增加。
               //按下上下方向鍵yspeed相應減少或增加。
               //記住在以后的教程中如果xspeed、yspeed的值增加的話,立方體就轉的更快。
               //如果一直按著某個方向鍵,立方體會在那個方向上轉的越快。
               If keys[VK_UP] Then      // Up方向鍵按下了么?
                  xspeed := xspeed - 0.01; //若是,減少xspeed
               If keys[VK_DOWN] Then    //Down方向鍵按下了么?
                  xspeed := xspeed + 0.01; //若是,增加xspeed
               If keys[VK_RIGHT] Then   //Right方向鍵按下了么?
                  yspeed := yspeed + 0.01; //若是,增加yspeed
               If keys[VK_LEFT] Then    //Left方向鍵按下了么?
                  yspeed := yspeed - 0.01; //若是, 減少yspeed

               If (keys[VK_ESCAPE]) Then // 如果按下了ESC鍵
                  finished := True


上一篇:正確看待《Delphi高手突破》最后一章的實例

下一篇:打造Delphi中字符串的replace函數

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97在线视频国产| 亚洲xxxx妇黄裸体| 性色av一区二区三区在线观看| 国产有码一区二区| 情事1991在线| 国产精品69精品一区二区三区| 国产精品视频yy9099| 国产精品揄拍500视频| 久久天天躁日日躁| 国产97色在线|日韩| 亚洲成人精品视频在线观看| 91亚洲一区精品| 97超级碰在线看视频免费在线看| 国产精品激情自拍| 国产97在线播放| 中文字幕欧美日韩| 97婷婷大伊香蕉精品视频| 欧美日韩国产黄| 欧美性视频在线| 5566成人精品视频免费| 亚洲男人天堂视频| 欧美成人精品在线播放| 亚洲一区av在线播放| 丝袜亚洲欧美日韩综合| 欧美成人亚洲成人| 国产专区精品视频| 欧美日韩亚洲激情| 欧美在线性视频| 亚洲激情自拍图| 九九久久久久99精品| 97免费视频在线播放| 国产成人jvid在线播放| 亚洲免费视频网站| 亚洲国产精品视频在线观看| 日韩av在线导航| 日韩中文字幕在线免费观看| 国产精品视频1区| 亚洲美女福利视频网站| 久久影视电视剧凤归四时歌| 5252色成人免费视频| 欧美成人黄色小视频| 国产精品一区二区性色av| 亚洲成人免费网站| 久久久国产精品免费| 麻豆国产va免费精品高清在线| 成人精品一区二区三区电影免费| 中文字幕少妇一区二区三区| 97久久超碰福利国产精品…| 久久激情视频久久| 亚洲综合精品伊人久久| 欧美精品18videosex性欧美| 亚洲国产成人久久综合一区| 伊人av综合网| 欧美成人在线影院| 亚洲精品aⅴ中文字幕乱码| 久久久久久久香蕉网| 午夜精品国产精品大乳美女| 亚洲男人天天操| 日韩中文第一页| 欧美超级免费视 在线| 亚洲一区制服诱惑| 亚洲免费视频网站| 欧美成年人网站| 国产伦精品一区二区三区精品视频| 日韩一区二区三区国产| 国产精品一区二区三区久久| 欧美片一区二区三区| 亚洲欧美www| 亚洲少妇中文在线| 欧美成人激情视频免费观看| 久久精品国产成人| 黄色一区二区在线观看| 日韩中文字幕在线视频| 久久精品国产久精国产一老狼| 97成人精品视频在线观看| 九九精品视频在线| 92看片淫黄大片看国产片| 亚洲国产成人精品一区二区| www亚洲精品| 91最新在线免费观看| 成人精品福利视频| 久久综合免费视频| 国产999在线观看| 国产精品久久77777| 精品久久久久久久中文字幕| 欧洲亚洲免费视频| 91久久精品在线| 国产精品一区二区久久精品| www.xxxx欧美| 中文字幕日韩电影| 亚洲国产精品va在线| 久久久国产成人精品| 亚洲精品日韩丝袜精品| 久久精品中文字幕电影| 亚洲女人被黑人巨大进入al| 亚州av一区二区| 55夜色66夜色国产精品视频| 亚洲女人被黑人巨大进入| 国产一区二区日韩精品欧美精品| 丰满岳妇乱一区二区三区| 欧美日韩国产999| 午夜美女久久久久爽久久| 亚洲精品午夜精品| 欧洲亚洲妇女av| 国产精品99久久99久久久二8| 欧美亚洲激情视频| 久久精品99久久久香蕉| 欧美国产日韩一区| 久久久久久久久久国产精品| 91亚洲永久免费精品| 91精品国产综合久久久久久久久| 92裸体在线视频网站| 亚洲va欧美va在线观看| 色婷婷综合久久久久中文字幕1| 欧美性感美女h网站在线观看免费| 亚洲第一男人av| 国产在线观看91精品一区| 国产欧美va欧美va香蕉在线| 国产精品专区h在线观看| 亚洲自拍偷拍第一页| 美女精品视频一区| 色偷偷av一区二区三区乱| 在线日韩第一页| 亚洲男人av在线| 国产精品久久婷婷六月丁香| 日本精品中文字幕| y97精品国产97久久久久久| 91亚洲精华国产精华| 欧美亚洲国产成人精品| 亚洲国产精彩中文乱码av在线播放| 亚洲国产日韩欧美在线动漫| 亚洲男人的天堂在线播放| 久久亚洲综合国产精品99麻豆精品福利| 欧美在线一级视频| 国产一区二区三区中文| 久久久久亚洲精品| 高清一区二区三区四区五区| 成人免费视频网址| 欧美日韩在线视频首页| 久久国产加勒比精品无码| 51色欧美片视频在线观看| 欧美午夜视频在线观看| 亚洲第一区第一页| 亚洲一区制服诱惑| 国产精品女视频| 久久久久久久一| 岛国av在线不卡| 亚洲已满18点击进入在线看片| 青青在线视频一区二区三区| 久久久国产在线视频| 欧美在线视频导航| 亚洲а∨天堂久久精品9966| 亚洲免费人成在线视频观看| 日韩精品在线观看视频| 亚洲国产精品久久久久秋霞蜜臀| 亚洲成人久久久久| 一本一本久久a久久精品综合小说| 亚洲精品www久久久| 26uuu国产精品视频| 97婷婷大伊香蕉精品视频| 91在线视频一区| 91精品国产自产91精品| 欧美限制级电影在线观看| 亚洲最大av网站|