麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Delphi > 正文

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

2019-11-18 18:34:52
字體:
供稿:網(wǎng)友
 

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

首先我們還要加進(jìn)SysUtils單元和Glaux單元。
}

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

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

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

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

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

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

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

   //filter 變量跟蹤顯示時所采用的紋理類型。
   //第一種紋理(texture 0) 使用gl_nearest(不光滑)濾波方式構(gòu)建。
   //第二種紋理 (texture 1) 使用gl_linear(線性濾波) 方式,
   //離屏幕越近的圖像看起來就越光滑。
   //第三種紋理 (texture 2) 使用 mipmapped濾波方式,
   //這將創(chuàng)建一個外觀十分優(yōu)秀的紋理。
   //根據(jù)我們的使用類型,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';

{
現(xiàn)在載入一個位圖,并用它創(chuàng)建三種不同的紋理。
這一課使用glaux輔助庫來載入位圖,
因此在編譯時您應(yīng)該確認(rèn)是否包含了glaux庫。
我知道Delphi和VC++都包含了glaux庫,但別的語言不能保證都有。
『譯者注:glaux是OpenGL輔助庫,根據(jù)OpenGL的跨平臺特性,
所有平臺上的代碼都應(yīng)通用。但輔助庫不是正式的OpenGL標(biāo)準(zhǔn)庫,
沒有出現(xiàn)在所有的平臺上。但正好在Win32平臺上可用。
呵呵,BCB當(dāng)然也沒問題了。』這里我只對新增的代碼做注解。
如果您對某行代碼有疑問的話,請查看教程六。
那一課很詳細(xì)的解釋了載入、創(chuàng)建紋理的內(nèi)容。
在上一段代碼后面及 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);         // 關(guān)閉句柄
         result := auxDIBImageLoadA(filename); //載入位圖并返回指針
      End
   Else
      result := Nil;                    // 如果載入失敗,返回NiL。
End;

Function LoadTexture: boolean;          // 載入位圖并轉(zhuǎn)換成紋理
Var
   Status           : boolean;          // Status 指示器
   TextureImage     : Array[0..1] Of PTAUX_RGBImageRec; // 創(chuàng)建紋理的存儲空間
Begin
   Status := false;
   ZeroMemory(@TextureImage, sizeof(TextureImage)); // 將指針設(shè)為 NULL
   TextureImage[0] := LoadBMP('Walls.bmp');
   If TextureImage[0] <> Nil Then
      Begin
         Status := TRUE;                // 將 Status 設(shè)為 TRUE
         glGenTextures(1, texture[0]);  // 創(chuàng)建紋理
         //第六課中我們使用了線性濾波的紋理貼圖。
         //這需要機(jī)器有相當(dāng)高的處理能力,但它們看起來很不錯。
         //這一課中,我們接著要創(chuàng)建的第一種紋理使用 GL_NEAREST方式。
         //從原理上講,這種方式?jīng)]有真正進(jìn)行濾波。
         //它只占用很小的處理能力,看起來也很差。
         //唯一的好處是這樣我們的工程在很快和很慢的機(jī)器上都可以正常運行。
         //您會注意到我們在 MIN 和 MAG 時都采用了GL_NEAREST,
         //你可以混合使用 GL_NEAREST 和 GL_LINEAR。
         //紋理看起來效果會好些,但我們更關(guān)心速度,所以全采用低質(zhì)量貼圖。
         //MIN_FILTER在圖像繪制時小于貼圖的原始尺寸時采用。
         //MAG_FILTER在圖像繪制時大于貼圖的原始尺寸時采用。

         // 創(chuàng)建 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]中的話,他將覆蓋前面創(chuàng)建的 GL_NEAREST紋理。
         glBindTexture(GL_TEXTURE_2D, texture[1]);  // 使用來自位圖數(shù)據(jù)生成 的典型紋理
         // 生成紋理
         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);  // 線形濾波

         //下面是創(chuàng)建紋理的新方法。 Mipmapping!
         //『譯者注:這個詞的中文我翻不出來,不過沒關(guān)系。看完這一段,您就知道意思最重要。』
         //您可能會注意到當(dāng)圖像在屏幕上變得很小的時候,很多細(xì)節(jié)將會丟失。
         //剛才還很不錯的圖案變得很難看。當(dāng)您告訴OpenGL創(chuàng)建一個 mipmapped的紋理后,
         //OpenGL將嘗試創(chuàng)建不同尺寸的高質(zhì)量紋理。當(dāng)您向屏幕繪制一個mipmapped紋理的時候,
         //OpenGL將選擇它已經(jīng)創(chuàng)建的外觀最佳的紋理(帶有更多細(xì)節(jié))來繪制,
         //而不僅僅是縮放原先的圖像(這將導(dǎo)致細(xì)節(jié)丟失)。
         //我曾經(jīng)說過有辦法可以繞過OpenGL對紋理寬度和高度所加的限制——64、128、256,等等。
         //辦法就是 gluBuild2DMipmaps。據(jù)我的發(fā)現(xiàn),您可以使用任意的位圖來創(chuàng)建紋理。
         //OpenGL將自動將它縮放到正常的大小。
         //因為是第三個紋理,我們將它存到texture[2]。這樣本課中的三個紋理全都創(chuàng)建好了。
         // 創(chuàng)建 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 紋理。
         //我們使用三種顏色(紅,綠,藍(lán))來生成一個2D紋理。
         //TextureImage[0].sizeX 是位圖寬度,
         //TextureImage[0].sizeY 是位圖高度,
         //(====不知為什么,delphi下這個函數(shù)沒有height這個參數(shù),
         //但是幫助中卻有,不知delphi再搞什么,郁悶ing......
         //最后我在前面自己寫了一個gluBuild2DMipmaps,
         //來載入glu32.dll中的gluBuild2DMipmaps函數(shù)=====)
         //GL_RGB意味著我們依次使用RGB色彩。
         //GL_UNSIGNED_BYTE 意味著紋理數(shù)據(jù)的單位是字節(jié)。
         //TextureImage[0].data指向我們創(chuàng)建紋理所用的位圖。
         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;   // 釋放紋理圖像占用的內(nèi)存
   TextureImage[0] := Nil;              // 釋放圖像結(jié)構(gòu)
   result := Status;                    // 返回 Status
End;

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

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

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

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

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

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

   //下三行代碼放置并旋轉(zhuǎn)貼圖立方體。
   //glTranslatef(0.0,0.0,z)將立方體沿著Z軸移動Z單位。
   //glRotatef(xrot,1.0f,0.0f,0.0f)將立方體繞X軸旋轉(zhuǎn)xrot。
   //glRotatef(yrot,0.0f,1.0f,0.0f)將立方體繞Y軸旋轉(zhuǎn)yrot。
   glTranslatef(0.0, 0.0, z);           // 移入/移出屏幕 z 個單位
   glRotatef(xrot, 1.0, 0.0, 0.0);      // 繞X軸旋轉(zhuǎn)
   glRotatef(yrot, 0.0, 1.0, 0.0);      // 繞Y軸旋轉(zhuǎn)

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

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

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

               If (keys[ord('L')] And Not lp) Then
                  Begin
                     //如果lp的值是false的話,
                     //意味著L鍵還沒按下,或者已經(jīng)松開了,接著lp將被設(shè)為TRUE。
                     //同時檢查這兩個條件的原因是為了防止L鍵被按住后,
                     //這段代碼被反復(fù)執(zhí)行,并導(dǎo)致窗體不停閃爍。
                     //lp設(shè)為true之后,計算機(jī)就知道L鍵按過了,
                     //我們則據(jù)此可以切換光源的開/關(guān):布爾變量light控制光源的開關(guān)。
                     lp := true;        // lp 設(shè)為 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設(shè)為FALSE

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

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

               //現(xiàn)在檢查方向鍵。按下左右方向鍵xspeed相應(yīng)減少或增加。
               //按下上下方向鍵yspeed相應(yīng)減少或增加。
               //記住在以后的教程中如果xspeed、yspeed的值增加的話,立方體就轉(zhuǎn)的更快。
               //如果一直按著某個方向鍵,立方體會在那個方向上轉(zhuǎn)的越快。
               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程序設(shè)計之--慣用法

下一篇:華為CMPP源碼delphi6版

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
學(xué)習(xí)交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網(wǎng)友關(guān)注

主站蜘蛛池模板: 日韩欧美电影一区二区三区 | 免费在线观看一级片 | 欧美成人精品h版在线观看 久久久久久三区 | 黄色aaa视频 | 中国免费黄色 | 中文字幕欧美专区 | 农村少妇吞精夜夜爽视频 | 欧美一级毛片一级毛片 | 超碰一区| 久久亚洲春色中文字幕久久 | 欧美日韩免费一区 | 天天看天天摸天天操 | 色中射| 国产成视频在线观看 | 91av久久| 久久人人av | 国产在线久 | xxxxhdhdhdhd日本 | 巨根插入| 国产噜噜噜噜久久久久久久久 | 在线播放免费人成毛片乱码 | 黄色片免费在线 | 天堂成人一区二区三区 | 欧美一级特黄特色大片免费 | 亚洲二区不卡 | 成人精品一区二区三区中文字幕 | 成人一区二区三区在线 | 精品亚洲一区二区三区 | 亚洲3atv精品一区二区三区 | 成人视屏在线 | 成人免费久久 | 国产精品剧情一区二区三区 | 欧美一级高清免费 | av在线大全| 日本不卡一区二区三区在线 | 国产成人av在线 | 日本在线观看一区二区 | 国产18成人免费视频 | 色呦呦一区二区三区 | 性欧美极品xxxx欧美一区二区 | 国产高清一区 |